groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject [groovy] 01/04: GROOVY-9292: Compilation error when accessing a protected super class field from a closure using owner, delegate or thisObject qualifier (different package)
Date Tue, 29 Oct 2019 04:58:32 GMT
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 3673e10c495f1e2618cf0679cc9887f8e8561e2f
Author: Daniel.Sun <realbluesun@hotmail.com>
AuthorDate: Tue Oct 29 08:10:51 2019 +0800

    GROOVY-9292: Compilation error when accessing a protected super class field from a closure
using owner, delegate or thisObject qualifier (different package)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |   18 +
 src/test/groovy/bugs/Groovy9288.groovy             |    8 +-
 src/test/groovy/bugs/Groovy9292Bug.groovy          | 1008 ++++++++++++++++++++
 src/test/groovy/bugs/Groovy9293.groovy             |    8 +-
 4 files changed, 1034 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index bafe1cb..5161529 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -222,6 +222,7 @@ import static org.codehaus.groovy.syntax.Types.MINUS_MINUS;
 import static org.codehaus.groovy.syntax.Types.MOD;
 import static org.codehaus.groovy.syntax.Types.MOD_EQUAL;
 import static org.codehaus.groovy.syntax.Types.PLUS_PLUS;
+import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ArrayList_TYPE;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.Collection_TYPE;
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.Matcher_TYPE;
@@ -1508,6 +1509,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport
{
         return existsProperty(pexp, checkForReadOnly, null);
     }
 
+    private static final Set<String> CLOSURE_IMPLICIT_VARIABLE_SET =
+            Collections.unmodifiableSet(new HashSet<>(Arrays.asList("it", "this", "thisObject",
"owner", "delegate")));
+
     /**
      * Checks whether a property exists on the receiver, or on any of the possible receiver
classes (found in the
      * temporary type information table)
@@ -1589,6 +1593,16 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport
{
 
                 FieldNode field = current.getDeclaredField(propertyName);
                 field = allowStaticAccessToMember(field, staticOnly);
+
+                if (null != field) {
+                    int fieldModifiers = field.getModifiers();
+                    if (Modifier.isProtected(fieldModifiers) || isPackagePrivate(fieldModifiers))
{
+                        if (null != typeCheckingContext.getEnclosingClosure() &&
CLOSURE_IMPLICIT_VARIABLE_SET.contains(objectExpression.getText())) {
+                            objectExpression.putNodeMetaData(RECEIVER_OF_DYNAMIC_PROPERTY,
OBJECT_TYPE);
+                        }
+                    }
+                }
+
                 if (storeField(field, isAttributeExpression, pexp, current, visitor, receiver.getData(),
!readMode)) {
                     pexp.removeNodeMetaData(READONLY_PROPERTY);
                     return true;
@@ -1717,6 +1731,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport
{
         return foundGetterOrSetter;
     }
 
+    private static boolean isPackagePrivate(int modifiers) {
+        return !(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers) || Modifier.isPrivate(modifiers));
+    }
+
     private static boolean hasAccessToField(FieldNode field, ClassNode objectExpressionType)
{
         if (field != null) {
             if (field.isPublic() || field.isProtected()) {
diff --git a/src/test/groovy/bugs/Groovy9288.groovy b/src/test/groovy/bugs/Groovy9288.groovy
index f2b5bee..87f2ac8 100644
--- a/src/test/groovy/bugs/Groovy9288.groovy
+++ b/src/test/groovy/bugs/Groovy9288.groovy
@@ -100,7 +100,7 @@ final class Groovy9288 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9292
+    @Test
     void 'test accessing a protected super class field inside a closure - diff package, it
qualifier'() {
         shell.evaluate '''
             package a
@@ -204,7 +204,7 @@ final class Groovy9288 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9292
+    @Test
     void 'test accessing a protected super class field inside a closure - diff package, owner
qualifier'() {
         shell.evaluate '''
             package a
@@ -256,7 +256,7 @@ final class Groovy9288 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9292
+    @Test
     void 'test accessing a protected super class field inside a closure - diff package, delegate
qualifier'() {
         shell.evaluate '''
             package a
@@ -308,7 +308,7 @@ final class Groovy9288 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9292
+    @Test
     void 'test accessing a protected super class field inside a closure - diff package, thisObject
qualifier'() {
         shell.evaluate '''
             package a
diff --git a/src/test/groovy/bugs/Groovy9292Bug.groovy b/src/test/groovy/bugs/Groovy9292Bug.groovy
new file mode 100644
index 0000000..6b11a4c
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9292Bug.groovy
@@ -0,0 +1,1008 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+import groovy.test.NotYetImplemented
+import org.junit.Test
+
+final class Groovy9292Bug {
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - different
package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    'something'.with {
+                        return superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - same package"()
{
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    'something'.with {
+                        return superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - using it -
different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return it.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - using this
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    'something'.with {
+                        return this.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - using thisObject
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    'something'.with {
+                        return thisObject.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - using owner
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    'something'.with {
+                        return owner.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a protected super class field from inside a closure - using delegate
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                protected String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return delegate.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a package-private super class field from inside a closure - same
package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return delegate.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a package-private super class field from inside a closure - using
delegate - same package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return delegate.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a package-private super class field from inside a closure - using
it - same package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return it.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+    @NotYetImplemented // java.lang.IllegalAccessError: class a.ConcreteClass$_doThing_closure1
tried to access field a.Abstract_Class.superField (a.ConcreteClass$_doThing_closure1 is in
unnamed module of loader groovy.lang.GroovyClassLoader$InnerLoader @5fa47fea; a.Abstract_Class
is in unnamed module of loader groovy.lang.GroovyClassLoader$InnerLoader @28cda624)
+    @Test
+    void "test accessing a package-private super class field from inside a closure - using
this - same package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return this.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a package-private super class field from inside a closure - using
thisObject - same package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return thisObject.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a package-private super class field from inside a closure - using
owner - same package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                @groovy.transform.PackageScope String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package a
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return owner.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a public super class field from inside a closure - different package
-- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a public super class field from inside a closure - using delegate
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return delegate.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a public super class field from inside a closure - using it - different
package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return it.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a public super class field from inside a closure - using this -
different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return this.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a public super class field from inside a closure - using thisObject
- different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return thisObject.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a public super class field from inside a closure - using owner -
different package"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                public String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return owner.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - different
package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - using
delegate - different package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return delegate.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - using
it - different package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return it.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - using
this - different package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return this.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - using
thisObject - different package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return thisObject.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+
+    @Test
+    void "test accessing a private super class field from inside a closure via getter - using
owner - different package -- regression"() {
+        GroovyShell shell = new GroovyShell()
+        shell.evaluate('''
+            package a
+            
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            abstract class Abstract_Class {
+                String superField = 'field'
+                
+                abstract String doThing()
+            }
+            assert true
+        ''')
+
+        shell.evaluate('''
+            package b
+            
+            import a.Abstract_Class
+            import groovy.transform.CompileStatic
+            
+            @CompileStatic
+            class ConcreteClass extends Abstract_Class {
+               
+                @Override
+                String doThing() {
+                    this.with {
+                        return owner.superField
+                    }
+                }
+            }
+            assert true
+        ''')
+
+        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
+    }
+}
diff --git a/src/test/groovy/bugs/Groovy9293.groovy b/src/test/groovy/bugs/Groovy9293.groovy
index 268e5ea..c50276a 100644
--- a/src/test/groovy/bugs/Groovy9293.groovy
+++ b/src/test/groovy/bugs/Groovy9293.groovy
@@ -106,7 +106,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9293
+    @Test
     void 'test accessing a package-private super class field inside a closure - diff package,
it qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -216,7 +216,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9293
+    @Test
     void 'test accessing a package-private super class field inside a closure - diff package,
owner qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -271,7 +271,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9293
+    @Test
     void 'test accessing a package-private super class field inside a closure - diff package,
delegate qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -326,7 +326,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9293
+    @Test
     void 'test accessing a package-private super class field inside a closure - diff package,
thisObject qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''


Mime
View raw message