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 bf30d25e12 GROOVY-7490, GROOVY-8389, GROOVY-10329: import static
callable property
bf30d25e12 is described below
commit bf30d25e12f85f6ee871844bfd3887d97fefde5c
Author: Eric Milles <[email protected]>
AuthorDate: Mon Mar 6 11:25:21 2023 -0600
GROOVY-7490, GROOVY-8389, GROOVY-10329: import static callable property
2_5_X backport
---
.../org/codehaus/groovy/classgen/Verifier.java | 48 ++--
.../groovy/control/StaticImportVisitor.java | 241 +++++++++++----------
src/test/Outer3.groovy | 22 --
src/test/Outer4.groovy | 22 --
src/test/groovy/StaticImportTest.groovy | 44 ++++
src/test/groovy/bugs/Groovy4145.groovy | 25 ---
6 files changed, 197 insertions(+), 205 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index ed40d7731c..c9b3763df1 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -19,7 +19,6 @@
package org.codehaus.groovy.classgen;
import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyObject;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
@@ -359,6 +358,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);
+ final ClassNode classNode = this.classNode;
node.addSyntheticMethod(
"$getStaticMetaClass",
ACC_PROTECTED,
@@ -1281,31 +1281,33 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
return MetaClassHelper.capitalize(name);
}
- protected Statement createGetterBlock(PropertyNode propertyNode, final
FieldNode field) {
+ protected Statement createGetterBlock(final PropertyNode propertyNode,
final FieldNode field) {
+ final String owner = BytecodeHelper.getClassInternalName(classNode);
return new BytecodeSequence(new BytecodeInstruction() {
public void visit(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());
}
});
}
- protected Statement createSetterBlock(PropertyNode propertyNode, final
FieldNode field) {
+ protected Statement createSetterBlock(final PropertyNode propertyNode,
final FieldNode field) {
+ final String owner = BytecodeHelper.getClassInternalName(classNode);
return new BytecodeSequence(new BytecodeInstruction() {
@Override
public void visit(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);
}
@@ -1496,48 +1498,42 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
}
}
- // if we reach this point we have at least one parameter or return
type, that
- // is different in its specified form. That means we have to create a
bridge method!
- MethodNode newMethod = new MethodNode(
+ // 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
+ final String owner = BytecodeHelper.getClassInternalName(classNode);
+ return new MethodNode(
oldMethod.getName(),
overridingMethod.getModifiers() | ACC_SYNTHETIC | ACC_BRIDGE,
cleanType(oldMethod.getReturnType()),
cleanParameters(oldMethod.getParameters()),
oldMethod.getExceptions(),
- null
- );
- List instructions = new ArrayList(1);
- instructions.add(
- new BytecodeInstruction() {
+ new BytecodeSequence(new BytecodeInstruction() {
@Override
public void visit(MethodVisitor mv) {
mv.visitVarInsn(ALOAD, 0);
Parameter[] para = oldMethod.getParameters();
Parameter[] goal = overridingMethod.getParameters();
int doubleSlotOffset = 0;
- for (int i = 0; i < para.length; i++) {
+ for (int i = 0; i < para.length; ++i) {
ClassNode type = para[i].getType();
BytecodeHelper.load(mv, type, i + 1 +
doubleSlotOffset);
- if (type.redirect() == ClassHelper.double_TYPE ||
- type.redirect() == ClassHelper.long_TYPE) {
- doubleSlotOffset++;
+ if (type.redirect() == ClassHelper.double_TYPE
+ || type.redirect() ==
ClassHelper.long_TYPE) {
+ doubleSlotOffset += 1;
}
if (!type.equals(goal[i].getType())) {
BytecodeHelper.doCast(mv, goal[i].getType());
}
}
- mv.visitMethodInsn(INVOKEVIRTUAL,
BytecodeHelper.getClassInternalName(classNode), overridingMethod.getName(),
BytecodeHelper.getMethodDescriptor(overridingMethod.getReturnType(),
overridingMethod.getParameters()), false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, owner,
overridingMethod.getName(),
BytecodeHelper.getMethodDescriptor(overridingMethod.getReturnType(),
overridingMethod.getParameters()), false);
BytecodeHelper.doReturn(mv, oldMethod.getReturnType());
}
- }
-
+ })
);
- newMethod.setCode(new BytecodeSequence(instructions));
- return newMethod;
}
- private boolean isAssignable(ClassNode node, ClassNode testNode) {
+ private static boolean isAssignable(ClassNode node, ClassNode testNode) {
if (node.isArray() && testNode.isArray()) {
return isArrayAssignable(node.getComponentType(),
testNode.getComponentType());
}
@@ -1547,7 +1543,7 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
return node.isDerivedFrom(testNode);
}
- private boolean isArrayAssignable(ClassNode node, ClassNode testNode) {
+ private static boolean isArrayAssignable(ClassNode node, ClassNode
testNode) {
if (node.isArray() && testNode.isArray()) {
return isArrayAssignable(node.getComponentType(),
testNode.getComponentType());
}
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index 5ac4917d47..b86c2cf2c9 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -205,7 +205,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) {
@@ -254,19 +254,9 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
if (!thisOrSuperMethod && !hasPossibleOuterMethod(currentClass,
name, args)) { // 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);
@@ -383,117 +373,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);
}
}
}
@@ -508,41 +508,62 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
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) {
@@ -575,14 +596,14 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
return false;
}
- private static PropertyExpression newStaticPropertyX(ClassNode type,
String name) {
- return new PropertyExpression(new
ClassExpression(type.getPlainNodeReference()), name);
- }
-
private static StaticMethodCallExpression newStaticMethodCallX(ClassNode
type, String name, Expression args) {
return new StaticMethodCallExpression(type.getPlainNodeReference(),
name, args);
}
+ private static PropertyExpression newStaticPropertyX(ClassNode type,
String name) {
+ return new PropertyExpression(new
ClassExpression(type.getPlainNodeReference()), name);
+ }
+
@Override
protected SourceUnit getSourceUnit() {
return sourceUnit;
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 4f2f35dc3a..347aa8f67e 100644
--- a/src/test/groovy/StaticImportTest.groovy
+++ b/src/test/groovy/StaticImportTest.groovy
@@ -318,6 +318,27 @@ final class StaticImportTest extends
gls.CompilableTestSupport {
}
}
+ // 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
gls.CompilableTestSupport {
}
}
+ // 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