Skip to content

Commit 98135b3

Browse files
committed
GROOVY-11056
1 parent f359f84 commit 98135b3

6 files changed

Lines changed: 139 additions & 47 deletions

File tree

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/ImportsTests.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2022 the original author or authors.
2+
* Copyright 2009-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -364,15 +364,15 @@ public void testStaticImport4() {
364364
"package a\n" +
365365
"interface B {\n" +
366366
" String C = 'nls'\n" +
367-
"}",
367+
"}\n",
368368

369369
"x/Y.groovy",
370370
"package x\n" +
371371
"import static a.B.C\n" +
372372
"class Y {\n" +
373373
" @SuppressWarnings(C) def one() {}\n" +
374374
" @SuppressWarnings(C) def two() {}\n" +
375-
"}",
375+
"}\n",
376376
};
377377
//@formatter:on
378378

@@ -392,7 +392,7 @@ public void testStaticImport5() {
392392
"package a\n" +
393393
"class B {\n" +
394394
" static boolean c = true\n" +
395-
"}",
395+
"}\n",
396396
};
397397
//@formatter:on
398398

@@ -410,13 +410,37 @@ public void testStaticImport5() {
410410
"package a\n" +
411411
"class B {\n" +
412412
" static boolean c\n" +
413-
"}",
413+
"}\n",
414414
};
415415
//@formatter:on
416416

417417
runConformTest(sources, "true");
418418
}
419419

420+
@Test // GROOVY-10329, GROOVY-11056
421+
public void testStaticImport6() {
422+
//@formatter:off
423+
String[] sources = {
424+
"Main.groovy",
425+
"import static p.C.callable\n" +
426+
"callable('foo')\n" +
427+
"def functor = {\n" +
428+
" callable('bar')\n" +
429+
"}\n" +
430+
"functor.call()\n",
431+
432+
"p/C.groovy",
433+
"package p\n" +
434+
"class C {\n" +
435+
" public static callable = new C()\n" +
436+
" void call(... args) { print args[0] }\n" +
437+
"}\n",
438+
};
439+
//@formatter:on
440+
441+
runConformTest(sources, "foobar");
442+
}
443+
420444
@Test
421445
public void testStaticImports_JtoG() {
422446
//@formatter:off

base/org.codehaus.groovy30/src/org/codehaus/groovy/control/StaticImportVisitor.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,19 @@
7070
* Visitor to resolve constants and method calls from static imports.
7171
*/
7272
public class StaticImportVisitor extends ClassCodeExpressionTransformer {
73-
private ClassNode currentClass;
74-
private MethodNode currentMethod;
73+
7574
private SourceUnit sourceUnit;
76-
private boolean inSpecialConstructorCall;
77-
private boolean inClosure;
78-
private boolean inPropertyExpression;
79-
private Expression foundConstant;
75+
private ClassNode currentClass;
76+
private MethodNode currentMethod;
77+
8078
private Expression foundArgs;
79+
private Expression foundConstant;
80+
81+
private boolean inClosure;
8182
private boolean inAnnotation;
8283
private boolean inLeftExpression;
84+
private boolean inPropertyExpression;
85+
private boolean inSpecialConstructorCall;
8386

8487
/**
8588
* Use {@link #StaticImportVisitor(ClassNode,SourceUnit)}.
@@ -261,9 +264,14 @@ protected Expression transformMethodCallExpression(MethodCallExpression mce) {
261264
Expression result = findStaticMethodImportFromModule(method, args);
262265
if (result != null) {
263266
// GRECLIPSE add
264-
if (result instanceof MethodCallExpression) {
267+
if (result instanceof MethodCallExpression) { // aka "pack.Type.member.call()"
265268
Expression member = ((MethodCallExpression) result).getObjectExpression();
266-
member.putNodeMetaData("static.import.alias", name);
269+
String memberName = member instanceof MethodCall
270+
? ((MethodCall) member).getMethodAsString()
271+
: ((PropertyExpression) member).getPropertyAsString();
272+
if (!memberName.equals(name)) { // retain source identifier
273+
member.putNodeMetaData("static.import.alias", name);
274+
}
267275
setSourcePosition(member, method);
268276

269277
result.setLastColumnNumber(mce.getLastColumnNumber());
@@ -473,10 +481,8 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
473481
if (staticImports.containsKey(name)) {
474482
ImportNode importNode = staticImports.get(name);
475483
expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
476-
if (expression != null) {
477-
return expression;
478-
}
479-
if (!inClosure && !inLeftExpression) {
484+
if (expression != null) return expression;
485+
if (!inLeftExpression) { // GROOVY-11056, et al.
480486
expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
481487
if (expression != null) { // assume name refers to a callable static field/property
482488
MethodCallExpression call = new MethodCallExpression(expression, "call", args);
@@ -527,7 +533,7 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
527533
ClassNode importType = importNode.getType();
528534
expression = findStaticMethod(importType, name, args);
529535
if (expression != null) return expression;
530-
if (!inClosure && !inLeftExpression) { // GROOVY-10329
536+
if (!inLeftExpression) { // GROOVY-10329, et al.
531537
expression = findStaticPropertyOrField(importType, name);
532538
if (expression != null) { // assume name refers to a callable static field/property
533539
MethodCallExpression call = new MethodCallExpression(expression, "call", args);

base/org.codehaus.groovy40/src/org/codehaus/groovy/control/StaticImportVisitor.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,19 @@
7373
* Visitor to resolve constants and method calls from static imports.
7474
*/
7575
public class StaticImportVisitor extends ClassCodeExpressionTransformer {
76-
private ClassNode currentClass;
77-
private MethodNode currentMethod;
76+
7877
private SourceUnit sourceUnit;
79-
private boolean inSpecialConstructorCall;
80-
private boolean inClosure;
81-
private boolean inPropertyExpression;
82-
private Expression foundConstant;
78+
private ClassNode currentClass;
79+
private MethodNode currentMethod;
80+
8381
private Expression foundArgs;
82+
private Expression foundConstant;
83+
84+
private boolean inClosure;
8485
private boolean inAnnotation;
8586
private boolean inLeftExpression;
87+
private boolean inPropertyExpression;
88+
private boolean inSpecialConstructorCall;
8689

8790
public StaticImportVisitor(final ClassNode classNode, final SourceUnit sourceUnit) {
8891
this.currentClass = classNode;
@@ -256,9 +259,14 @@ protected Expression transformMethodCallExpression(MethodCallExpression mce) {
256259
Expression result = findStaticMethodImportFromModule(method, args);
257260
if (result != null) {
258261
// GRECLIPSE add
259-
if (result instanceof MethodCallExpression) {
262+
if (result instanceof MethodCallExpression) { // aka "pack.Type.member.call()"
260263
Expression member = ((MethodCallExpression) result).getObjectExpression();
261-
member.putNodeMetaData("static.import.alias", name);
264+
String memberName = member instanceof MethodCall
265+
? ((MethodCall) member).getMethodAsString()
266+
: ((PropertyExpression) member).getPropertyAsString();
267+
if (!memberName.equals(name)) { // retain source identifier
268+
member.putNodeMetaData("static.import.alias", name);
269+
}
262270
setSourcePosition(member, method);
263271

264272
result.setLastColumnNumber(mce.getLastColumnNumber());
@@ -466,10 +474,8 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
466474
if (staticImports.containsKey(name)) {
467475
ImportNode importNode = staticImports.get(name);
468476
expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
469-
if (expression != null) {
470-
return expression;
471-
}
472-
if (!inClosure && !inLeftExpression) {
477+
if (expression != null) return expression;
478+
if (!inLeftExpression) { // GROOVY-11056, et al.
473479
expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
474480
if (expression != null) { // assume name refers to a callable static field/property
475481
MethodCallExpression call = new MethodCallExpression(expression, "call", args);
@@ -520,7 +526,7 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
520526
ClassNode importType = importNode.getType();
521527
expression = findStaticMethod(importType, name, args);
522528
if (expression != null) return expression;
523-
if (!inClosure && !inLeftExpression) { // GROOVY-10329
529+
if (!inLeftExpression) { // GROOVY-10329, et al.
524530
expression = findStaticPropertyOrField(importType, name);
525531
if (expression != null) { // assume name refers to a callable static field/property
526532
MethodCallExpression call = new MethodCallExpression(expression, "call", args);

base/org.codehaus.groovy50/src/org/codehaus/groovy/control/StaticImportVisitor.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,19 @@
7373
* Visitor to resolve constants and method calls from static imports.
7474
*/
7575
public class StaticImportVisitor extends ClassCodeExpressionTransformer {
76-
private ClassNode currentClass;
77-
private MethodNode currentMethod;
76+
7877
private SourceUnit sourceUnit;
79-
private boolean inSpecialConstructorCall;
80-
private boolean inClosure;
81-
private boolean inPropertyExpression;
82-
private Expression foundConstant;
78+
private ClassNode currentClass;
79+
private MethodNode currentMethod;
80+
8381
private Expression foundArgs;
82+
private Expression foundConstant;
83+
84+
private boolean inClosure;
8485
private boolean inAnnotation;
8586
private boolean inLeftExpression;
87+
private boolean inPropertyExpression;
88+
private boolean inSpecialConstructorCall;
8689

8790
public StaticImportVisitor(final ClassNode classNode, final SourceUnit sourceUnit) {
8891
this.currentClass = classNode;
@@ -256,9 +259,14 @@ protected Expression transformMethodCallExpression(MethodCallExpression mce) {
256259
Expression result = findStaticMethodImportFromModule(method, args);
257260
if (result != null) {
258261
// GRECLIPSE add
259-
if (result instanceof MethodCallExpression) {
262+
if (result instanceof MethodCallExpression) { // aka "pack.Type.member.call()"
260263
Expression member = ((MethodCallExpression) result).getObjectExpression();
261-
member.putNodeMetaData("static.import.alias", name);
264+
String memberName = member instanceof MethodCall
265+
? ((MethodCall) member).getMethodAsString()
266+
: ((PropertyExpression) member).getPropertyAsString();
267+
if (!memberName.equals(name)) { // retain source identifier
268+
member.putNodeMetaData("static.import.alias", name);
269+
}
262270
setSourcePosition(member, method);
263271

264272
result.setLastColumnNumber(mce.getLastColumnNumber());
@@ -466,10 +474,8 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
466474
if (staticImports.containsKey(name)) {
467475
ImportNode importNode = staticImports.get(name);
468476
expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
469-
if (expression != null) {
470-
return expression;
471-
}
472-
if (!inClosure && !inLeftExpression) {
477+
if (expression != null) return expression;
478+
if (!inLeftExpression) { // GROOVY-11056, et al.
473479
expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
474480
if (expression != null) { // assume name refers to a callable static field/property
475481
MethodCallExpression call = new MethodCallExpression(expression, "call", args);
@@ -520,7 +526,7 @@ private Expression findStaticMethodImportFromModule(Expression method, Expressio
520526
ClassNode importType = importNode.getType();
521527
expression = findStaticMethod(importType, name, args);
522528
if (expression != null) return expression;
523-
if (!inClosure && !inLeftExpression) { // GROOVY-10329
529+
if (!inLeftExpression) { // GROOVY-10329, et al.
524530
expression = findStaticPropertyOrField(importType, name);
525531
if (expression != null) { // assume name refers to a callable static field/property
526532
MethodCallExpression call = new MethodCallExpression(expression, "call", args);

ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/actions/AliasingOrganizeImportsTests.groovy

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,31 @@ final class AliasingOrganizeImportsTests extends OrganizeImportsTestSuite {
518518
doContentsCompareTest(contents)
519519
}
520520

521+
@Test // https://github.com/groovy/groovy-eclipse/issues/1309
522+
void testRetainStaticAlias16() {
523+
createGroovyType 'p', 'C', '''\
524+
|class C {
525+
| public static callable = new C()
526+
| public static closure = { -> }
527+
| def call(... args) {
528+
| }
529+
|}
530+
|'''
531+
532+
for (tag in ['', '@groovy.transform.CompileStatic']) {
533+
String contents = """\
534+
|import static p.C.callable as bar
535+
|import static p.C.closure as baz
536+
|$tag
537+
|void foo() {
538+
| bar()
539+
| baz()
540+
|}
541+
|"""
542+
doContentsCompareTest(contents)
543+
}
544+
}
545+
521546
@Test
522547
void testRemoveStaticAlias1() {
523548
String originalContents = '''\

ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/actions/OrganizeImportsTests.groovy

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,28 @@ final class OrganizeImportsTests extends OrganizeImportsTestSuite {
12491249

12501250
@Test // https://github.com/groovy/groovy-eclipse/issues/1309
12511251
void testStaticImport22() {
1252+
createGroovyType 'p', 'C', '''\
1253+
|class C {
1254+
| static getClosure_property() {
1255+
| return { -> }
1256+
| }
1257+
|}
1258+
|'''
1259+
1260+
for (tag in ['', '@groovy.transform.CompileStatic']) {
1261+
String contents = """\
1262+
|import static p.C.closure_property
1263+
|$tag
1264+
|void test() {
1265+
| closure_property()
1266+
|}
1267+
|"""
1268+
doContentsCompareTest(contents)
1269+
}
1270+
}
1271+
1272+
@Test // https://github.com/groovy/groovy-eclipse/issues/1309
1273+
void testStaticImport23() {
12521274
createGroovyType 'p', 'C', '''\
12531275
|class C {
12541276
| static final callable_property = new C()
@@ -1273,20 +1295,23 @@ final class OrganizeImportsTests extends OrganizeImportsTestSuite {
12731295
}
12741296

12751297
@Test // https://github.com/groovy/groovy-eclipse/issues/1309
1276-
void testStaticImport23() {
1298+
void testStaticImport24() {
12771299
createGroovyType 'p', 'C', '''\
12781300
|class C {
1279-
| static getClosure_property() {
1280-
| return { -> }
1301+
| public static callable_property = new C()
1302+
| public static closure_property = { -> }
1303+
| def call(... args) {
12811304
| }
12821305
|}
12831306
|'''
12841307

12851308
for (tag in ['', '@groovy.transform.CompileStatic']) {
12861309
String contents = """\
1310+
|import static p.C.callable_property
12871311
|import static p.C.closure_property
12881312
|$tag
12891313
|void test() {
1314+
| callable_property()
12901315
| closure_property()
12911316
|}
12921317
|"""

0 commit comments

Comments
 (0)