You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/04/23 04:55:03 UTC

[groovy] 02/02: GROOVY-5961: Variable scope not checked properly for AIC in static method

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

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

commit 888411c7256a8a862416d2c4fe2de4448edf1091
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Apr 23 14:51:30 2019 +1000

    GROOVY-5961: Variable scope not checked properly for AIC in static method
---
 .../groovy/classgen/InnerClassVisitorHelper.java   |  2 +-
 .../groovy/classgen/VariableScopeVisitor.java      |  9 +++--
 src/test/groovy/bugs/VariableScopingBug.groovy     | 42 +++++++++++++++-------
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
index 7ed0629..0971146 100644
--- a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
@@ -103,7 +103,7 @@ public abstract class InnerClassVisitorHelper extends ClassCodeVisitorSupport {
 
     protected static boolean isStatic(InnerClassNode node) {
         VariableScope scope = node.getVariableScope();
-        if (scope != null) return scope.isInStaticContext();
+        if (scope != null) return scope.getParent().isInStaticContext();
         return (node.getModifiers() & Opcodes.ACC_STATIC) != 0;
     }
 
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 18a94d5..66f314d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -160,7 +160,7 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
             // if we are in a class and no variable is declared until
             // now, then we can break the loop, because we are allowed
             // to declare a variable of the same name as a class member
-            if (scope.getClassScope() != null) break;
+            if (scope.getClassScope() != null && !isAnonymous(scope.getClassScope())) break;
 
             if (scope.getDeclaredVariable(var.getName()) != null) {
                 // variable already declared
@@ -204,6 +204,7 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
 
         Variable ret = findClassMember(cn.getSuperClass(), name);
         if (ret != null) return ret;
+        if (isAnonymous(cn)) return null;
         return findClassMember(cn.getOuterClass(), name);
     }
 
@@ -255,7 +256,9 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
                     if (!(staticScope && !staticMember))
                         var = member;
                 }
-                break;
+                // GROOVY-5961
+                if (!isAnonymous(classScope))
+                    break;
             }
             scope = scope.getParent();
         }
@@ -557,6 +560,8 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
         pushState();
         InnerClassNode innerClass = (InnerClassNode) call.getType();
         innerClass.setVariableScope(currentScope);
+        currentScope.setClassScope(innerClass);
+        currentScope.setInStaticContext(false);
         for (MethodNode method : innerClass.getMethods()) {
             Parameter[] parameters = method.getParameters();
             if (parameters.length == 0) parameters = null; // null means no implicit "it"
diff --git a/src/test/groovy/bugs/VariableScopingBug.groovy b/src/test/groovy/bugs/VariableScopingBug.groovy
index b8d1d95..7586b1c 100644
--- a/src/test/groovy/bugs/VariableScopingBug.groovy
+++ b/src/test/groovy/bugs/VariableScopingBug.groovy
@@ -18,14 +18,10 @@
  */
 package groovy.bugs
 
-/**
- */
 class VariableScopingBug extends TestSupport {
     
-    void testBug() {
-        // undeclared variable x
-
-        shouldFail {
+    void testUndeclaredVariable() {
+        shouldFail(MissingPropertyException) {
             def shell = new GroovyShell()
             shell.evaluate("""
                 class SomeTest {
@@ -35,17 +31,18 @@ class VariableScopingBug extends TestSupport {
                         }
 
                         for (t in 0..3) {
-                            for (y in x) {
+                            for (y in x) { // previous x no longer be in scope
                                 println x
                             }
                         }
                     }
-               }
-               new SomeTest().run()""")
-           }
+                }
+                new SomeTest().run()
+            """)
+        }
     }
 
-    void testVariableReuse() {
+    void testVariableReuseAllowedInDifferentScopes() {
         def shell = new GroovyShell()
         shell.evaluate("""
             for (z in 0..2) {
@@ -55,6 +52,25 @@ class VariableScopingBug extends TestSupport {
             for (t in 0..3) {
                 def x = 123
                 println x
-            }""")
+            }
+        """)
+    }
+
+    // GROOVY-5961
+    void testVariableInAicInsideStaticMethod() {
+        def shell = new GroovyShell()
+        shell.evaluate("""
+            static foo() {
+                new LinkedList([1, 2]) {
+                    int count
+                    Object get(int i) { super.get(count++) }
+                }
+            }
+
+            def l = foo()
+            assert l.count == 0
+            assert l[0] == 1
+            assert l.count == 1
+        """)
     }
-}
\ No newline at end of file
+}