groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject groovy git commit: GROOVY-8093: Final variable analysis broken within closure fields
Date Tue, 06 Feb 2018 22:40:02 GMT
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X 46bad1d83 -> 084b1a204


GROOVY-8093: Final variable analysis broken within closure fields


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/084b1a20
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/084b1a20
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/084b1a20

Branch: refs/heads/GROOVY_2_5_X
Commit: 084b1a2049dd2d885a6bc900668ed7e1639fc53e
Parents: 46bad1d
Author: paulk <paulk@asert.com.au>
Authored: Tue Feb 6 18:11:28 2018 +1000
Committer: paulk <paulk@asert.com.au>
Committed: Wed Feb 7 08:39:50 2018 +1000

----------------------------------------------------------------------
 .../groovy/classgen/FinalVariableAnalyzer.java  | 16 ++++++++++++++++
 .../classgen/FinalVariableAnalyzerTest.groovy   | 20 ++++++++++++++------
 2 files changed, 30 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/084b1a20/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java b/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
index 141daa6..924a76e 100644
--- a/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
+++ b/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
@@ -43,6 +43,7 @@ import java.lang.reflect.Modifier;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
@@ -189,10 +190,25 @@ public class FinalVariableAnalyzer extends ClassCodeVisitorSupport {
     public void visitClosureExpression(final ClosureExpression expression) {
         boolean old = inAssignment;
         inAssignment = false;
+        Map<Variable, VariableState> origState = new StateMap();
+        origState.putAll(getState());
         super.visitClosureExpression(expression);
+        cleanLocalVars(origState, getState());
         inAssignment = old;
     }
 
+    private void cleanLocalVars(Map<Variable, VariableState> origState, Map<Variable,
VariableState> state) {
+        // clean local vars added during visit of closure
+        for (Iterator<Map.Entry<Variable, VariableState>> iter = state.entrySet().iterator();
iter.hasNext(); ) {
+            Map.Entry<Variable, VariableState> next = iter.next();
+            Variable key = next.getKey();
+            if (key instanceof VariableExpression && ((VariableExpression)key).getAccessedVariable()
== key && !origState.containsKey(key)) {
+                // remove local variable
+                iter.remove();
+            }
+        }
+    }
+
     @Override
     public void visitPrefixExpression(final PrefixExpression expression) {
         inAssignment = expression.getExpression() instanceof VariableExpression;

http://git-wip-us.apache.org/repos/asf/groovy/blob/084b1a20/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy b/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
index c5a8cd7..44a3a2f 100644
--- a/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
@@ -111,12 +111,6 @@ class FinalVariableAnalyzerTest extends GroovyTestCase {
         '''
     }
 
-    void testVariableDeclaredInsideClosureShouldBeFinal() {
-        assertFinals x: true, '''
-            def cl = { def x = 1 }
-        '''
-    }
-
     void testParameterShouldBeConsideredFinal() {
         assertFinals x: true, '''
             def foo(int x) { x+1 }
@@ -452,6 +446,20 @@ class FinalVariableAnalyzerTest extends GroovyTestCase {
         ''')
     }
 
+    // GROOVY-8093
+    void testLocalVarsInClosureOnlyCheckedWithinClosure() {
+        assertScript '''
+            class Foo {
+                public Closure bar = {
+                    final RANKINGS = ["year": 0, "month": 10]
+                    RANKINGS.size()
+                }
+            }
+
+            assert new Foo().bar() == 2
+        '''
+    }
+
     @CompileStatic
     private static class AssertionFinalVariableAnalyzer extends FinalVariableAnalyzer {
 


Mime
View raw message