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/02/25 20:36:54 UTC
[groovy] 02/02: GROOVY-10396: StaticImportVisitor: static context skips instance methods
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
commit 2871e15cc275d04b43f0a2e45b200c3321bdd4f3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Nov 30 10:54:18 2021 -0600
GROOVY-10396: StaticImportVisitor: static context skips instance methods
Conflicts:
src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
src/test/groovy/StaticImportTest.groovy
---
.../groovy/control/StaticImportVisitor.java | 35 +-
src/test/groovy/StaticImportTest.groovy | 487 +++++++++++++++------
src/test/groovy/bugs/Groovy8389Bug.groovy | 109 -----
3 files changed, 375 insertions(+), 256 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index eb74e80..5ac4917 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -227,14 +227,6 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
return ve;
}
- private boolean hasPossibleClassOrOuterMethod(String name, Expression args) {
- if (currentClass.tryFindPossibleMethod(name, args) != null) return true;
- for (ClassNode outerClass : currentClass.getOuterClasses()) {
- if (outerClass.tryFindPossibleMethod(name, args) != null) return true;
- }
- return false;
- }
-
/**
* Set the source position of toSet including its property expression if it has one.
*
@@ -253,24 +245,30 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
Expression method = transform(mce.getMethod());
Expression args = transform(mce.getArguments());
+ // GROOVY-10396: skip the instance method checks when the context is static with-respect-to current class
+ boolean staticWrtCurrent = inSpecialConstructorCall || currentMethod != null && currentMethod.isStatic();
+
if (mce.isImplicitThis()) {
String name = mce.getMethodAsString();
- if (!hasPossibleClassOrOuterMethod(name, args)) { // GROOVY-5239
+ boolean thisOrSuperMethod = staticWrtCurrent ? hasPossibleStaticMethod(currentClass, name, args, true) : currentClass.tryFindPossibleMethod(name, args) != null;
+ if (!thisOrSuperMethod && !hasPossibleOuterMethod(currentClass, name, args)) { // GROOVY-5239
Expression result = findStaticMethodImportFromModule(method, args);
if (result != null) {
- setSourcePosition(result, mce);
+ result.setSourcePosition(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 (currentMethod != null && currentMethod.isStatic() && isSuperExpression(object)) {
+ } else if (staticWrtCurrent && isSuperExpression(object)) {
Expression result = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args);
result.setSourcePosition(mce);
return result;
@@ -279,7 +277,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
if (method instanceof ConstantExpression && ((ConstantExpression) method).getValue() instanceof String && (mce.isImplicitThis() || isThisOrSuper(object))) {
String methodName = (String) ((ConstantExpression) method).getValue();
- boolean foundInstanceMethod = (currentMethod != null && !currentMethod.isStatic() && currentClass.hasPossibleMethod(methodName, args));
+ boolean foundInstanceMethod = !staticWrtCurrent && currentClass.hasPossibleMethod(methodName, args);
if (mce.isImplicitThis()) {
if (isInnerClass(currentClass)) {
@@ -353,7 +351,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
if (currentMethod != null && currentMethod.isStatic()
&& isSuperExpression(pe.getObjectExpression())) {
PropertyExpression pexp = new PropertyExpression(
- new ClassExpression(currentClass.getSuperClass()),
+ new ClassExpression(currentClass.getUnresolvedSuperClass()),
transform(pe.getProperty())
);
pexp.setSourcePosition(pe);
@@ -370,7 +368,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
if (foundArgs != null && foundConstant != null
&& !foundConstant.getText().trim().isEmpty()
&& objectExpression instanceof MethodCallExpression
- && ((MethodCallExpression)objectExpression).isImplicitThis()) {
+ && ((MethodCallExpression) objectExpression).isImplicitThis()) {
Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
if (result != null) {
objectExpression = result;
@@ -568,6 +566,15 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
return false;
}
+ private static boolean hasPossibleOuterMethod(ClassNode type, String name, Expression args) {
+ for (ClassNode outerClass : type.getOuterClasses()) {
+ if (outerClass.tryFindPossibleMethod(name, args) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static PropertyExpression newStaticPropertyX(ClassNode type, String name) {
return new PropertyExpression(new ClassExpression(type.getPlainNodeReference()), name);
}
diff --git a/src/test/groovy/StaticImportTest.groovy b/src/test/groovy/StaticImportTest.groovy
index 5f12f0b..4f2f35d 100644
--- a/src/test/groovy/StaticImportTest.groovy
+++ b/src/test/groovy/StaticImportTest.groovy
@@ -18,7 +18,6 @@
*/
package groovy
-import gls.CompilableTestSupport
import static java.lang.Boolean.FALSE as F
import static java.text.DateFormat.MEDIUM as M
import static java.util.regex.Pattern.*
@@ -27,24 +26,21 @@ import static junit.framework.Assert.format
import static junit.framework.Assert.assertEquals
import static groovy.StaticImportTarget.x
import static groovy.StaticImportTarget.z // do not remove
-import static groovy.StaticImportTarget.cl
import static java.lang.Math.*
import static java.util.Calendar.getInstance as now
import static groovy.API.*
import static groovy.StaticImportChild.*
-import static groovy.bugs.Groovy4145.foo4145
import static groovy.Outer1.*
import static groovy.Outer2.Inner2
import static groovy.Outer2.Inner2 as InnerAlias2
import static java.util.jar.Attributes.*
import static java.util.jar.Attributes.Name as AttrName
-// TODO GROOVY-4287: reinstate next two imports
-//import static Outer3.*
-//import static Outer4.Inner4
import static groovy.Container5087.*
+import static Foo4964.*
import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
-class StaticImportTest extends CompilableTestSupport {
+final class StaticImportTest extends gls.CompilableTestSupport {
+
void testFieldWithAliasInExpression() {
assert !F
}
@@ -71,15 +67,16 @@ class StaticImportTest extends CompilableTestSupport {
}
void testFieldAsArgumentList() {
- assert ("" + PI.toString()).contains('3.14')
+ assert ('' + PI.toString()).contains('3.14')
}
void testFieldAliasing() {
assert MEDIUM == M
}
+ // GROOVY-1809
void testMethodAliasing() {
- // GROOVY-1809 making this not possible on one line?
+ // making this not possible on one line?
def now = now().time
assert now.class == Date
}
@@ -91,7 +88,7 @@ class StaticImportTest extends CompilableTestSupport {
private format(a, b, c, ignored) { format(a, b, c) }
void testMethodDefCanUseStaticallyImportedMethodWithSameNameButDiffArgs() {
- assert format("different", "abc", "aBc", 3) == 'different expected:<abc> but was:<aBc>'
+ assert format('different', 'abc', 'aBc', 3) == 'different expected:<abc> but was:<aBc>'
}
void testAssertEqualsFromJUnit() {
@@ -103,15 +100,15 @@ class StaticImportTest extends CompilableTestSupport {
}
void testStaticImportFromGroovy() {
- def nonstaticval = new StaticImportTarget().y("he", 3)
- def staticval = x("he", 3)
+ def nonstaticval = new StaticImportTarget().y('he', 3)
+ def staticval = x('he', 3)
assert nonstaticval == staticval
}
void testStaticImportWithVarArgs() {
- assert noArrayMethod("one", 1) == 'noArrayMethod(one, 1)'
- assert API.arrayMethod("two", 1, 2, 3) == 'arrayMethod(two, 1, 2, 3)'
- assert arrayMethod("three", 1, 2, 3) == 'arrayMethod(three, 1, 2, 3)'
+ assert noArrayMethod('one', 1) == 'noArrayMethod(one, 1)'
+ assert API.arrayMethod('two', 1, 2, 3) == 'arrayMethod(two, 1, 2, 3)'
+ assert arrayMethod('three', 1, 2, 3) == 'arrayMethod(three, 1, 2, 3)'
}
void testStaticImportFromParentClass() {
@@ -120,126 +117,284 @@ class StaticImportTest extends CompilableTestSupport {
assert cfield == 21
assert pfield == 42
}
-
+
void testStaticImportAndDefaultValue() {
- assertScript """
- import static Foo.*
- import static Bar.*
-
- class Bar {
- static void bar() {
- assert foo(10,1000) == 1010
- assert foo(10) == 110
- }
- }
-
- class Foo {
- static int foo(int x, int y = 100) {x+y}
- }
-
- Bar.bar()
- """
+ assertScript '''
+ import static Foo.*
+ import static Bar.*
+
+ class Bar {
+ static void bar() {
+ assert foo(10,1000) == 1010
+ assert foo(10) == 110
+ }
+ }
+
+ class Foo {
+ static int foo(int x, int y = 100) {x+y}
+ }
+
+ Bar.bar()
+ '''
}
void testStaticImportProperty() {
- def sources = [
- "class Foo { static x = 'foo'" + " }",
- "class Foo { static x = 'foo'" + "; static getX() { x + '_get' } }",
- "class Foo { static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }",
- "class Foo { static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }"
- ]
- def imports = [
- "import static Foo.*",
- "import static Foo.getX; import static Foo.setX"
- ]
- def results = [
- "assert x == 'foo'; x = 'bar'; assert getX() == 'bar'; setX('baz'); assert 'baz' == x",
- "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_get'; setX('baz'); assert 'baz_get' == x",
- "assert x == 'foo'; x = 'bar'; assert getX() == 'bar_set'; setX('baz'); assert 'baz_set' == x",
- "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == x"
- ]
- [0..<sources.size(), 0..<imports.size()].combinations().each { i, j ->
- assertScript sources[i] + "\n" + imports[j] + "\n" + results[i]
+ for (imports in ['import static Foo.getX; import static Foo.setX', 'import static Foo.*']) {
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ }
+ assert x == 'foo'
+ x = 'bar'
+ assert getX() == 'bar'
+ setX('baz')
+ assert 'baz' == x
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static getX() { x + '_get' }
+ }
+ assert x == 'foo_get'
+ x = 'bar'
+ assert getX() == 'bar_get'
+ setX('baz')
+ assert 'baz_get' == x
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert x == 'foo'
+ x = 'bar'
+ assert getX() == 'bar_set'
+ setX('baz')
+ assert 'baz_set' == x
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static getX() { x + '_get' }
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert x == 'foo_get'
+ x = 'bar'
+ assert getX() == 'bar_set_get'
+ setX('baz')
+ assert 'baz_set_get' == x
+ """
}
}
void testStaticImportPropertyBooleanAlternative() {
- def sources = [
- "class Foo { static x = null" + "; static boolean isX() { x } }",
- "class Foo { static x = null" + "; static boolean isX() { x }; static void setX(newx) { x = newx } }"
- ]
- def imports = [
- "import static Foo.*",
- "import static Foo.x",
- "import static Foo.isX; import static Foo.setX"
- ]
- def results = [
- "assert !x; x = true ; assert isX(); setX(false); assert !x",
- "assert !x; x = false; assert !isX(); setX(true); assert x"
- ]
- [0..<sources.size(), 0..<imports.size()].combinations().each { i, j ->
- assertScript sources[i] + "\n" + imports[j] + "\n" + results[i]
+ for (imports in ['import static Foo.isX; import static Foo.setX', 'import static Foo.x', 'import static Foo.*']) {
+ assertScript """$imports
+ class Foo {
+ static x
+ static boolean isX() { !!x }
+ }
+ assert !x
+ x = true
+ assert isX()
+ setX(false)
+ assert !x
+ """
+ assertScript """$imports
+ class Foo {
+ static x
+ static boolean isX() { !!x }
+ static void setX(newx) { x = newx }
+ }
+ assert !x
+ x = false
+ assert !isX()
+ setX(true)
+ assert x
+ """
}
}
void testStaticImportPropertyWithPublicField() {
- def sources = [
- "class Foo { public static x = 'foo'" + " }",
- "class Foo { public static x = 'foo'" + "; static getX() { x + '_get' } }",
- "class Foo { public static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }",
- "class Foo { public static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }"
- ]
- def imports = [
- "import static Foo.*",
- "import static Foo.x"
- ]
- def results = [
- "assert x == 'foo'; x = 'bar'; assert x == 'bar'; x = 'baz' ; assert 'baz' == x",
- "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_get'; x = 'baz' ; assert 'baz_get' == x",
- "assert x == 'foo'; x = 'bar'; assert x == 'bar_set'; setX('baz'); assert 'baz_set' == x",
- "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == x"
- ]
- [0..<sources.size(), 0..<imports.size()].combinations().each { i, j ->
- assertScript sources[i] + "\n" + imports[j] + "\n" + results[i]
+ for (imports in ['import static Foo.x', 'import static Foo.*']) {
+ assertScript """$imports
+ class Foo {
+ public static x = 'foo'
+ }
+ assert x == 'foo'
+ x = 'bar'
+ assert x == 'bar'
+ x = 'baz'
+ assert x == 'baz'
+ """
+ assertScript """$imports
+ class Foo {
+ public static x = 'foo'
+ static getX() { x + '_get' }
+ }
+ assert x == 'foo_get'
+ x = 'bar'
+ assert getX() == 'bar_get'
+ x = 'baz'
+ assert x == 'baz_get'
+ """
+ assertScript """$imports
+ class Foo {
+ public static x = 'foo'
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert x == 'foo'
+ x = 'bar'
+ assert x == 'bar_set'
+ setX('baz')
+ assert x == 'baz_set'
+ """
+ assertScript """$imports
+ class Foo {
+ public static x = 'foo'
+ static getX() { x + '_get' }
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert x == 'foo_get'
+ x = 'bar'
+ assert getX() == 'bar_set_get'
+ setX('baz')
+ assert x == 'baz_set_get'
+ """
}
- assertScript sources[3] + """
+ assertScript '''
import static Foo.getX; import static Foo.setX
+ class Foo { public static x = 'foo'; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }
assert getX() == 'foo_get'; setX('bar'); assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == getX()
- """
+ '''
}
void testStaticImportPropertyWithAliases() {
- def sources = [
- "class Foo { static x = 'foo'" + " }",
- "class Foo { static x = 'foo'" + "; static getX() { x + '_get' } }",
- "class Foo { static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }",
- "class Foo { static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }"
- ]
- def imports = [
- "import static Foo.x as z",
- "import static Foo.getX as getZ; import static Foo.setX as setZ"
- ]
- def results = [
- "assert z == 'foo'; z = 'bar'; assert getZ() == 'bar'; setZ('baz'); assert 'baz' == z",
- "assert z == 'foo_get'; z = 'bar'; assert getZ() == 'bar_get'; setZ('baz'); assert 'baz_get' == z",
- "assert z == 'foo'; z = 'bar'; assert getZ() == 'bar_set'; setZ('baz'); assert 'baz_set' == z",
- "assert z == 'foo_get'; z = 'bar'; assert getZ() == 'bar_set_get'; setZ('baz'); assert 'baz_set_get' == z"
- ]
- [0..<sources.size(), 0..<imports.size()].combinations().each { i, j ->
- assertScript sources[i] + "\n" + imports[j] + "\n" + results[i]
+ for (imports in ['import static Foo.getX as getZ; import static Foo.setX as setZ', 'import static Foo.x as z']) {
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ }
+ assert z == 'foo'
+ z = 'bar'
+ assert getZ() == 'bar'
+ setZ('baz')
+ assert z == 'baz'
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static getX() { x + '_get' }
+ }
+ assert z == 'foo_get'
+ z = 'bar'
+ assert getZ() == 'bar_get'
+ setZ('baz')
+ assert z == 'baz_get'
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert z == 'foo'
+ z = 'bar'
+ assert getZ() == 'bar_set'
+ setZ('baz')
+ assert z == 'baz_set'
+ """
+ assertScript """$imports
+ class Foo {
+ static x = 'foo'
+ static getX() { x + '_get' }
+ static void setX(newx) { x = newx + '_set' }
+ }
+ assert z == 'foo_get'
+ z = 'bar'
+ assert getZ() == 'bar_set_get'
+ setZ('baz')
+ assert z == 'baz_set_get'
+ """
}
}
+ // GROOVY-8389
+ void testStaticImportMethodVsLocalMethod() {
+ assertScript '''
+ import static Foo.bar
+ class Foo {
+ static bar = 'foo'
+ }
+ def bar() {
+ 'bar'
+ }
+ @groovy.transform.CompileStatic
+ def test() {
+ bar()
+ }
+ assert test() == 'bar'
+ '''
+
+ assertScript '''
+ import static Foo.bar
+ class Foo {
+ static bar = 'foo'
+ }
+ static bar() {
+ 'bar'
+ }
+ @groovy.transform.CompileStatic
+ def test() {
+ bar()
+ }
+ assert test() == 'bar'
+ '''
+
+ assertScript '''
+ import static Foo.baz
+ import static Foo.bar
+ class Foo {
+ static bar() { 'foobar' }
+ static baz() { 'foobaz' }
+ }
+ def bar() {
+ 'bar'
+ }
+ @groovy.transform.CompileStatic
+ def test() {
+ "${bar()}${baz()}"
+ }
+ assert test() == 'barfoobaz'
+ '''
+
+ assertScript '''
+ import static Foo.baz
+ import static Foo.bar
+ class Foo {
+ static bar() { 'foobar' }
+ static baz() { 'foobaz' }
+ }
+ static bar() {
+ 'bar'
+ }
+ @groovy.transform.CompileStatic
+ def test() {
+ "${bar()}${baz()}"
+ }
+ assert test() == 'barfoobaz'
+ '''
+ }
+
void testConstructorArgsAliasing() {
// not recommended style to use statics in constructors but supported
- assertScript """
- class Foo {
- static x
- }
- import static Foo.x as z
- new Foo(z:'hi')
- assert z == 'hi'
- """
+ assertScript '''
+ class Foo {
+ static x
+ }
+ import static Foo.x as z
+ new Foo(z:'hi')
+ assert z == 'hi'
+ '''
}
void testMethodCallWithThisTargetIsNotResolvedToStaticallyImportedMethod() {
@@ -257,17 +412,33 @@ class StaticImportTest extends CompilableTestSupport {
fail()
} catch (MissingMethodException expected) {}
}
-
- void testStaticImportOfAClosureField() { //GROOVY-3945
- assert cl() == 'StaticImportTarget#static closure called'
+
+ // GROOVY-3945, GROOVY-10329
+ void testStaticImportOfClosureProperty() {
+ for (imports in ['import static groovy.StaticImportTarget.cl', 'import static groovy.StaticImportTarget.*']) {
+ assertScript """$imports
+ String result = cl()
+ assert result == 'StaticImportTarget#static closure called'
+ """
+ }
}
- void testStaticPropertyImportedImplementedAsGetter() { //GROOVY-4145
- assert foo4145 == 3
+ // GROOVY-4145
+ void testStaticPropertyImportedImplementedAsGetter() {
+ assertScript '''
+ import static Groovy4145.foo4145
+ class Groovy4145 {
+ static getFoo4145() {
+ return 3
+ }
+ }
+ assert foo4145 == 3
+ '''
}
- void testMethodCallExpressionInStaticContextWithInstanceVariableShouldFail() { //GROOVY-4228
- shouldNotCompile '''
+ // GROOVY-4228
+ void testMethodCallExpressionInStaticContextWithInstanceVariableShouldFail() {
+ def err = shouldFail '''
class B {
def c = new Object()
static main(args) {
@@ -275,6 +446,57 @@ class StaticImportTest extends CompilableTestSupport {
}
}
'''
+ assert err =~ /Apparent variable 'c' was found in a static scope but doesn't refer to a local variable, static field or class/
+ }
+
+ // GROOVY-10396
+ void testStaticImportVersusThisOrSuperMethod1() {
+ assertScript '''
+ import static groovy.Extension10396.*
+
+ static void test() {
+ println 'x'
+ }
+ strings.clear()
+ test()
+
+ assert 'x' in strings
+ '''
+ }
+
+ // GROOVY-10396
+ void testStaticImportVersusThisOrSuperMethod2() {
+ assertScript '''
+ import static groovy.Extension10396.*
+
+ def obj = new Object() { // outer class extends Script
+ String toString() {
+ println 'AIC::x'
+ super.toString()
+ }
+ }
+ strings.clear()
+ obj.toString()
+
+ assert !('x' in strings)
+ '''
+ }
+
+ // GROOVY-10396
+ void testStaticImportVersusThisOrSuperMethod3() {
+ assertScript '''
+ import static groovy.Extension10396.*
+
+ static void println(String s) { // static overload
+ }
+ static void test() {
+ println 'x'
+ }
+ strings.clear()
+ test()
+
+ assert !('x' in strings)
+ '''
}
void testStaticStarImportOfStaticInnerClass() {
@@ -301,15 +523,6 @@ class StaticImportTest extends CompilableTestSupport {
Bar4964.run()
}
- // TODO GROOVY-4287: reinstate next two tests
-// void testStaticStarImportOfStaticInnerClassExternalClass() {
-// assert Inner3.class.name == 'Outer3$Inner3'
-// }
-//
-// void testStaticImportOfStaticInnerClassExternalClass() {
-// assert Inner4.class.name == 'Outer4$Inner4'
-// }
-
void testMapIndexInLeftExpressionOfEquals() {
holder = 'foo'
def map = [:]
@@ -337,6 +550,8 @@ class StaticImportTest extends CompilableTestSupport {
}
}
+//------------------------------------------------------------------------------
+
class API {
static noArrayMethod(String s, int value) {
"noArrayMethod(${s}, ${value})"
@@ -348,13 +563,13 @@ class API {
}
class StaticImportParent {
- static pfield = 42
- static pmethod() { 'hello from parent' }
+ static pfield = 42
+ static pmethod() { 'hello from parent' }
}
class StaticImportChild extends StaticImportParent {
- static cfield = 21
- static cmethod() { 'hello from child' }
+ static cfield = 21
+ static cmethod() { 'hello from child' }
}
class Outer1 {
@@ -369,7 +584,6 @@ class Foo4964 {
static doIt() { [k: 'foo'] }
}
-import static Foo4964.*
class Bar4964 {
static doIt() { [k: 'bar'] }
@@ -405,3 +619,10 @@ class HolderWrapper {
holder[name] = value
}
}
+
+class Extension10396 {
+ static final List<String> strings = []
+ static void println(String s) {
+ strings << s
+ }
+}
diff --git a/src/test/groovy/bugs/Groovy8389Bug.groovy b/src/test/groovy/bugs/Groovy8389Bug.groovy
deleted file mode 100644
index bf56fbd..0000000
--- a/src/test/groovy/bugs/Groovy8389Bug.groovy
+++ /dev/null
@@ -1,109 +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 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'
- '''
- }
-}