You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/08/19 20:52:29 UTC

[groovy] branch GROOVY-10200 created (now f59509a)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch GROOVY-10200
in repository https://gitbox.apache.org/repos/asf/groovy.git.


      at f59509a  GROOVY-10200: do not retain static for outer member checking of variable

This branch includes the following new commits:

     new f59509a  GROOVY-10200: do not retain static for outer member checking of variable

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[groovy] 01/01: GROOVY-10200: do not retain static for outer member checking of variable

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-10200
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit f59509af7dd754e7c7fd92cd25a9124a5816902a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Aug 19 15:45:38 2021 -0500

    GROOVY-10200: do not retain static for outer member checking of variable
---
 .../groovy/classgen/VariableScopeVisitor.java      |  12 +-
 src/test/groovy/lang/MixinAnnotationTest.groovy    | 152 ++++++++++++---------
 .../stc/FieldsAndPropertiesSTCTest.groovy          |   2 +-
 3 files changed, 92 insertions(+), 74 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 7067b78..70fb8ad 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -238,19 +238,19 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
             ClassNode node = scope.getClassScope();
             if (node != null) {
                 Variable member = findClassMember(node, name);
+                boolean requireStatic = (crossingStaticContext || inSpecialConstructorCall);
                 while (member == null && node.getOuterClass() != null && !isAnonymous(node)) {
-                    crossingStaticContext = (crossingStaticContext || isStatic(node.getModifiers()));
+                    requireStatic = requireStatic || isStatic(node.getModifiers());
                     member = findClassMember((node = node.getOuterClass()), name);
                 }
                 if (member != null) {
-                    boolean staticScope = (crossingStaticContext || inSpecialConstructorCall), staticMember = member.isInStaticContext();
-                    // prevent a static context (e.g. a static method) from accessing a non-static variable (e.g. a non-static field)
-                    if (!(staticScope ? !staticMember : node.isScript())) {
+                    // prevent a static context (e.g. a static method) from accessing a non-static member (e.g. a non-static field)
+                    if (requireStatic ? member.isInStaticContext() : !node.isScript()) {
                         variable = member;
                     }
                 }
-                // GROOVY-5961
-                if (!isAnonymous(scope.getClassScope())) break;
+
+                if (!isAnonymous(scope.getClassScope())) break; // GROOVY-5961
             }
             scope = scope.getParent();
         }
diff --git a/src/test/groovy/lang/MixinAnnotationTest.groovy b/src/test/groovy/lang/MixinAnnotationTest.groovy
index 6aa66ef..49df14f 100644
--- a/src/test/groovy/lang/MixinAnnotationTest.groovy
+++ b/src/test/groovy/lang/MixinAnnotationTest.groovy
@@ -18,81 +18,99 @@
  */
 package groovy.lang
 
-import groovy.test.GroovyShellTestCase
 import org.codehaus.groovy.reflection.ReflectionCache
-
-class MixinAnnotationTest extends GroovyShellTestCase {
-
-    void testSingleMixinAnnotation () {
-        evaluate """
-
-interface Mixed {
-  def getA ()
-}
-
-@Category(Mixed)
-class CategoryToUse {
-    static def msg = "under category: "
-
-    def asText () {
-        msg + this + ": " + a
-    }
-}
-
-@Mixin(CategoryToUse)
-class ClassToExtend implements Mixed{
-    String toString () {
-        "object of ClassToExtend"
-    }
-
-    def a = "blah"
-}
-
-        groovy.test.GroovyTestCase.assertEquals("under category: object of ClassToExtend: blah", new ClassToExtend().asText ())
-
-        boolean failed = false;
-        try {
-            new Object().asText ()
-        }
-        catch (MissingMethodException e) {
-          failed = true;
-        }
-        assert failed
-
-        """
+import org.junit.After
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class MixinAnnotationTest {
+
+    @Test
+    void testSingleMixinAnnotation() {
+        assertScript '''
+            interface Mixed {
+                def getA()
+            }
+
+            @Category(Mixed)
+            class CategoryToUse {
+                private static String msg = 'under category: '
+                String asText() {
+                    msg + this + ': ' + a
+                }
+            }
+
+            @Mixin(CategoryToUse)
+            class ClassToExtend implements Mixed {
+                String toString() {
+                    'object of ClassToExtend'
+                }
+                def a = 'blah'
+            }
+
+            def result = new ClassToExtend().asText()
+            assert result == 'under category: object of ClassToExtend: blah'
+            groovy.test.GroovyAssert.shouldFail(MissingMethodException) {
+                new Object().asText()
+            }
+        '''
     }
 
+    @Test
     void testMultipleMixinAnnotation () {
-        evaluate """
-@Category(Object)
-class CategoryToUse1 {
-    def asText () {
-        "under category: " + asBiggerText ()
+        assertScript '''
+            @Category(Object)
+            class CategoryToUse1 {
+                def asText() {
+                    'under category: ' + asBiggerText()
+                }
+            }
+
+            @Category(Object)
+            class CategoryToUse2 {
+                def asBiggerText() {
+                    'under BIG category: ' + this
+                }
+            }
+
+            @Mixin([CategoryToUse1, CategoryToUse2])
+            class ClassToExtend {
+                String toString() {
+                    'object of ClassToExtend'
+                }
+            }
+
+            def result = new ClassToExtend().asText()
+            assert result == 'under category: under BIG category: object of ClassToExtend'
+        '''
     }
-}
-
-@Category(Object)
-class CategoryToUse2 {
-    def asBiggerText () {
-        "under BIG category: " + this
-    }
-}
-
-@Mixin([CategoryToUse1, CategoryToUse2])
-class ClassToExtend {
-    String toString () {
-        "object of ClassToExtend"
-    }
-}
 
-        groovy.test.GroovyTestCase.assertEquals("under category: under BIG category: object of ClassToExtend", new ClassToExtend().asText ())
-        """
+    @Test // GROOVY-10200
+    void testStaticInnerMixinAnnotation() {
+        assertScript '''
+            class A {
+                def getB() {
+                    'works'
+                }
+            }
+            class C {
+                @Mixin(A)
+                static class D {
+                    def test() {
+                        return b
+                    }
+                }
+            }
+            def result = new C.D().test()
+            assert result == 'works'
+        '''
     }
 
-    protected void tearDown() {
-        super.tearDown()
-        ReflectionCache.getCachedClass(ArrayList).setNewMopMethods (null)
-        ReflectionCache.getCachedClass(List).setNewMopMethods (null)
+    @After
+    void tearDown() {
+        ReflectionCache.getCachedClass(ArrayList).setNewMopMethods(null)
+        ReflectionCache.getCachedClass(List).setNewMopMethods(null)
     }
 
 //    void testOneClass () {
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index be5b8c2..bddafa0 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -562,7 +562,7 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
             }
             def i = new Outer.Inner()
             def x = i.m()
-        ''', "Apparent variable 'p' was found in a static scope but doesn't refer to a local variable, static field or class."
+        ''', 'The variable [p] is undeclared.'
     }
 
     void testOuterPropertyAccess3() {