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 2022/08/25 21:11:03 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-9127, GROOVY-9195, GROOVY-9288, GROOVY-9292, GROOVY-9293: fields
This is an automated email from the ASF dual-hosted git repository.
emilles 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 58c8d9586b GROOVY-9127, GROOVY-9195, GROOVY-9288, GROOVY-9292, GROOVY-9293: fields
58c8d9586b is described below
commit 58c8d9586bea7ff9a5dfcbbea1f00e7f53ddbacc
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Aug 25 16:04:53 2022 -0500
GROOVY-9127, GROOVY-9195, GROOVY-9288, GROOVY-9292, GROOVY-9293: fields
---
.../groovy/classgen/AsmClassGenerator.java | 32 +-
.../transform/stc/StaticTypeCheckingVisitor.java | 55 +-
src/test/groovy/bugs/Groovy9127.groovy | 164 ++++
src/test/groovy/bugs/Groovy9136.groovy | 61 +-
src/test/groovy/bugs/Groovy9288.groovy | 109 ++-
src/test/groovy/bugs/Groovy9292.groovy | 382 ++++++++
src/test/groovy/bugs/Groovy9292Bug.groovy | 1008 --------------------
.../stc/FieldsAndPropertiesSTCTest.groovy | 50 +-
.../ArraysAndCollectionsStaticCompileTest.groovy | 27 +-
9 files changed, 727 insertions(+), 1161 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index a9e12910e7..9d3ced436b 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -91,6 +91,7 @@ import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
import org.codehaus.groovy.ast.stmt.ThrowStatement;
import org.codehaus.groovy.ast.stmt.TryCatchStatement;
import org.codehaus.groovy.ast.stmt.WhileStatement;
+import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.ast.tools.WideningCategories;
import org.codehaus.groovy.classgen.asm.BytecodeHelper;
import org.codehaus.groovy.classgen.asm.BytecodeVariable;
@@ -1180,8 +1181,7 @@ public class AsmClassGenerator extends ClassGenerator {
}
private boolean isThisOrSuperInStaticContext(Expression objectExpression) {
- if (controller.isInClosure()) return false;
- return controller.isStaticContext() && isThisOrSuper(objectExpression);
+ return isThisOrSuper(objectExpression) && controller.isStaticContext() && !controller.isInClosure();
}
public void visitPropertyExpression(PropertyExpression expression) {
@@ -1233,11 +1233,11 @@ public class AsmClassGenerator extends ClassGenerator {
if (controller.getCompileStack().isLHS()) {
adapter = setField;
if (isGroovyObject(objectExpression)) adapter = setGroovyObjectField;
- if (usesSuper(expression)) adapter = setFieldOnSuper;
+ if (isSuperExpression(objectExpression)) adapter = setFieldOnSuper;
} else {
adapter = getField;
if (isGroovyObject(objectExpression)) adapter = getGroovyObjectField;
- if (usesSuper(expression)) adapter = getFieldOnSuper;
+ if (isSuperExpression(objectExpression)) adapter = getFieldOnSuper;
}
visitAttributeOrProperty(expression, adapter);
}
@@ -1249,18 +1249,18 @@ public class AsmClassGenerator extends ClassGenerator {
}
}
- private static boolean usesSuper(PropertyExpression pe) {
- Expression expression = pe.getObjectExpression();
- if (expression instanceof VariableExpression) {
- VariableExpression varExp = (VariableExpression) expression;
- String variable = varExp.getName();
- return variable.equals("super");
- }
- return false;
+ private boolean isGroovyObject(Expression objectExpression) {
+ if (ExpressionUtils.isThisExpression(objectExpression)) return true;
+ if (objectExpression instanceof ClassExpression) return false;
+
+ ClassNode objectExpressionType = controller.getTypeChooser().resolveType(objectExpression, controller.getClassNode());
+ if (objectExpressionType.equals(ClassHelper.OBJECT_TYPE)) objectExpressionType = objectExpression.getType();
+ if (GeneralUtils.isOrImplements(objectExpressionType, ClassHelper.MAP_TYPE)) return false; // GROOVY-8074
+ return implementsGroovyObject(objectExpressionType); // GROOVY-9195, GROOVY-9288, et al.
}
- private static boolean isGroovyObject(Expression objectExpression) {
- return ExpressionUtils.isThisExpression(objectExpression) || objectExpression.getType().isDerivedFromGroovyObject() && !(objectExpression instanceof ClassExpression);
+ private static boolean implementsGroovyObject(ClassNode cn) {
+ return cn.isDerivedFromGroovyObject() || (!cn.isInterface() && cn.getCompileUnit() != null);
}
public void visitFieldExpression(FieldExpression expression) {
@@ -1691,8 +1691,8 @@ public class AsmClassGenerator extends ClassGenerator {
public void loadWrapper(Expression argument) {
MethodVisitor mv = controller.getMethodVisitor();
ClassNode goalClass = argument.getType();
- visitClassExpression(new ClassExpression(goalClass));
- if (goalClass.isDerivedFromGroovyObject()) {
+ visitClassExpression(classX(goalClass));
+ if (implementsGroovyObject(goalClass)) {
createGroovyObjectWrapperMethod.call(mv);
} else {
createPojoWrapperMethod.call(mv);
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 954d8c06ba..9212345315 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1450,9 +1450,6 @@ 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)
@@ -1476,9 +1473,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// Outer.this for any level of nesting
ClassNode outerNode = objectExpressionType.getGenericsTypes()[0].getType();
ClassNode found = null;
- for (ClassNode current : enclosingTypes) {
- if (!current.isStaticClass() && current instanceof InnerClassNode && outerNode.equals(current.getOuterClass())) {
- found = current;
+ for (ClassNode enclosingType : enclosingTypes) {
+ if (!enclosingType.isStaticClass() && outerNode.equals(enclosingType.getOuterClass())) {
+ found = enclosingType;
break;
}
}
@@ -1492,9 +1489,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
List<Receiver<String>> receivers = new ArrayList<>();
addReceivers(receivers, makeOwnerList(objectExpression), pexp.isImplicitThis());
- String capName = MetaClassHelper.capitalize(propertyName);
+ String capName = MetaClassHelper.capitalize(propertyName), isserName = "is" + capName, getterName = "get" + capName, setterName = "set" + capName;
boolean isAttributeExpression = pexp instanceof AttributeExpression;
- HashSet<ClassNode> handledNodes = new HashSet<ClassNode>();
+ Set<ClassNode> handledNodes = new HashSet<>();
for (Receiver<String> receiver : receivers) {
ClassNode receiverType = receiver.getType();
@@ -1538,16 +1535,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
field = allowStaticAccessToMember(field, staticOnly);
- // GROOVY-9288, GROOVY-9292, GROOVY-9293
- 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(StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY, OBJECT_TYPE);
- }
- }
- }
-
// skip property/accessor checks for "x.@field"
if (storeField(field, isAttributeExpression, pexp, receiverType, visitor, receiver.getData(), !readMode)) {
pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
@@ -1562,13 +1549,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return true;
}
- boolean isThisExpression = enclosingTypes.contains(receiverType);
-
- MethodNode getter = findGetter(current, "get" + capName, pexp.isImplicitThis());
+ MethodNode getter = findGetter(current, getterName, pexp.isImplicitThis());
getter = allowStaticAccessToMember(getter, staticOnly);
- if (getter == null) getter = findGetter(current, "is" + capName, pexp.isImplicitThis());
+ if (getter == null) getter = findGetter(current, isserName, pexp.isImplicitThis());
getter = allowStaticAccessToMember(getter, staticOnly);
- final String setterName = "set" + capName;
List<MethodNode> setters = findSetters(current, setterName, false);
setters = allowStaticAccessToMember(setters, staticOnly);
@@ -1578,7 +1562,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
PropertyNode propertyNode = current.getProperty(propertyName);
propertyNode = allowStaticAccessToMember(propertyNode, staticOnly);
// prefer explicit getter or setter over property if receiver is not 'this'
- boolean checkGetterOrSetter = !isThisExpression || propertyNode == null;
+ boolean checkGetterOrSetter = propertyNode == null || !enclosingTypes.contains(receiverType);
if (readMode && checkGetterOrSetter) {
if (getter != null) {
@@ -1587,8 +1571,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
storeTargetMethod(pexp, getter);
pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
String delegationData = receiver.getData();
- if (delegationData != null)
+ if (delegationData != null) {
pexp.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, delegationData);
+ }
return true;
}
} else if (!readMode && checkGetterOrSetter) {
@@ -1610,6 +1595,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (enclosingBinaryExpression != null) {
putSetterInfo(enclosingBinaryExpression.getLeftExpression(), info);
}
+ pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
String delegationData = receiver.getData();
if (delegationData != null) {
pexp.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, delegationData);
@@ -1632,8 +1618,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// GROOVY-5568: the property may be defined by DGM
for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new ClassNode[]{receiverType, getWrapper(receiverType)} : new ClassNode[]{receiverType}) {
- List<MethodNode> methods = findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, "get" + capName, ClassNode.EMPTY_ARRAY);
- for (MethodNode m : findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, "is" + capName, ClassNode.EMPTY_ARRAY)) {
+ List<MethodNode> methods = findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, getterName, ClassNode.EMPTY_ARRAY);
+ for (MethodNode m : findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, isserName, ClassNode.EMPTY_ARRAY)) {
if (Boolean_TYPE.equals(getWrapper(m.getReturnType()))) methods.add(m);
}
if (isUsingGenericsOrIsArrayUsingGenerics(dgmReceiver)) { // GROOVY-10075: "List<Integer>" vs "List<String>"
@@ -1697,18 +1683,15 @@ 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.isPublic() || field.isProtected()) {
+ private static boolean hasAccessToField(final FieldNode field, final ClassNode accessor) {
+ if (field.isPublic() || accessor.equals(field.getDeclaringClass())) {
return true;
}
- if (!field.isPrivate() && Objects.equals(objectExpressionType.getPackageName(), field.getDeclaringClass().getPackageName())) {
- return true;
+ if (field.isProtected()) {
+ return accessor.isDerivedFrom(field.getDeclaringClass());
+ } else {
+ return !field.isPrivate() && Objects.equals(accessor.getPackageName(), field.getDeclaringClass().getPackageName());
}
- return false;
}
private MethodNode findGetter(ClassNode current, String name, boolean searchOuterClasses) {
diff --git a/src/test/groovy/bugs/Groovy9127.groovy b/src/test/groovy/bugs/Groovy9127.groovy
new file mode 100644
index 0000000000..60c957a00a
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9127.groovy
@@ -0,0 +1,164 @@
+/*
+ * 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.transform.CompileStatic
+import org.codehaus.groovy.control.CompilationFailedException
+import org.codehaus.groovy.control.CompilationUnit
+
+import static org.codehaus.groovy.control.Phases.CLASS_GENERATION
+
+@CompileStatic
+final class Groovy9127 extends GroovyTestCase {
+
+ void testReadOnlyPropertyAssignment1() {
+ assertScript '''
+ @groovy.transform.CompileStatic
+ class Foo {
+ protected String field = 'foo'
+ String getField() { return field }
+ }
+ @groovy.transform.CompileStatic
+ class Bar extends Foo {
+ void changeField() {
+ field = 'bar' // GROOVY-9127: [Static type checking] - Cannot set read-only property: field
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ def bar = new Bar()
+ bar.changeField()
+ assert bar.field == 'value'
+ '''
+ }
+
+ void testReadOnlyPropertyAssignment2() {
+ assertScript '''
+ @groovy.transform.CompileStatic
+ class Foo {
+ public String field = 'foo'
+ String getField() { return field }
+ }
+ @groovy.transform.CompileStatic
+ class Bar extends Foo {
+ void changeField() {
+ field = 'bar'
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ def bar = new Bar()
+ bar.changeField()
+ assert bar.field == 'value'
+ '''
+ }
+
+ void testReadOnlyPropertyAssignment3() {
+ assertScript '''
+ @groovy.transform.CompileStatic
+ class Foo {
+ @groovy.transform.PackageScope String field = 'foo'
+ String getField() { return field }
+ }
+ @groovy.transform.CompileStatic
+ class Bar extends Foo {
+ void changeField() {
+ field = 'bar'
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ def bar = new Bar()
+ bar.changeField()
+ assert bar.field == 'value'
+ '''
+ }
+
+ void testReadOnlyPropertyAssignment4() {
+ new CompilationUnit().with {
+ addSource 'Foo.groovy', '''
+ package foo
+
+ @groovy.transform.CompileStatic
+ class Foo {
+ @groovy.transform.PackageScope String field = 'foo'
+ String getField() { return field }
+ }
+ '''
+
+ addSource 'Bar.groovy', '''
+ package bar
+
+ @groovy.transform.CompileStatic
+ class Bar extends foo.Foo {
+ void changeField() {
+ field = 'bar'
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ '''
+
+ def err = shouldFail CompilationFailedException, {
+ compile CLASS_GENERATION
+ }
+ assert err =~ /\[Static type checking\] - Cannot set read-only property: field/
+ }
+ }
+
+ void testReadOnlyPropertyAssignment5() {
+ def err = shouldFail CompilationFailedException, '''
+ @groovy.transform.CompileStatic
+ class Foo {
+ private String field = 'foo'
+ String getField() { return field }
+ }
+ @groovy.transform.CompileStatic
+ class Bar extends Foo {
+ void changeField() {
+ field = 'bar'
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ '''
+ assert err =~ /\[Static type checking\] - Cannot set read-only property: field/
+ }
+
+ void testAttributeAssignmentVariation() {
+ assertScript '''
+ @groovy.transform.CompileStatic
+ class Foo {
+ protected String field = 'foo'
+ String getField() { return field }
+ }
+ @groovy.transform.CompileStatic
+ class Bar extends Foo {
+ void changeField() {
+ this.@field = 'bar'
+ }
+ @Override
+ String getField() { return 'value' }
+ }
+ def bar = new Bar()
+ bar.changeField()
+ assert bar.field == 'value'
+ '''
+ }
+}
diff --git a/src/test/groovy/bugs/Groovy9136.groovy b/src/test/groovy/bugs/Groovy9136.groovy
index f85aff276e..eac12742c8 100644
--- a/src/test/groovy/bugs/Groovy9136.groovy
+++ b/src/test/groovy/bugs/Groovy9136.groovy
@@ -18,28 +18,71 @@
*/
package groovy.bugs
-import groovy.transform.CompileStatic
+import org.junit.Test
-@CompileStatic
-final class Groovy9136 extends GroovyTestCase {
+import static groovy.test.GroovyAssert.assertScript
- void testMethodParameterAccessFromClosure() {
+final class Groovy9136 {
+
+ @Test
+ void testMethodParameterFieldAccessFromClosure1() {
assertScript '''
- @groovy.transform.CompileStatic
class Foo {
public String field = 'foo'
}
- @groovy.transform.CompileStatic
class Bar {
- def doIt(Foo foo) {
+ @groovy.transform.CompileStatic
+ def test(Foo foo) {
'baz'.with {
- foo.field // GROOVY-9136: Access to Foo#foo is forbidden at line: -1, column: -1
+ foo.field // Access to Foo#foo is forbidden at line: -1, column: -1
+ }
+ }
+ }
+
+ def bar = new Bar()
+ def out = bar.test(new Foo())
+ assert out == 'foo'
+ '''
+ }
+
+ @Test // GROOVY-9195
+ void testMethodParameterFieldAccessFromClosure2() {
+ assertScript '''
+ class Foo {
+ private String field = 'foo'
+ }
+ class Bar {
+ @groovy.transform.CompileStatic
+ def test(Foo foo) {
+ 'baz'.with {
+ foo.field
+ }
+ }
+ }
+
+ def bar = new Bar()
+ def out = bar.test(new Foo())
+ assert out == 'foo'
+ '''
+ }
+
+ @Test
+ void testMethodParameterFieldAccessFromClosure3() {
+ assertScript '''
+ class Foo {
+ private String field = 'foo'
+ }
+ @groovy.transform.CompileStatic
+ class Bar {
+ def test(Foo foo) {
+ foo.with {
+ field
}
}
}
def bar = new Bar()
- def out = bar.doIt(new Foo())
+ def out = bar.test(new Foo())
assert out == 'foo'
'''
}
diff --git a/src/test/groovy/bugs/Groovy9288.groovy b/src/test/groovy/bugs/Groovy9288.groovy
index d8650eecb3..d1b67e3b6c 100644
--- a/src/test/groovy/bugs/Groovy9288.groovy
+++ b/src/test/groovy/bugs/Groovy9288.groovy
@@ -19,18 +19,31 @@
package groovy.bugs
import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameter
+import org.junit.runners.Parameterized.Parameters
+@RunWith(Parameterized)
final class Groovy9288 {
+ @Parameters
+ static modifiers() {
+ ['public', 'protected']
+ }
+
+ @Parameter
+ public String modifier
+
private final GroovyShell shell = new GroovyShell()
@Test
- void 'test accessing a protected super class field inside a closure - same package'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -44,20 +57,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
@@ -77,12 +90,12 @@ final class Groovy9288 {
}
@Test
- void 'test accessing a protected super class field inside a closure - same package, it qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package, it qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -96,20 +109,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package, it qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package, it qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
@@ -129,12 +142,12 @@ final class Groovy9288 {
}
@Test
- void 'test accessing a protected super class field inside a closure - same package, this qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package, this qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -148,20 +161,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package, this qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package, this qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
@@ -181,12 +194,12 @@ final class Groovy9288 {
}
@Test
- void 'test accessing a protected super class field inside a closure - same package, owner qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package, owner qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -200,20 +213,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package, owner qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package, owner qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
@@ -233,12 +246,12 @@ final class Groovy9288 {
}
@Test
- void 'test accessing a protected super class field inside a closure - same package, delegate qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package, delegate qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -252,20 +265,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package, delegate qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package, delegate qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
@@ -285,12 +298,12 @@ final class Groovy9288 {
}
@Test
- void 'test accessing a protected super class field inside a closure - same package, thisObject qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - same package, thisObject qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
class B extends A {
@@ -304,20 +317,20 @@ final class Groovy9288 {
def obj = new B()
assert obj.test() == "works"
- '''
+ """
}
@Test
- void 'test accessing a protected super class field inside a closure - diff package, thisObject qualifier'() {
- shell.evaluate '''
+ void 'test accessing a super class field inside a closure - diff package, thisObject qualifier'() {
+ shell.evaluate """
package a
class A {
- protected String superField = 'works'
+ $modifier String superField = 'works'
}
assert true
- '''
+ """
shell.evaluate '''
package b
diff --git a/src/test/groovy/bugs/Groovy9292.groovy b/src/test/groovy/bugs/Groovy9292.groovy
new file mode 100644
index 0000000000..3ffe823f8e
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9292.groovy
@@ -0,0 +1,382 @@
+/*
+ * 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 org.junit.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy9292 {
+
+ private final GroovyShell shell = new GroovyShell()
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same module'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package a
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package, it qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ with {
+ return it.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package, it qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ with {
+ return it.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package, this qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return this.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package, this qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return this.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package, owner qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return owner.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package, owner qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return owner.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package, delegate qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ with {
+ return delegate.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package, delegate qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ with {
+ return delegate.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - same package, thisObject qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ class B extends A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return thisObject.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+
+ @Test
+ void 'test accessing a private super class field inside a closure - diff package, thisObject qualifier'() {
+ shouldFail(MissingPropertyException) {
+ shell.evaluate '''
+ package a
+
+ class A {
+ private String superField
+ }
+
+ assert true
+ '''
+
+ shell.evaluate '''
+ package b
+
+ class B extends a.A {
+ @groovy.transform.CompileStatic
+ def test() {
+ 'something'.with {
+ return thisObject.superField
+ }
+ }
+ }
+
+ new B().test()
+ '''
+ }
+ }
+}
diff --git a/src/test/groovy/bugs/Groovy9292Bug.groovy b/src/test/groovy/bugs/Groovy9292Bug.groovy
deleted file mode 100644
index 06cadbca21..0000000000
--- a/src/test/groovy/bugs/Groovy9292Bug.groovy
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * 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.transform.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/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index f0688df44e..962272700a 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -383,23 +383,6 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
'''
}
- // GROOVY-5517
- void testShouldFindStaticPropertyEvenIfObjectImplementsMap() {
- assertScript '''
- class C extends HashMap {
- public static int version = 666
- }
- def map = new C()
- map['foo'] = 123
- def value = map.foo
- assert value == 123
- map['foo'] = 4.5
- value = map['foo']
- assert value == 4.5
- assert C.version == 666
- '''
- }
-
void testClassPropertyOnInterface() {
assertScript '''
Class test(Serializable arg) {
@@ -476,7 +459,7 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-5700
- void testInferenceOfMapDotProperty() {
+ void testMapPropertyAccess1() {
assertScript '''
def map = [key: 123]
@ASTTest(phase=INSTRUCTION_SELECTION, value={
@@ -488,7 +471,7 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-5700, GROOVY-8788
- void testInferenceOfMapSubProperty() {
+ void testMapPropertyAccess2() {
assertScript '''
def map = [key: 123]
@ASTTest(phase=INSTRUCTION_SELECTION, value={
@@ -499,6 +482,35 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-8074
+ void testMapPropertyAccess3() {
+ assertScript '''
+ class C extends HashMap {
+ def foo = 1
+ }
+ def map = new C()
+ map.put('foo', 42)
+ assert map.foo == 42
+ '''
+ }
+
+ // GROOVY-5517
+ void testMapPropertyAccess4() {
+ assertScript '''
+ class C extends HashMap {
+ public static int version = 666
+ }
+ def map = new C()
+ map['foo'] = 123
+ def value = map.foo
+ assert value == 123
+ map['foo'] = 4.5
+ value = map['foo']
+ assert value == 4.5
+ assert C.version == 666
+ '''
+ }
+
void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
assertScript '''
// a base class defining a read-only property
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy
index b61bffb579..8e68703f7a 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy
@@ -97,7 +97,7 @@ class ArraysAndCollectionsStaticCompileTest extends ArraysAndCollectionsSTCTest
}
}
- //GROOVY-7442
+ // GROOVY-7442
void testSpreadDotOperatorWithinAssert() {
assertScript '''
def myMethod(String a, String b) {
@@ -108,7 +108,7 @@ class ArraysAndCollectionsStaticCompileTest extends ArraysAndCollectionsSTCTest
'''
}
- //GROOVY-7688
+ // GROOVY-7688
void testSpreadSafeMethodCallReceiversWithSideEffectsShouldNotBeVisitedTwice() {
try {
assertScript '''
@@ -125,27 +125,4 @@ class ArraysAndCollectionsStaticCompileTest extends ArraysAndCollectionsSTCTest
assert astTrees['Foo'][1].count('DefaultGroovyMethods.toList') == 1
}
}
-
- //GROOVY-8074
- void testMapSubclassPropertyStyleAccess() {
- assertScript '''
- class MyMap extends LinkedHashMap {
- def foo = 1
- }
-
- def map = new MyMap()
- map.put('foo', 42)
- assert map.foo == 42
- '''
- }
-
- @Override
- void testForInLoop() {
- try {
- super.testForInLoop()
- } finally {
- println astTrees
- }
- }
}
-