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 2023/03/06 17:44:49 UTC
[groovy] branch GROOVY_3_0_X updated: GROOVY-7490, GROOVY-8389, GROOVY-10329: import static callable property
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 054c762947 GROOVY-7490, GROOVY-8389, GROOVY-10329: import static callable property
054c762947 is described below
commit 054c7629478067dd886bebb15c46867cba52d60f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Mar 6 11:25:21 2023 -0600
GROOVY-7490, GROOVY-8389, GROOVY-10329: import static callable property
3_0_X backport
---
.../org/codehaus/groovy/classgen/Verifier.java | 18 +-
.../classgen/asm/sc/StaticInvocationWriter.java | 11 +-
.../groovy/control/StaticImportVisitor.java | 236 +++++++++++----------
src/test/Outer3.groovy | 22 --
src/test/Outer4.groovy | 22 --
src/test/groovy/StaticImportTest.groovy | 44 ++++
src/test/groovy/bugs/Groovy4145.groovy | 25 ---
src/test/groovy/bugs/Groovy8389Bug.groovy | 111 ----------
8 files changed, 189 insertions(+), 300 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 76dfebb5fc..9b8d6e5153 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -103,7 +103,6 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.fieldX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getSetterName;
import static org.codehaus.groovy.ast.tools.GeneralUtils.localVarX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
@@ -354,7 +353,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
FieldNode staticMetaClassField = node.addField(staticMetaClassFieldName, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.make(ClassInfo.class, false), null);
staticMetaClassField.setSynthetic(true);
-
+ ClassNode classNode = this.classNode;
node.addSyntheticMethod(
"$getStaticMetaClass",
ACC_PROTECTED,
@@ -661,7 +660,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
FieldNode field = node.getField();
String getterName = "get" + capitalize(name);
- String setterName = getSetterName(name);
+ String setterName = "set" + capitalize(name);
int accessorModifiers = adjustPropertyModifiersForMethod(node);
@@ -1189,14 +1188,15 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
}
protected Statement createGetterBlock(final PropertyNode propertyNode, final FieldNode field) {
+ String owner = BytecodeHelper.getClassInternalName(classNode);
return new BytecodeSequence(new BytecodeInstruction() {
@Override
public void visit(final MethodVisitor mv) {
if (field.isStatic()) {
- mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(classNode), field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
+ mv.visitFieldInsn(GETSTATIC, owner, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
} else {
mv.visitVarInsn(ALOAD, 0);
- mv.visitFieldInsn(GETFIELD, BytecodeHelper.getClassInternalName(classNode), field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
+ mv.visitFieldInsn(GETFIELD, owner, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
}
BytecodeHelper.doReturn(mv, field.getType());
}
@@ -1204,16 +1204,17 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
}
protected Statement createSetterBlock(final PropertyNode propertyNode, final FieldNode field) {
+ String owner = BytecodeHelper.getClassInternalName(classNode);
return new BytecodeSequence(new BytecodeInstruction() {
@Override
public void visit(final MethodVisitor mv) {
if (field.isStatic()) {
BytecodeHelper.load(mv, field.getType(), 0);
- mv.visitFieldInsn(PUTSTATIC, BytecodeHelper.getClassInternalName(classNode), field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
+ mv.visitFieldInsn(PUTSTATIC, owner, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
} else {
mv.visitVarInsn(ALOAD, 0);
BytecodeHelper.load(mv, field.getType(), 1);
- mv.visitFieldInsn(PUTFIELD, BytecodeHelper.getClassInternalName(classNode), field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
+ mv.visitFieldInsn(PUTFIELD, owner, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
}
mv.visitInsn(RETURN);
}
@@ -1399,6 +1400,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
// if we reach this point there is least one parameter or return type
// that is different in its specified form, so create a bridge method
+ String owner = BytecodeHelper.getClassInternalName(classNode);
return new MethodNode(
oldMethod.getName(),
overridingMethod.getModifiers() | ACC_SYNTHETIC | ACC_BRIDGE,
@@ -1423,7 +1425,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
BytecodeHelper.doCast(mv, goal[i].getType());
}
}
- mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(classNode), overridingMethod.getName(), BytecodeHelper.getMethodDescriptor(nmr, overridingMethod.getParameters()), false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, owner, overridingMethod.getName(), BytecodeHelper.getMethodDescriptor(nmr, overridingMethod.getParameters()), false);
BytecodeHelper.doReturn(mv, oldMethod.getReturnType());
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 6b7cb08bd3..3bdf965890 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -21,6 +21,7 @@ package org.codehaus.groovy.classgen.asm.sc;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.EnumConstantClassNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.GroovyCodeVisitor;
import org.codehaus.groovy.ast.InnerClassNode;
@@ -482,7 +483,7 @@ public class StaticInvocationWriter extends InvocationWriter {
} else {
controller.getSourceUnit().addFatalError("Binding failed" +
" for arguments [" + argumentList.stream().map(arg -> typeChooser.resolveType(arg, classNode).toString(false)).collect(Collectors.joining(", ")) + "]" +
- " and parameters [" + Arrays.stream(parameters).map(prm -> prm.getType().toString(false)).collect(Collectors.joining(", ")) + "]", currentCall);
+ " and parameters [" + Arrays.stream(parameters).map(prm -> prm.getType().toString(false)).collect(Collectors.joining(", ")) + "]", getCurrentCall());
}
}
for (int i = 0; i < nArgs; i += 1) {
@@ -736,9 +737,11 @@ public class StaticInvocationWriter extends InvocationWriter {
type = ClassHelper.getWrapper(type);
}
ClassNode declaringClass = target.getDeclaringClass();
- if (type.getClass() != ClassNode.class
- && type.getClass() != InnerClassNode.class
- && type.getClass() != DecompiledClassNode.class) {
+ Class<?> typeClass = type.getClass();
+ if (typeClass != ClassNode.class
+ && typeClass != InnerClassNode.class
+ && typeClass != DecompiledClassNode.class
+ && typeClass != EnumConstantClassNode.class) {
type = declaringClass; // ex: LUB type
}
if (ClassHelper.OBJECT_TYPE.equals(declaringClass)) {
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index c47311a5fe..18436ed427 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -64,7 +64,6 @@ import static org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper;
import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
import static org.apache.groovy.util.BeanUtils.capitalize;
import static org.codehaus.groovy.ast.tools.ClosureUtils.getParametersSafe;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getSetterName;
/**
* Visitor to resolve constants and method calls from static imports.
@@ -224,7 +223,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
protected Expression transformVariableExpression(VariableExpression ve) {
Variable v = ve.getAccessedVariable();
if (v instanceof DynamicVariable) {
- Expression result = findStaticFieldOrPropAccessorImportFromModule(v.getName());
+ Expression result = findStaticFieldOrPropertyAccessorImportFromModule(v.getName());
if (result != null) {
setSourcePosition(result, ve);
if (inAnnotation) {
@@ -260,19 +259,9 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
if (!thisOrSuperMethod && currentClass.getOuterClasses().stream().noneMatch(oc -> oc.tryFindPossibleMethod(name, args) != null)) { // GROOVY-5239
Expression result = findStaticMethodImportFromModule(method, args);
if (result != null) {
- result.setSourcePosition(mce);
+ setSourcePosition(result, mce);
return result;
}
- if (name != null && !inLeftExpression) { // maybe a closure field
- result = findStaticFieldOrPropAccessorImportFromModule(name);
- if (result != null) {
- setSourcePosition(result, method);
- result = new MethodCallExpression(result, "call", args);
- ((MethodCallExpression) result).setImplicitThis(false);
- result.setSourcePosition(mce);
- return result;
- }
- }
}
} else if (staticWrtCurrent && isSuperExpression(object)) {
Expression result = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args);
@@ -401,117 +390,127 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
return pe;
}
- private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
- ModuleNode module = currentClass.getModule();
- if (module == null) return null;
- Map<String, ImportNode> importNodes = module.getStaticImports();
- Expression expression;
- String accessorName = getAccessorName(name);
+ //--------------------------------------------------------------------------
+
+ private Expression findStaticFieldOrPropertyAccessorImportFromModule(String name) {
+ ModuleNode module = currentClass.getModule(); if (module == null) return null;
+ Map<String, ImportNode> staticImports = module.getStaticImports();
+
// look for one of these:
// import static MyClass.setProp [as setOtherProp]
// import static MyClass.getProp [as getOtherProp]
- // when resolving prop reference
- if (importNodes.containsKey(accessorName)) {
- expression = findStaticProperty(importNodes, accessorName);
+ // import static MyClass.isProp [as isOtherProp]
+ // when resolving property reference
+ Expression expression;
+ expression = findStaticProperty(staticImports, getAccessorName(name));
+ if (expression != null) return expression;
+ if (!inLeftExpression) {
+ expression = findStaticProperty(staticImports, "is" + capitalize(name));
if (expression != null) return expression;
}
- if (accessorName.startsWith("get")) {
- accessorName = "is" + accessorName.substring(3);
- if (importNodes.containsKey(accessorName)) {
- expression = findStaticProperty(importNodes, accessorName);
- if (expression != null) return expression;
- }
- }
// look for one of these:
// import static MyClass.prop [as otherProp]
- // when resolving prop or field reference
- if (importNodes.containsKey(name)) {
- ImportNode importNode = importNodes.get(name);
- expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
- if (expression != null) return expression;
- expression = findStaticField(importNode.getType(), importNode.getFieldName());
+ // when resolving property or field reference
+ if (staticImports.containsKey(name)) { ImportNode importNode = staticImports.get(name);
+ expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
if (expression != null) return expression;
}
+
// look for one of these:
// import static MyClass.*
- // when resolving prop or field reference
+ // when resolving property or field reference
for (ImportNode importNode : module.getStaticStarImports().values()) {
- ClassNode node = importNode.getType();
- expression = findStaticPropertyAccessor(node, name);
- if (expression != null) return expression;
- expression = findStaticField(node, name);
+ expression = findStaticPropertyOrField(importNode.getType(), name);
if (expression != null) return expression;
}
- return null;
- }
- private Expression findStaticProperty(Map<String, ImportNode> importNodes, String accessorName) {
- Expression result = null;
- ImportNode importNode = importNodes.get(accessorName);
- ClassNode importClass = importNode.getType();
- String importMember = importNode.getFieldName();
- result = findStaticPropertyAccessorByFullName(importClass, importMember);
- if (result == null) {
- result = findStaticPropertyAccessor(importClass, getPropNameForAccessor(importMember));
- }
- return result;
+ return null;
}
private Expression findStaticMethodImportFromModule(Expression method, Expression args) {
- ModuleNode module = currentClass.getModule();
- if (module == null || !(method instanceof ConstantExpression)) return null;
- Map<String, ImportNode> importNodes = module.getStaticImports();
- ConstantExpression ce = (ConstantExpression) method;
+ if (currentClass.getModule() == null) return null;
+ if (!(method instanceof ConstantExpression)) return null;
+ if (!(((ConstantExpression) method).getValue() instanceof String)) return null;
+
Expression expression;
- Object value = ce.getValue();
- // skip non-Strings, e.g. Integer
- if (!(value instanceof String)) return null;
- final String name = (String) value;
+ String name = method.getText();
+ Map<String, ImportNode> staticImports = currentClass.getModule().getStaticImports();
// look for one of these:
- // import static SomeClass.method [as otherName]
- // when resolving methodCall() or getProp() or setProp()
- if (importNodes.containsKey(name)) {
- ImportNode importNode = importNodes.get(name);
+ // import static MyClass.field [as alias]
+ // import static MyClass.method [as alias]
+ // import static MyClass.property [as alias]
+ // when resolving implicit-this call name(args)
+ if (staticImports.containsKey(name)) {
+ ImportNode importNode = staticImports.get(name);
expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
- if (expression != null) return expression;
- expression = findStaticPropertyAccessorGivenArgs(importNode.getType(), getPropNameForAccessor(importNode.getFieldName()), args);
if (expression != null) {
- return newStaticMethodCallX(importNode.getType(), importNode.getFieldName(), args);
+ return expression;
+ }
+ if (!inClosure && !inLeftExpression) {
+ expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
+ if (expression != null) { // assume name refers to a callable static field/property
+ MethodCallExpression call = new MethodCallExpression(expression, "call", args);
+ call.setImplicitThis(false);
+ return call;
+ }
}
}
// look for one of these:
- // import static SomeClass.someProp [as otherName]
- // when resolving getProp() or setProp()
- if (isValidAccessorName(name)) {
- String propName = getPropNameForAccessor(name);
- if (importNodes.containsKey(propName)) {
- ImportNode importNode = importNodes.get(propName);
- ClassNode importClass = importNode.getType();
+ // import static MyClass.property [as alias]
+ // import static MyClass.setProperty [as alias]
+ // import static MyClass.getProperty [as alias]
+ // import static MyClass.isProperty [as alias]
+ // when resolving isName(), getName() or setName(args)
+ boolean accessor = isValidAccessorName(name);
+ if (accessor) {
+ ImportNode importNode = staticImports.get(name);
+ if (importNode != null) {
+ String propName = getPropNameForAccessor(importNode.getFieldName());
+ expression = findStaticPropertyAccessorGivenArgs(importNode.getType(), propName, args);
+ if (expression != null) { // expression may refer to getter or setter, so make new call
+ return newStaticMethodCallX(importNode.getType(), importNode.getFieldName(), args);
+ }
+ }
+ importNode = staticImports.get(getPropNameForAccessor(name));
+ if (importNode != null) {
+ ClassNode importType = importNode.getType();
String importMember = importNode.getFieldName();
- expression = findStaticMethod(importClass, prefix(name) + capitalize(importMember), args);
+ expression = findStaticMethod(importType, prefix(name) + capitalize(importMember), args);
if (expression != null) return expression;
- expression = findStaticPropertyAccessorGivenArgs(importClass, importMember, args);
+ expression = findStaticPropertyAccessorGivenArgs(importType, importMember, args);
if (expression != null) {
- return newStaticMethodCallX(importClass, prefix(name) + capitalize(importMember), args);
+ return newStaticMethodCallX(importType, prefix(name) + capitalize(importMember), args);
}
}
}
- Map<String, ImportNode> starImports = module.getStaticStarImports();
- ClassNode starImportType;
- if (currentClass.isEnum() && starImports.containsKey(currentClass.getName())) {
- ImportNode importNode = starImports.get(currentClass.getName());
- starImportType = importNode == null ? null : importNode.getType();
- expression = findStaticMethod(starImportType, name, args);
+
+ Map<String, ImportNode> staticStarImports = currentClass.getModule().getStaticStarImports();
+ if (currentClass.isEnum() && staticStarImports.containsKey(currentClass.getName())) {
+ ImportNode importNode = staticStarImports.get(currentClass.getName());
+ expression = findStaticMethod(importNode.getType(), name, args);
return expression;
- } else {
- for (ImportNode importNode : starImports.values()) {
- starImportType = importNode == null ? null : importNode.getType();
- expression = findStaticMethod(starImportType, name, args);
- if (expression != null) return expression;
- expression = findStaticPropertyAccessorGivenArgs(starImportType, getPropNameForAccessor(name), args);
- if (expression != null) {
- return newStaticMethodCallX(starImportType, name, args);
+ }
+ // look for one of these:
+ // import static MyClass.*
+ // when resolving name(args), getName(), etc.
+ for (ImportNode importNode : staticStarImports.values()) {
+ ClassNode importType = importNode.getType();
+ expression = findStaticMethod(importType, name, args);
+ if (expression != null) return expression;
+ if (!inClosure && !inLeftExpression) { // GROOVY-10329
+ expression = findStaticPropertyOrField(importType, name);
+ if (expression != null) { // assume name refers to a callable static field/property
+ MethodCallExpression call = new MethodCallExpression(expression, "call", args);
+ call.setImplicitThis(false);
+ return call;
+ }
+ }
+ if (accessor) {
+ String propName = getPropNameForAccessor(name);
+ expression = findStaticPropertyAccessorGivenArgs(importType, propName, args);
+ if (expression != null) { // expression may refer to getter or setter, so ...
+ return newStaticMethodCallX(importType, name, args);
}
}
}
@@ -523,44 +522,65 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
}
private String getAccessorName(String name) {
- return inLeftExpression ? getSetterName(name) : "get" + capitalize(name);
+ return (inLeftExpression ? "set" : "get") + capitalize(name);
+ }
+
+ private Expression findStaticPropertyAccessorByFullName(ClassNode staticImportType, String accessorName) {
+ Expression argumentList = inLeftExpression ? new ArgumentListExpression(EmptyExpression.INSTANCE) : ArgumentListExpression.EMPTY_ARGUMENTS;
+ Expression accessorExpr = findStaticMethod(staticImportType, accessorName, argumentList);
+ // TODO: GROOVY-9382, GROOVY-10133
+ return accessorExpr;
}
private Expression findStaticPropertyAccessorGivenArgs(ClassNode staticImportType, String propName, Expression args) {
- // TODO validate args?
- return findStaticPropertyAccessor(staticImportType, propName);
+ return findStaticPropertyAccessor(staticImportType, propName); // TODO: validate args?
}
private Expression findStaticPropertyAccessor(ClassNode staticImportType, String propName) {
String accessorName = getAccessorName(propName);
Expression accessor = findStaticPropertyAccessorByFullName(staticImportType, accessorName);
- if (accessor == null && accessorName.startsWith("get")) {
+ if (accessor == null && !inLeftExpression) {
accessor = findStaticPropertyAccessorByFullName(staticImportType, "is" + accessorName.substring(3));
}
if (accessor == null && hasStaticProperty(staticImportType, propName)) {
- // args will be replaced
if (inLeftExpression)
- accessor = newStaticMethodCallX(staticImportType, accessorName, ArgumentListExpression.EMPTY_ARGUMENTS);
+ accessor = newStaticMethodCallX(staticImportType, accessorName, ArgumentListExpression.EMPTY_ARGUMENTS); // <-- will be replaced
else
accessor = newStaticPropertyX(staticImportType, propName);
}
return accessor;
}
- private Expression findStaticPropertyAccessorByFullName(ClassNode staticImportType, String accessorMethodName) {
- // anything will do as we only check size == 1
- ArgumentListExpression dummyArgs = new ArgumentListExpression();
- dummyArgs.addExpression(EmptyExpression.INSTANCE);
- return findStaticMethod(staticImportType, accessorMethodName, (inLeftExpression ? dummyArgs : ArgumentListExpression.EMPTY_ARGUMENTS));
+ private Expression findStaticPropertyOrField(ClassNode staticImportType, String variableName) {
+ Expression expression = findStaticPropertyAccessor(staticImportType, variableName);
+ if (expression == null) {
+ if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
+ FieldNode field = getField(staticImportType, variableName);
+ if (field != null && field.isStatic())
+ expression = newStaticPropertyX(staticImportType, variableName);
+ }
+ }
+ return expression;
}
- private static Expression findStaticField(ClassNode staticImportType, String fieldName) {
- if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
- FieldNode field = getField(staticImportType, fieldName);
- if (field != null && field.isStatic())
- return newStaticPropertyX(staticImportType, fieldName);
+ private Expression findStaticProperty(Map<String, ImportNode> staticImports, String accessorName) {
+ Expression expression = null;
+ ImportNode importNode = staticImports.get(accessorName);
+ if (importNode != null) { ClassNode importType = importNode.getType();
+ expression = findStaticPropertyAccessorByFullName(importType, importNode.getFieldName());
+ if (expression == null) { // perhaps the property accessor will be generated
+ String propertyName = getPropNameForAccessor(importNode.getFieldName());
+ if (hasStaticProperty(importType, propertyName)) {
+ if (inLeftExpression) {
+ expression = newStaticMethodCallX(importType, importNode.getFieldName(),
+ ArgumentListExpression.EMPTY_ARGUMENTS); // <-- will be replaced
+ } else {
+ expression = newStaticPropertyX(importType, propertyName);
+ }
+ }
+ }
}
- return null;
+ return expression;
}
private static Expression findStaticMethod(ClassNode staticImportType, String methodName, Expression args) {
diff --git a/src/test/Outer3.groovy b/src/test/Outer3.groovy
deleted file mode 100644
index ee2ffa6ccf..0000000000
--- a/src/test/Outer3.groovy
+++ /dev/null
@@ -1,22 +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.
- */
-class Outer3 {
- // test class with no package and having a static inner class
- static class Inner3 {}
-}
diff --git a/src/test/Outer4.groovy b/src/test/Outer4.groovy
deleted file mode 100644
index 52385dbdc3..0000000000
--- a/src/test/Outer4.groovy
+++ /dev/null
@@ -1,22 +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.
- */
-class Outer4 {
- // test class with no package and having a static inner class
- static class Inner4 {}
-}
diff --git a/src/test/groovy/StaticImportTest.groovy b/src/test/groovy/StaticImportTest.groovy
index f04699f545..409aa93090 100644
--- a/src/test/groovy/StaticImportTest.groovy
+++ b/src/test/groovy/StaticImportTest.groovy
@@ -318,6 +318,27 @@ final class StaticImportTest extends groovy.test.GroovyTestCase {
}
}
+ // GROOVY-8389, GROOVY-10329
+ void testStaticImportPropertyWithClosure() {
+ for (imports in ['import static Foo.bar; import static Foo.baz', 'import static Foo.*']) {
+ assertScript """$imports
+ class Foo {
+ static Closure<String> bar = { -> 'property' }
+ static Closure<String> baz = { -> 'property' }
+ }
+ String bar() {
+ 'method'
+ }
+ @groovy.transform.CompileStatic
+ def test() {
+ bar() + ':' + baz()
+ }
+ String result = test()
+ assert result == 'method:property'
+ """
+ }
+ }
+
// GROOVY-8389
void testStaticImportMethodVsLocalMethod() {
assertScript '''
@@ -423,6 +444,29 @@ final class StaticImportTest extends groovy.test.GroovyTestCase {
}
}
+ // GROOVY-7490, GROOVY-10329
+ void testStaticImportOfCallableProperty() {
+ for (imports in ['import static Pogo.callable_property', 'import static Pogo.*']) {
+ assertScript """$imports
+ class WithCall {
+ String call(String input) {
+ return input
+ }
+ }
+ class Pogo {
+ static final WithCall callable_property = new WithCall()
+ }
+
+ @groovy.transform.CompileStatic
+ def usage() {
+ callable_property('works')
+ }
+ String result = usage()
+ assert result == 'works'
+ """
+ }
+ }
+
// GROOVY-4145
void testStaticPropertyImportedImplementedAsGetter() {
assertScript '''
diff --git a/src/test/groovy/bugs/Groovy4145.groovy b/src/test/groovy/bugs/Groovy4145.groovy
deleted file mode 100644
index d45349055d..0000000000
--- a/src/test/groovy/bugs/Groovy4145.groovy
+++ /dev/null
@@ -1,25 +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
-
-class Groovy4145 {
- static getFoo4145() {
- return 3
- }
-}
\ No newline at end of file
diff --git a/src/test/groovy/bugs/Groovy8389Bug.groovy b/src/test/groovy/bugs/Groovy8389Bug.groovy
deleted file mode 100644
index 5443b27c0c..0000000000
--- a/src/test/groovy/bugs/Groovy8389Bug.groovy
+++ /dev/null
@@ -1,111 +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.test.GroovyTestCase
-
-class Groovy8389Bug extends GroovyTestCase {
- void testLocalMethodInvoked() {
- assertScript '''
- import static A.bar
-
- class A {
- static bar = "A"
- }
-
- def bar() {
- "bar"
- }
-
- @groovy.transform.CompileStatic
- def usage() {
- bar()
- }
-
- assert "bar" == usage()
- '''
- }
-
- void testLocalMethodInvoked2() {
- assertScript '''
- import static A.bar
-
- class A {
- static bar = "A"
- }
-
- static bar() {
- "bar"
- }
-
- @groovy.transform.CompileStatic
- def usage() {
- bar()
- }
-
- assert "bar" == usage()
- '''
- }
-
- void testLocalMethodInvoked3() {
- assertScript '''
- import static A.baz
- import static A.bar
-
- class A {
- static bar() { "Abar" }
- static baz() { "Abaz" }
- }
-
- def bar() {
- "bar"
- }
-
- @groovy.transform.CompileStatic
- def usage() {
- "${bar()}${baz()}"
- }
-
- assert usage() == 'barAbaz'
- '''
- }
-
- void testLocalMethodInvoked4() {
- assertScript '''
- import static A.baz
- import static A.bar
-
- class A {
- static bar() { "Abar" }
- static baz() { "Abaz" }
- }
-
- static bar() {
- "bar"
- }
-
- @groovy.transform.CompileStatic
- def usage() {
- "${bar()}${baz()}"
- }
-
- assert usage() == 'barAbaz'
- '''
- }
-}