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 2021/08/20 11:21:20 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-10200: do not retain
static for outer member checking of variable (PORT to 2_5_X)
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
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new e972fed GROOVY-10200: do not retain static for outer member checking of variable (PORT to 2_5_X)
e972fed is described below
commit e972fed3209c13c50b0563051469e2714c44cbfb
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 (PORT to 2_5_X)
---
.../groovy/classgen/VariableScopeVisitor.java | 12 +-
src/test/groovy/lang/MixinAnnotationTest.groovy | 150 ++++++++++++---------
.../stc/FieldsAndPropertiesSTCTest.groovy | 2 +-
3 files changed, 92 insertions(+), 72 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 45cdc74..f6afa6a 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -232,19 +232,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)) {
+ // 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 844041a..3cdf197 100644
--- a/src/test/groovy/lang/MixinAnnotationTest.groovy
+++ b/src/test/groovy/lang/MixinAnnotationTest.groovy
@@ -20,78 +20,98 @@ package groovy.lang
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"
-}
-
- 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 ()
- }
-}
-
-@Category(Object)
-class CategoryToUse2 {
- def asBiggerText () {
- "under BIG category: " + this
+ 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'
+ '''
}
-}
-
-@Mixin([CategoryToUse1, CategoryToUse2])
-class ClassToExtend {
- String toString () {
- "object of ClassToExtend"
- }
-}
- 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 2a9721f..79bfd24 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -487,7 +487,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() {