diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovySimpleTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovySimpleTests.java index 2aec0fc9b9..1b478cec32 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovySimpleTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/GroovySimpleTests.java @@ -28,11 +28,9 @@ import java.util.Map; import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ImportNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.ast.Parameter; -import org.codehaus.jdt.groovy.internal.compiler.ast.AliasImportReference; import org.codehaus.jdt.groovy.internal.compiler.ast.EventListener; import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyClassScope; import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration; @@ -41,7 +39,6 @@ import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.junit.Ignore; @@ -115,26 +112,6 @@ public void testGreclipse719_2() { "----------\n"); } - @Test - public void testDuplicateClassesUnnecessaryExceptions() { - runNegativeTest(new String[] { - "A.groovy", - "class Foo {}\n"+ - "class Foo {}", - }, - "----------\n" + - "1. ERROR in A.groovy (at line 2)\n" + - "\tclass Foo {}\n" + - "\t^^^^^^^^^^^^\n" + - "Groovy:Invalid duplicate class definition of class Foo : The source A.groovy contains at least two definitions of the class Foo.\n" + - "----------\n" + - "2. ERROR in A.groovy (at line 2)\n" + - "\tclass Foo {}\n" + - "\t ^^^\n" + - "The type Foo is already defined\n" + - "----------\n"); - } - @Test public void testStaticProperty() { runConformTest(new String[] { @@ -243,6 +220,26 @@ public void testUnreachable_1047_2() { }); } + @Test + public void testDuplicateClassesUnnecessaryExceptions() { + runNegativeTest(new String[] { + "A.groovy", + "class Foo {}\n"+ + "class Foo {}", + }, + "----------\n" + + "1. ERROR in A.groovy (at line 2)\n" + + "\tclass Foo {}\n" + + "\t^^^^^^^^^^^^\n" + + "Groovy:Invalid duplicate class definition of class Foo : The source A.groovy contains at least two definitions of the class Foo.\n" + + "----------\n" + + "2. ERROR in A.groovy (at line 2)\n" + + "\tclass Foo {}\n" + + "\t ^^^\n" + + "The type Foo is already defined\n" + + "----------\n"); + } + /** * This test is looking at what happens when a valid type is compiled ahead of two problem types (problematic * since they both declare the same class). Although the first file gets through resolution OK, re-resolution @@ -345,192 +342,6 @@ public void testCrashRatherThanError_GRE986() { "----------\n"); } - @Test - public void testAmbiguous_GRE945_gu() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static Factory fact = new Factory()\n"+ - " public static void main(String[]argv) {\n"+ - " fact.foo()\n"+ - " }\n"+ - "}\n", - - "Factory.groovy", - "package bug.factory\n"+ - "class Factory { static foo() { print 'abc'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_jl() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static StringBuffer fact = new StringBuffer()\n"+ - " public static void main(String[]argv) {\n"+ - " print fact.foo()\n"+ - " }\n"+ - "}\n", - - "StringBuffer.groovy", - "package bug.factory\n"+ - "class StringBuffer { static String foo() { return 'abc'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_bothFromSource() { - runConformTest(new String[] { - "Code.groovy", - "import a.*\n"+ - "import b.*\n"+ - "class Code {\n"+ - " static A fact = new A()\n"+ - " public static void main(String[]argv) {\n"+ - " print fact.foo()\n"+ - " }\n"+ - "}\n", - - "a/A.groovy", - "package a\n"+ - "class A { static String foo() { return 'abc'}}\n", - - "b/A.groovy", - "package b\n"+ - "class A { static String foo() { return 'def'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_bothFromSource_2() { - runConformTest(new String[] { - "Code.groovy", - "import b.*\n"+ - "import a.*\n"+ - "class Code {\n"+ - " static A fact = new A()\n"+ - " public static void main(String[]argv) {\n"+ - " print fact.foo()\n"+ - " }\n"+ - "}\n", - - "a/A.groovy", - "package a\n"+ - "class A { static String foo() { return 'abc'}}\n", - - "b/A.groovy", - "package b\n"+ - "class A { static String foo() { return 'def'}}\n", - }, - "def"); - } - - @Test - public void testAmbiguous_GRE945_bothFromSource_3() { - runConformTest(new String[] { - "Code.groovy", - "import b.*\n"+ - "import a.*\n"+ - "class Code {\n"+ - " static Process fact = new Process()\n"+ - " public static void main(String[]argv) {\n"+ - " print fact.foo()\n"+ - " }\n"+ - "}\n", - - "a/Process.groovy", - "package a\n"+ - "class Process { static String foo() { return 'abc'}}\n", - - "b/Process.groovy", - "package b\n"+ - "class Process { static String foo() { return 'def'}}\n", - }, - "def"); - } - - @Test - public void testAmbiguous_GRE945_ju() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static List fact = new List()\n"+ - " public static void main(String[]argv) {\n"+ - " fact.foo()\n"+ - " }\n"+ - "}\n", - - "List.groovy", - "package bug.factory\n"+ - "class List { static foo() { print 'abc'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_jn() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static Socket fact = new Socket()\n"+ - " public static void main(String[]argv) {\n"+ - " fact.foo()\n"+ - " }\n"+ - "}\n", - - "Socket.groovy", - "package bug.factory\n"+ - "class Socket { static foo() { print 'abc'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_gl() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static Tuple fact = new Tuple()\n"+ - " public static void main(String[]argv) {\n"+ - " fact.foo()\n"+ - " }\n"+ - "}\n", - - "Tuple.groovy", - "package bug.factory\n"+ - "class Tuple { static foo() { print 'abc'}}\n", - }, - "abc"); - } - - @Test - public void testAmbiguous_GRE945_ji() { - runConformTest(new String[] { - "Code.groovy", - "import bug.factory.*\n"+ - "class Code {\n"+ - " static Serializable fact = new Serializable()\n"+ - " public static void main(String[]argv) {\n"+ - " fact.foo()\n"+ - " }\n"+ - "}\n", - - "Serializable.groovy", - "package bug.factory\n"+ - "class Serializable { static foo() { print 'abc'}}\n", - }, - "abc"); - } - @Test public void testStaticOuter_GRE944_2() { runNegativeTest(new String[] { @@ -1307,38 +1118,6 @@ public void testOverriding_ReducedVisibility3a() { "----------\n"); } - @Test - public void testAliasing_GRE473() { - runConformTest(new String[] { - "Foo.groovy", - "import java.util.regex.Pattern as JavaPattern\n"+ - "class Pattern {JavaPattern javaPattern}\n"+ - "def p = new Pattern(javaPattern:~/\\d+/)\n"+ - "assert \"123\" ==~ p.javaPattern\n"+ - "print 'success '\n"+ - "print '['+p.class.name+']['+JavaPattern.class.name+']'\n", - }, - "success [Pattern][java.util.regex.Pattern]"); - } - - @Test - public void testAliasing_GRE473_2() { - runNegativeTest(new String[] { - "Foo.groovy", - "import java.util.regex.Pattern\n"+ - "class Pattern {Pattern javaPattern}\n"+ - "def p = new Pattern(javaPattern:~/\\d+/)\n"+ - "assert \"123\" ==~ p.javaPattern\n"+ - "print 'success'\n", - }, - "----------\n" + - "1. ERROR in Foo.groovy (at line 1)\n" + - "\timport java.util.regex.Pattern\n" + - "\t ^^^^^^^^^^^^^^^^^^^^^^^\n" + - "The import java.util.regex.Pattern conflicts with a type defined in the same file\n" + - "----------\n"); - } - @Test public void testEnumPositions_GRE1072() { runConformTest(new String[] { @@ -2261,22 +2040,6 @@ public void testNotSeriousEnough_GRE396_2() { "----------\n"); } - @Test - public void testStarImports_GRE421() { - runConformTest(new String[] { - "Wibble.groovy", - "import a.b.c.*;\n"+ - "class Wibble {\n"+ - " Process process = new Process()\n"+ - " public static void main(String[] argv) { print new Wibble().process.class}\n"+ - "}\n", - "a/b/c/Process.java", - "package a.b.c;\n"+ - "public class Process {}\n", - }, - "class a.b.c.Process"); - } - // The getter for 'description' implements the interface @Test public void testImplementingAnInterfaceViaProperty() { @@ -2391,26 +2154,6 @@ public void testProtectedType() { "success"); } - @Test - public void testNonTerminalMissingImport() { - runNegativeTest(new String[] { - "p/X.groovy", - "package p;\n" + - "import a.b.c.D;\n"+ - "public class X {\n" + - " public static void main(String[]argv) {\n"+ - " print \"success\"\n"+ - " }\n"+ - "}\n", - }, - "----------\n" + - "1. ERROR in p\\X.groovy (at line 2)\n" + - "\timport a.b.c.D;\n" + - "\t ^^^^^^^\n" + - "Groovy:unable to resolve class a.b.c.D\n" + - "----------\n"); - } - @Test public void testTypeClash() { runNegativeTest(new String[] { @@ -2855,7 +2598,7 @@ public void testImplementingInterface_JavaExtendingGroovyAndImplementingMethod() } @Test - public void testFieldPositioning01() { + public void testFieldPositioning1() { runNegativeTest(new String[] { "p/C.groovy", "package p;\n" + @@ -2873,7 +2616,7 @@ public void testFieldPositioning01() { // FIXASC poor positional error for invalid field name - this test needs sorting out @Test - public void testFieldPositioning02() { + public void testFieldPositioning2() { runNegativeTest(new String[] { "p/C.groovy", "package p;\n" + @@ -3046,321 +2789,113 @@ public void testImplementingInterface_MethodWithParameters_GextendsJ() { "success"); } - // Test that the alias is recognized when referenced as superclass - // WMTW: the code Scope.getShortNameFor() @Test - public void testImportAliasingGoober() { + public void testImplementingInterface_MethodWithParameters_JextendsG() { runConformTest(new String[] { - "p/C.groovy", + "p/C.java", "package p;\n" + - "import java.util.HashMap as Goober;\n"+ - "public class C extends Goober {\n"+ + "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ + " public void m(String s) { }\n"+ " public static void main(String[] argv) {\n"+ - " print 'q.A.run'\n"+ + " System.out.println( \"success\");\n"+ " }\n"+ "}\n", + + "p/I.groovy", + "package p;\n"+ + "public interface I {\n" + + " void m(String s);\n"+ + "}\n", }, - "q.A.run"); + "success"); } @Test - public void testImportAliasing() { + public void testImplementingInterface_MethodWithParameters2_JextendsG() { runConformTest(new String[] { - "p/C.groovy", + "p/C.java", "package p;\n" + - "import q.A as AA;\n"+ - "import r.A as AB;\n"+ - "public class C {\n"+ + "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ + " public void m(String s, Integer i) { }\n"+ " public static void main(String[] argv) {\n"+ - " callitOne(new AA());\n"+ - " callitTwo(new AB());\n"+ + " System.out.println( \"success\");\n"+ " }\n"+ - " public static void callitOne(AA a) { a.run();}\n"+ - " public static void callitTwo(AB a) { a.run();}\n"+ - "}\n", - - "q/A.java", - "package q;\n"+ - "public class A {\n" + - " public static void run() { System.out.print(\"q.A.run \");}\n"+ "}\n", - "r/A.java", - "package r;\n"+ - "public class A {\n" + - " public static void run() { System.out.print(\"r.A.run\");}\n"+ + "p/I.groovy", + "package p;\n"+ + "public interface I {\n" + + " void m(String s, Integer i);\n"+ "}\n", }, - "q.A.run r.A.run"); + "success"); } @Test - public void testImportAliasingAndOldReference() { - runNegativeTest(new String[] { + public void testImplementingInterface_MethodWithParameters2_GextendsJ() { + runConformTest(new String[] { "p/C.groovy", "package p;\n" + - "import q.A as AA;\n"+ - "import r.A as AB;\n"+ - "public class C {\n"+ + "public class C implements I {\n"+ + " public void m(String s, Integer i) { return null;}\n"+ " public static void main(String[] argv) {\n"+ - " callitOne(new AA());\n"+ + " System.out.println( \"success\");\n"+ " }\n"+ - " public static void callitOne(A a) { }\n"+ // no A imported! - "}\n", - - "q/A.java", - "package q;\n"+ - "public class A {\n" + - " public static void run() { System.out.print(\"q.A.run \");}\n"+ "}\n", - "r/A.java", - "package r;\n"+ - "public class A {\n" + - " public static void run() { System.out.print(\"r.A.run\");}\n"+ + "p/I.java", + "package p;\n"+ + "public interface I {\n" + + " void m(String s, Integer i);\n"+ "}\n", }, - "----------\n" + - "1. ERROR in p\\C.groovy (at line 8)\n" + - "\tpublic static void callitOne(A a) { }\n" + - "\t ^\n" + - "Groovy:unable to resolve class A\n" + - "----------\n"); + "success"); } @Test - public void testImportInnerInner01() { + public void testImplementingInterface_MethodWithParameters3_GextendsJ() { runConformTest(new String[] { "p/C.groovy", "package p;\n" + - "public class C {\n"+ - " private static Wibble.Inner.Inner2 wibbleInner = new G();\n"+ + "public class C implements I {\n"+ + " public void m(String s, Integer i) { return null;}\n"+ " public static void main(String[] argv) {\n"+ - " wibbleInner.run();\n"+ + " System.out.println( \"success\");\n"+ " }\n"+ - "}\n"+ - "class G extends Wibble.Inner.Inner2 {}", + "}\n", - "p/Wibble.java", + "p/I.java", "package p;\n"+ - "public class Wibble {\n" + - " public static class Inner {\n"+ - " public static class Inner2 {\n"+ - " public static void run() { System.out.print(\"p.Wibble.Inner.Inner2.run \");}\n"+ - " }\n"+ - " }\n"+ + "public interface I {\n" + + " void m(String s, T t);\n"+ "}\n", }, - "p.Wibble.Inner.Inner2.run"); + "success"); } @Test - public void testImportInnerClass01_JavaCase() { + public void testImplementingInterface_MethodWithParameters3_JextendsG() { runConformTest(new String[] { "p/C.java", "package p;\n" + - "import x.y.z.Wibble.Inner;\n"+ - "\n"+ - "public class C {\n"+ - " private static Inner wibbleInner = new Inner();\n"+ + "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ + " public void m(String s, Integer i) { }\n"+ " public static void main(String[] argv) {\n"+ - " wibbleInner.run();\n"+ + " System.out.println( \"success\");\n"+ " }\n"+ "}\n", - "x/y/z/Wibble.java", - "package x.y.z;\n"+ - "public class Wibble {\n" + - " public static class Inner {\n"+ - " public static void run() { System.out.print(\"q.A.run \");}\n"+ - " }\n"+ + "p/I.groovy", + "package p;\n"+ + "public interface I {\n" + + " void m(String s, T t);\n"+ "}\n", }, - "q.A.run"); + "success"); } - // FIXASC need to look at all other kinds of import - statics/double nested static classes/etc @Test - public void testImportInnerClass01_GroovyCase() { - runConformTest(new String[] { - "p/C.groovy", - "package p;\n" + - "import x.y.z.Wibble.Inner\n"+ - "\n"+ - "public class C {\n"+ - " private static Inner wibbleInner = new Inner();\n"+ - " public static void main(String[] argv) {\n"+ - " wibbleInner.run();\n"+ - " }\n"+ - "}\n", - - "x/y/z/Wibble.java", - "package x.y.z;\n"+ - "public class Wibble {\n" + - " public static class Inner {\n"+ - " public static void run() { System.out.print(\"q.A.run \");}\n"+ - " }\n"+ - "}\n", - }, - "q.A.run"); - } - - @Test - public void testImportInnerClass() { - runConformTest(new String[] { - "p/C.groovy", - "package p;\n" + - "import x.y.z.Wibble.Inner /*as WibbleInner*/;\n"+ - "public class C {\n"+ - " private static Inner wibbleInner = new Inner();\n"+ - " public static void main(String[] argv) {\n"+ - " wibbleInner.run();\n"+ - " }\n"+ - //" public static void callitOne(WibbleInner a) { a.run();}\n"+ - "}\n", - - "x/y/z/Wibble.java", - "package x.y.z;\n"+ - "public class Wibble {\n" + - " public static class Inner {\n"+ - " public void run() { System.out.print(\"run\");}\n"+ - " }\n"+ - "}\n", - }, - "run"); - } - - @Test - public void testImportAliasingInnerClass() { - runConformTest(new String[] { - "p/C.groovy", - "package p;\n" + - "import x.y.z.Wibble.Inner as WibbleInner;\n"+ - "public class C {\n"+ - " private static WibbleInner wibbleInner = new WibbleInner();\n"+ - " public static void main(String[] argv) {\n"+ - " wibbleInner.run();\n"+ - " }\n"+ - "}\n", - - "x/y/z/Wibble.java", - "package x.y.z;\n"+ - "public class Wibble {\n" + - " public static class Inner {\n"+ - " public void run() { System.out.print(\"run \");}\n"+ - " }\n"+ - "}\n", - }, - "run"); - } - - @Test - public void testImplementingInterface_MethodWithParameters_JextendsG() { - runConformTest(new String[] { - "p/C.java", - "package p;\n" + - "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ - " public void m(String s) { }\n"+ - " public static void main(String[] argv) {\n"+ - " System.out.println( \"success\");\n"+ - " }\n"+ - "}\n", - - "p/I.groovy", - "package p;\n"+ - "public interface I {\n" + - " void m(String s);\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testImplementingInterface_MethodWithParameters2_JextendsG() { - runConformTest(new String[] { - "p/C.java", - "package p;\n" + - "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ - " public void m(String s, Integer i) { }\n"+ - " public static void main(String[] argv) {\n"+ - " System.out.println( \"success\");\n"+ - " }\n"+ - "}\n", - - "p/I.groovy", - "package p;\n"+ - "public interface I {\n" + - " void m(String s, Integer i);\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testImplementingInterface_MethodWithParameters2_GextendsJ() { - runConformTest(new String[] { - "p/C.groovy", - "package p;\n" + - "public class C implements I {\n"+ - " public void m(String s, Integer i) { return null;}\n"+ - " public static void main(String[] argv) {\n"+ - " System.out.println( \"success\");\n"+ - " }\n"+ - "}\n", - - "p/I.java", - "package p;\n"+ - "public interface I {\n" + - " void m(String s, Integer i);\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testImplementingInterface_MethodWithParameters3_GextendsJ() { - runConformTest(new String[] { - "p/C.groovy", - "package p;\n" + - "public class C implements I {\n"+ - " public void m(String s, Integer i) { return null;}\n"+ - " public static void main(String[] argv) {\n"+ - " System.out.println( \"success\");\n"+ - " }\n"+ - "}\n", - - "p/I.java", - "package p;\n"+ - "public interface I {\n" + - " void m(String s, T t);\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testImplementingInterface_MethodWithParameters3_JextendsG() { - runConformTest(new String[] { - "p/C.java", - "package p;\n" + - "public class C extends groovy.lang.GroovyObjectSupport implements I {\n"+ - " public void m(String s, Integer i) { }\n"+ - " public static void main(String[] argv) {\n"+ - " System.out.println( \"success\");\n"+ - " }\n"+ - "}\n", - - "p/I.groovy", - "package p;\n"+ - "public interface I {\n" + - " void m(String s, T t);\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testCallingMethods_JcallingG() { + public void testCallingMethods_JcallingG() { runConformTest(new String[] { "p/C.java", "package p;\n" + @@ -3503,8 +3038,7 @@ public void testGroovyObjectsAreGroovyAtCompileTime() { "p/OtherClass.groovy", "package p;\n"+ - "import java.util.*;\n"+ - "public class OtherClass {\n" + + "class OtherClass {\n" + "}\n", }, "success"); @@ -3525,8 +3059,7 @@ public void testCallGroovyObjectMethods_invokeMethod() { "p/OtherClass.groovy", "package p;\n"+ - "import java.util.*;\n"+ - "public class OtherClass {\n" + + "class OtherClass {\n" + " String toString() { return \"success\";}\n"+ "}\n", }, @@ -3547,8 +3080,7 @@ public void testGroovyObjectsAreGroovyAtRunTime() { "p/OtherClass.groovy", "package p;\n"+ - "import java.util.*;\n"+ - "public class OtherClass {\n" + + "class OtherClass {\n" + "}\n", }, "true"); @@ -4157,156 +3689,6 @@ public void testTwoTopLevelTypesInAFile() { "success"); } - @Test - public void testImports1() { - runConformTest(new String[] { - "p/First.groovy", - "package p;\n"+ - "import java.util.regex.Pattern\n"+ - "public class First {\n"+ - " public static void main(String[] argv) {\n"+ - " Pattern p = Pattern.compile(\".\")\n"+ - " print \"success\"\n"+ - " }\n"+ - " public Pattern getPattern() { return null;}\n"+ - "}\n", - }, - "success"); - } - - @Test - public void testImports2() { - runConformTest(new String[] { - "p/First.groovy", - "package p;\n"+ - "import java.util.regex.Pattern\n"+ - "public class First {\n"+ - " public static void main(String[] argv) {\n"+ - " print \"success\"\n"+ - " }\n"+ - " public File getFile() { return null;}\n"+ // java.io.File should be picked up magically - "}\n", - }, - "success"); - } - - @Test - public void testImportsBigDecimal1() { - runConformTest(new String[] { - "p/Main.java", - "package p;\n" + - "public class Main {\n" + - " public static void main(String[] args) {\n" + - " System.out.print(new Big().getAmount().toString());\n" + // https://github.com/groovy/groovy-eclipse/issues/268 - " }\n" + - "}\n", - - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " BigDecimal amount = 3.14\n" + - "}\n", - }, - "3.14"); - } - - @Test - public void testImportsBigDecimal2() { - runConformTest(new String[] { - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " static void main(String[] args) {\n" + - " print 'success'\n" + - " }\n" + - " BigDecimal getAmount() { return 0 }\n" + - "}\n", - }, - "success"); - } - - @Test - public void testImportsBigDecimal3() { - // this version has an import; that can make a difference... - runConformTest(new String[] { - "p/Big.groovy", - "package p\n" + - "import java.util.regex.Pattern\n" + - "class Big {\n" + - " static void main(String[] args) {\n" + - " print 'success'\n" + - " }\n" + - " BigDecimal getAmount() { return 0 }\n" + - "}\n", - }, - "success"); - } - - @Test - public void testImportsBigDecimal4() { - runConformTest(new String[] { - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " static void main(String[] args) {\n" + - " print 'success'\n" + - " }\n" + - " private static final BigDecimal FIXED_AMOUNT = BigDecimal.TEN\n" + - "}\n", - }, - "success"); - } - - @Test - public void testImportsBigInteger1() { - runConformTest(new String[] { - "p/Main.java", - "package p;\n" + - "public class Main {\n" + - " public static void main(String[] args) {\n" + - " System.out.print(new Big().getAmount().toString());\n" + - " }\n" + - "}\n", - - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " BigInteger amount = 10\n" + - "}\n", - }, - "10"); - } - - @Test - public void testImportsBigInteger2() { - runConformTest(new String[] { - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " static void main(String[] args) {\n" + - " print 'success'\n" + - " }\n" + - " BigInteger getAmount() { return 0 }\n" + - "}\n", - }, - "success"); - } - - @Test - public void testImportsBigInteger3() { - runConformTest(new String[] { - "p/Big.groovy", - "package p\n" + - "class Big {\n" + - " static void main(String[] args) {\n" + - " print 'success'\n" + - " }\n" + - " private static final BigInteger FIXED_AMOUNT = BigInteger.TEN\n" + - "}\n", - }, - "success"); - } - @Test public void testMultipleTypesInOneFile01() { runConformTest(new String[] { @@ -4472,392 +3854,8 @@ public void testConfigScriptWithError() { options); } - @Test - public void testExtraImports1() { - Map options = getCompilerOptions(); - // use the pre-2.1 verbose syntax for one test case to ensure it works as a fallback - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "import org.codehaus.groovy.control.customizers.ImportCustomizer\n" + - "def ic = new ImportCustomizer()\n" + - "ic.addStarImports 'com.foo'\n" + - "configuration.addCompilationCustomizers(ic)\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports2() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " star 'com.foo'\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports3() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports4() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " normal 'com.foo.Type2'\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " Type2.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - - "com/foo/Type2.groovy", - "package com.foo\n" + - "class Type2 {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports_extensionFilter1() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " source(extension: 'groovy') {\n" + - " imports {\n" + - " star 'com.foo'\n" + - " }\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports_extensionFilter2() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " source(extension: 'groovy') {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " }\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports_extensionFilter3() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " source(extension: 'groovy') {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " normal 'com.foo.TypeB'\n" + - " }\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " TypeB.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + "class Type {\n" + - " public static void m() {}\n" + - "}\n", - - "com/foo/TypeB.groovy", - "package com.foo\n" + - "class TypeB {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test - public void testExtraImports_nonMatchingSuffix() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " source(extension: 'gradle') {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " }\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runNegativeTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "----------\n" + - "1. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + - "\tType.m()\n" + - "\t^^^^\n" + - "Groovy:Apparent variable 'Type' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:\n" + - "----------\n", - options); - } - - @Test - public void testExtraImports_typeDoesNotExist() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " normal 'com.foo.Type2'\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runNegativeTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "----------\n" + - "1. ERROR in com\\bar\\Runner.groovy (at line 1)\n" + - "\tpackage com.bar\n" + - "\t^\n" + - "Groovy:unable to resolve class com.foo.Type2\n" + - "----------\n" + - "2. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + - "\tType.m()\n" + - "\t^^^^\n" + - "Groovy:Apparent variable \'Type\' was found in a static scope but doesn\'t refer to a local variable, static field or class. Possible causes:\n" + - "----------\n" + - "----------\n" + - "1. ERROR in com\\foo\\Type.groovy (at line 1)\n" + - "\tpackage com.foo\n" + - "\t^\n" + - "Groovy:unable to resolve class com.foo.Type2\n" + - "----------\n", - options); - } - - @Test - public void testExtraImports_packageDoesNotExist() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " star 'com.whatever'\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runNegativeTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "----------\n" + - "1. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + - "\tType.m()\n" + - "\t^^^^\n" + - "Groovy:Apparent variable \'Type\' was found in a static scope but doesn\'t refer to a local variable, static field or class. Possible causes:\n" + - "----------\n", - options); - } - - @Test - public void testExtraImports_mixedAdditions() { - Map options = getCompilerOptions(); - options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", - "withConfig(configuration) {\n" + - " imports {\n" + - " star 'com.whatever'\n" + - " }\n" + - " source(extension: 'groovy') {\n" + - " imports {\n" + - " normal 'com.foo.Type'\n" + - " }\n" + - " }\n" + - "}\n" - ).getAbsolutePath()); - - runConformTest(new String[] { - "com/bar/Runner.groovy", - "package com.bar\n" + - "class Runner {\n" + - " public static void main(args) {\n" + - " Type.m()\n" + // requires extra import - " print 'done'\n" + - " }\n" + - "}\n", - - "com/foo/Type.groovy", - "package com.foo\n" + - "class Type {\n" + - " public static void m() {}\n" + - "}\n", - }, - "done", options); - } - - @Test // Variable arguments - public void testInvokingVarargs01_JtoG() { + @Test // Variable arguments + public void testInvokingVarargs01_JtoG() { runConformTest(new String[] { "p/Run.java", "package p;\n"+ @@ -5059,7 +4057,7 @@ public void testInvokingVarargsCtors01_GtoJ() { } @Test - public void testPositions() { + public void testPositions1() { runNegativeTest(new String[] { "One.groovy", "class One {\n" + @@ -5081,7 +4079,7 @@ public void testPositions() { } @Test - public void testPositions_2() { + public void testPositions2() { runNegativeTest(new String[] { "One.groovy", "class One {\n" + @@ -5180,465 +4178,6 @@ public void testSecondaryTypeTagging() { assertTrue((tds[3].bits&ASTNode.IsSecondaryType)!=0); } - @Test // static imports - public void testStaticImports_JtoG() { - runConformTest(new String[] { - "p/Run.java", - "package p;\n"+ - "import static p.q.r.Colour.*;\n"+ - "public class Run {\n" + - " public static void main(String[] argv) {\n"+ - " System.out.print(Red);\n"+ - " System.out.print(Green);\n"+ - " System.out.print(Blue);\n"+ - " }\n"+ - "}\n", - - "p/q/r/Colour.groovy", - "package p.q.r;\n" + - "enum Colour { Red,Green,Blue; }\n", - },"RedGreenBlue"); - } - - @Test - public void testStaticImports_GtoJ() { - runConformTest(new String[] { - "p/Run.groovy", - "package p;\n"+ - "import static p.q.r.Colour.*;\n"+ - "public class Run {\n" + - " public static void main(String[] argv) {\n"+ - " System.out.print(Red);\n"+ - " System.out.print(Green);\n"+ - " System.out.print(Blue);\n"+ - " }\n"+ - "}\n", - - "p/q/r/Colour.java", - "package p.q.r;\n" + - "enum Colour { Red,Green,Blue; }\n", - },"RedGreenBlue"); - } - - @Test - public void testStaticImports2_GtoJ() { - runConformTest(new String[] { - "p/Run.java", - "package p;\n"+ - "import static p.q.r.Colour.*;\n"+ - "public class Run {\n" + - " public static void main(String[] argv) {\n"+ - " Red.printme();\n"+ - " }\n"+ - "}\n", - - "p/q/r/Colour.groovy", - "package p.q.r;\n" + - "enum Colour { Red,Green,Blue; \n" + - " void printme() {\n"+ - " println \"${name()}\";\n" + - " }\n"+ - "}\n", - },"Red"); - } - - @Test - public void testStaticImportsAliasing_G() { - runConformTest(new String[] { - "p/Run.groovy", - "package p\n" + - "import static java.lang.Math.PI as pi\n" + - "import static java.lang.Math.sin as sine\n" + - "import static java.lang.Math.cos as cosine\n" + - "\n"+ - "print sine(pi / 6) + cosine(pi / 3)\n", - }, "1.0"); - } - - @Test // 'import static a.B.FOO' - public void testImportStatic1() { - runConformTest(new String[] { - "b/Run.groovy", - "package b\n" + - "import static a.B.FOO\n" + - "class Run { public static void main(String[]argv) { print FOO;} }\n", - - "a/B.groovy", - "package a\n" + - "class B { public static String FOO='abc';}\n", - }, "abc"); - - ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; - assertTrue(ref.isStatic()); - assertEquals("a.B.FOO", ref.toString()); - assertFalse(ref instanceof AliasImportReference); - assertEquals("FOO", String.valueOf(ref.getSimpleName())); - } - - @Test // 'import static a.B.*' - public void testImportStatic2() { - runConformTest(new String[] { - "b/Run.groovy", - "package b\n" + - "import static a.B.*\n" + - "class Run { public static void main(String[]argv) { print FOO;} }\n", - - "a/B.groovy", - "package a\n" + - "class B { public static String FOO='abc';}\n", - }, "abc"); - - ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; - assertTrue(ref.isStatic()); - assertEquals("a.B.*", ref.toString()); - } - - @Test // 'import static a.B.FOO as Wibble' - public void testImportStatic3() { - runConformTest(new String[] { - "b/Run.groovy", - "package b\n" + - "import static a.B.FOO as Wibble\n" + - "class Run { public static void main(String[]argv) { print Wibble;} }\n", - - "a/B.groovy", - "package a\n" + - "class B { public static String FOO='abc';}\n", - }, "abc"); - - ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; - assertTrue(ref.isStatic()); - assertTrue(ref instanceof AliasImportReference); - assertEquals("a.B.FOO as Wibble", ref.toString()); - assertEquals("Wibble", String.valueOf(ref.getSimpleName())); - } - - @Test - public void testImportStatic4() { - runConformTest(new String[] { - "a/B.groovy", - "package a\n" + - "interface B {\n" + - " String C = 'nls'\n" + - "}", - - "x/Y.groovy", - "package x\n" + - "import static a.B.C\n" + - "class Y {\n" + - " @SuppressWarnings(C) def one() {}\n" + - " @SuppressWarnings(C) def two() {}\n" + - "}", - }); - } - - @Test - public void testParsingBlankPackage() { - runNegativeTest(new String[] { - "Foo.groovy", - "package \n"+ - "class Name { }\n", - }, - "----------\n" + - "1. ERROR in Foo.groovy (at line 1)\n" + - "\tpackage \n" + - "\t^\n" + - "Groovy:Invalid package specification @ line 1, column 0.\n" + - "----------\n"); - } - - @Test - public void testParsingBlankPackage2() { - runNegativeTest(new String[] { - "Foo.groovy", - "package ;\n"+ - "class Name { }\n", - }, - "----------\n" + - "1. ERROR in Foo.groovy (at line 1)\n" + - "\tpackage ;\n" + - "\t^\n" + - "Groovy:Invalid package specification @ line 1, column 0.\n" + - "----------\n"); - } - - @Test // does the second error now get reported after the package problem - public void testParsingBlankPackage3() { - runNegativeTest(new String[] { - "Foo.groovy", - "package ;\n"+ - "class Name { \n" + - " asdf\n"+ - "}\n", - }, - "----------\n" + - "1. ERROR in Foo.groovy (at line 1)\n" + - "\tpackage ;\n" + - "\t^\n" + - "Groovy:Invalid package specification @ line 1, column 0.\n" + - "----------\n" + - "2. ERROR in Foo.groovy (at line 3)\n" + - "\tasdf\n" + - "\t^\n" + - "Groovy:unexpected token: asdf @ line 3, column 3.\n" + - "----------\n"); - } - - @Test - public void testParsingBlankImport_538() { - runNegativeTest(new String[] { - "A.groovy", - "import " - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport \n" + - "\t^^^^^^^\n" + - "Groovy:unable to resolve class ?\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals(0, recoveredImport.getStart()); - assertEquals(7, recoveredImport.getEnd()); - assertEquals("?", recoveredImport.getType().getName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertTrue(cn.getName().equals("A")); - } - - @Test - public void testParsingBlankImport2_538() { - runNegativeTest(new String[] { - "A.groovy", - "import ;" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport ;\n" + - "\t^^^^^^^\n" + - "Groovy:unable to resolve class ?\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals(0, recoveredImport.getStart()); - assertEquals(7, recoveredImport.getEnd()); - assertEquals("?", recoveredImport.getType().getName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertTrue(cn.getName().equals("A")); - } - - @Test - public void testParsingDotTerminatedImport_538() { - runNegativeTest(new String[] { - "A.groovy", - "import foo." - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport foo.\n" + - "\t ^\n" + - "Groovy:Invalid import @ line 1, column 8.\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getStarImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals("foo.", recoveredImport.getPackageName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertTrue(cn.getName().equals("A")); - } - - @Test - public void testParsingBlankImportStatic_538() { - runNegativeTest(new String[] { - "A.groovy", - "import static \n" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport static \n" + - "\t^^^^^^^^^^^^^^\n" + - "Groovy:unable to resolve class ?\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals(0, recoveredImport.getStart()); - assertEquals(14, recoveredImport.getEnd()); - assertEquals("?", recoveredImport.getType().getName()); - assertTrue(mn.getStaticImports().isEmpty()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertTrue(cn.getName().equals("A")); - } - - @Test - public void testParsingBlankImportStatic2_538() { - runNegativeTest(new String[] { - "A.groovy", - "import static ;\n" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport static ;\n" + - "\t^^^^^^^^^^^^^^\n" + - "Groovy:unable to resolve class ?\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals(0, recoveredImport.getStart()); - assertEquals(14, recoveredImport.getEnd()); - assertEquals("?", recoveredImport.getType().getName()); - assertTrue(mn.getStaticImports().isEmpty()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertTrue(cn.getName().equals("A")); - } - - @Test - public void testParsingDotTerminatedImportStatic_538() { - runNegativeTest(new String[] { - "A.groovy", - "import static foo.Bar." - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport static foo.Bar.\n" + - "\t ^^^^^^^\n" + - "Groovy:unable to resolve class foo.Bar\n" + - "----------\n" + - "2. ERROR in A.groovy (at line 1)\n" + - "\timport static foo.Bar.\n" + - "\t ^\n" + - "Groovy:Invalid import @ line 1, column 15.\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - Map imports = mn.getStaticStarImports(); - ImportNode recoveredImport = imports.get("foo.Bar"); - assertEquals("foo.Bar", recoveredImport.getType().getName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertEquals("A", cn.getName()); - } - - @Test - public void testParsingDotTerminatedImportFollowedByClassDeclaration_538() { - runNegativeTest(new String[] { - "A.groovy", - "import foo.\n"+ - "\n"+ - "class Wibble {}\n" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport foo.\n" + - "\t ^\n" + - "Groovy:Invalid import @ line 1, column 8.\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getStarImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals("foo.", recoveredImport.getPackageName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertEquals("Wibble", cn.getName()); - } - - @Test - public void testParsingDotTerminatedImportFollowedByModifierAndClassDeclaration_538() { - runNegativeTest(new String[] { - "A.groovy", - "import foo.\n"+ - "\n"+ - "public class Wibble {}\n" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport foo.\n" + - "\t ^\n" + - "Groovy:Invalid import @ line 1, column 8.\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getStarImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals("foo.", recoveredImport.getPackageName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertEquals("Wibble", cn.getName()); - } - - @Test - public void testParsingBlankImportFollowedByClassDeclaration_538() { - runNegativeTest(new String[] { - "A.groovy", - "import\n"+ - "\n"+ - "public class Wibble {}\n" - }, - "----------\n" + - "1. ERROR in A.groovy (at line 1)\n" + - "\timport\n" + - "\t^^^^^^\n" + - "Groovy:unable to resolve class ?\n" + - "----------\n"); - - ModuleNode mn = getModuleNode("A.groovy"); - assertNotNull(mn); - assertFalse(mn.encounteredUnrecoverableError()); - - List imports = mn.getImports(); - ImportNode recoveredImport = imports.get(0); - assertEquals("?", recoveredImport.getType().getName()); - - ClassNode cn = mn.getClasses().get(0); - assertNotNull(cn); - assertEquals("Wibble", cn.getName()); - } - @Test public void testParsingIncompleteClassDeclaration_495() { runNegativeTest(new String[] { diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/ImportsTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/ImportsTests.java new file mode 100644 index 0000000000..a289621f0c --- /dev/null +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/ImportsTests.java @@ -0,0 +1,1528 @@ +/* + * Copyright 2009-2018 the original author or authors. + * + * Licensed 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 org.eclipse.jdt.groovy.core.tests.basic; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Map; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.ImportNode; +import org.codehaus.groovy.ast.ModuleNode; +import org.codehaus.jdt.groovy.internal.compiler.ast.AliasImportReference; +import org.eclipse.jdt.internal.compiler.ast.ImportReference; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.junit.Test; + +public final class ImportsTests extends GroovyCompilerTestSuite { + + @Test + public void testImports() { + runConformTest(new String[] { + "p/First.groovy", + "package p\n" + + "import java.util.regex.Pattern\n" + + "class First {\n" + + " static void main(String[] argv) {\n" + + " Pattern p = Pattern.compile('.')\n" + + " print 'success'\n" + + " }\n" + + " Pattern getPattern() {}\n" + + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsJavaIO() { + runConformTest(new String[] { + "p/First.groovy", + "package p\n" + + "import java.util.regex.Pattern\n" + + "class First {\n" + + " static void main(String[] argv) {\n" + + " print 'success'\n" + + " }\n" + + " File getFile() {}\n" + // java.io.File should be picked up magically + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsBigDecimal1() { + runConformTest(new String[] { + "p/Main.java", + "package p;\n" + + "public class Main {\n" + + " public static void main(String[] args) {\n" + + " System.out.print(new Big().getAmount().toString());\n" + // https://github.com/groovy/groovy-eclipse/issues/268 + " }\n" + + "}\n", + + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " BigDecimal amount = 3.14\n" + + "}\n", + }, + "3.14"); + } + + @Test + public void testDefaultImportsBigDecimal2() { + runConformTest(new String[] { + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " static void main(String[] args) {\n" + + " print 'success'\n" + + " }\n" + + " BigDecimal getAmount() { return 0 }\n" + + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsBigDecimal3() { + // this version has an import; that can make a difference... + runConformTest(new String[] { + "p/Big.groovy", + "package p\n" + + "import java.util.regex.Pattern\n" + + "class Big {\n" + + " static void main(String[] args) {\n" + + " print 'success'\n" + + " }\n" + + " BigDecimal getAmount() { return 0 }\n" + + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsBigDecimal4() { + runConformTest(new String[] { + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " static void main(String[] args) {\n" + + " print 'success'\n" + + " }\n" + + " private static final BigDecimal FIXED_AMOUNT = BigDecimal.TEN\n" + + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsBigInteger1() { + runConformTest(new String[] { + "p/Main.java", + "package p;\n" + + "public class Main {\n" + + " public static void main(String[] args) {\n" + + " System.out.print(new Big().getAmount().toString());\n" + + " }\n" + + "}\n", + + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " BigInteger amount = 10\n" + + "}\n", + }, + "10"); + } + + @Test + public void testDefaultImportsBigInteger2() { + runConformTest(new String[] { + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " static void main(String[] args) {\n" + + " print 'success'\n" + + " }\n" + + " BigInteger getAmount() { return 0 }\n" + + "}\n", + }, + "success"); + } + + @Test + public void testDefaultImportsBigInteger3() { + runConformTest(new String[] { + "p/Big.groovy", + "package p\n" + + "class Big {\n" + + " static void main(String[] args) {\n" + + " print 'success'\n" + + " }\n" + + " private static final BigInteger FIXED_AMOUNT = BigInteger.TEN\n" + + "}\n", + }, + "success"); + } + + @Test + public void testStarImports1() { + runConformTest(new String[] { + "Script.groovy", + "import foo.*\n" + + "println new Pojo().class.name\n", + + "foo/Pojo.java", + "package foo;\n" + + "public class Pojo {}\n", + }, + "foo.Pojo"); + } + + @Test + public void testStarImports2() { + runConformTest(new String[] { + "Script.groovy", + "import foo.bar.*\n" + + "println new Pojo().class.name\n", + + "foo/bar/Pojo.java", + "package foo.bar;\n" + + "public class Pojo {}\n", + }, + "foo.bar.Pojo"); + } + + @Test + public void testStarImports3() { + runConformTest(new String[] { + "Wibble.groovy", + "import a.b.c.*\n" + + "class Wibble {\n" + + " Process process = new Process()\n" + + " static void main(String[] argv) {\n" + + " print new Wibble().process.class\n" + + " }\n" + + "}\n", + + "a/b/c/Process.java", + "package a.b.c;\n" + + "public class Process {}\n", + }, + "class a.b.c.Process"); + } + + @Test // 'import static a.B.FOO' + public void testStaticImport1() { + runConformTest(new String[] { + "b/Run.groovy", + "package b\n" + + "import static a.B.FOO\n" + + "class Run { public static void main(String[]argv) { print FOO;} }\n", + + "a/B.groovy", + "package a\n" + + "class B { public static String FOO='abc';}\n", + }, + "abc"); + + ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; + assertTrue(ref.isStatic()); + assertEquals("a.B.FOO", ref.toString()); + assertFalse(ref instanceof AliasImportReference); + assertEquals("FOO", String.valueOf(ref.getSimpleName())); + } + + @Test // 'import static a.B.*' + public void testStaticImport2() { + runConformTest(new String[] { + "b/Run.groovy", + "package b\n" + + "import static a.B.*\n" + + "class Run { public static void main(String[]argv) { print FOO;} }\n", + + "a/B.groovy", + "package a\n" + + "class B { public static String FOO='abc';}\n", + }, + "abc"); + + ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; + assertTrue(ref.isStatic()); + assertEquals("a.B.*", ref.toString()); + } + + @Test // 'import static a.B.FOO as Wibble' + public void testStaticImport3() { + runConformTest(new String[] { + "b/Run.groovy", + "package b\n" + + "import static a.B.FOO as Wibble\n" + + "class Run { public static void main(String[]argv) { print Wibble;} }\n", + + "a/B.groovy", + "package a\n" + + "class B { public static String FOO='abc';}\n", + }, + "abc"); + + ImportReference ref = getCUDeclFor("Run.groovy").imports[0]; + assertTrue(ref.isStatic()); + assertTrue(ref instanceof AliasImportReference); + assertEquals("a.B.FOO as Wibble", ref.toString()); + assertEquals("Wibble", String.valueOf(ref.getSimpleName())); + } + + @Test + public void testStaticImport4() { + runConformTest(new String[] { + "a/B.groovy", + "package a\n" + + "interface B {\n" + + " String C = 'nls'\n" + + "}", + + "x/Y.groovy", + "package x\n" + + "import static a.B.C\n" + + "class Y {\n" + + " @SuppressWarnings(C) def one() {}\n" + + " @SuppressWarnings(C) def two() {}\n" + + "}", + }); + } + + @Test + public void testStaticImports_JtoG() { + runConformTest(new String[] { + "p/Run.java", + "package p;\n" + + "import static p.q.r.Colour.*;\n" + + "public class Run {\n" + + " public static void main(String[] argv) {\n" + + " System.out.print(Red);\n" + + " System.out.print(Green);\n" + + " System.out.print(Blue);\n" + + " }\n" + + "}\n", + + "p/q/r/Colour.groovy", + "package p.q.r;\n" + + "enum Colour { Red,Green,Blue; }\n", + }, + "RedGreenBlue"); + } + + @Test + public void testStaticImports_GtoJ() { + runConformTest(new String[] { + "p/Run.groovy", + "package p;\n" + + "import static p.q.r.Colour.*;\n" + + "public class Run {\n" + + " public static void main(String[] argv) {\n" + + " System.out.print(Red);\n" + + " System.out.print(Green);\n" + + " System.out.print(Blue);\n" + + " }\n" + + "}\n", + + "p/q/r/Colour.java", + "package p.q.r;\n" + + "enum Colour { Red,Green,Blue; }\n", + }, + "RedGreenBlue"); + } + + @Test + public void testStaticImports2_GtoJ() { + runConformTest(new String[] { + "p/Run.java", + "package p;\n" + + "import static p.q.r.Colour.*;\n" + + "public class Run {\n" + + " public static void main(String[] argv) {\n" + + " Red.printme();\n" + + " }\n" + + "}\n", + + "p/q/r/Colour.groovy", + "package p.q.r;\n" + + "enum Colour { Red,Green,Blue; \n" + + " void printme() {\n" + + " println \"${name()}\";\n" + + " }\n" + + "}\n", + }, + "Red"); + } + + @Test + public void testImportAliasing() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import q.A as AA;\n" + + "import r.A as AB;\n" + + "public class C {\n" + + " public static void main(String[] argv) {\n" + + " callitOne(new AA());\n" + + " callitTwo(new AB());\n" + + " }\n" + + " public static void callitOne(AA a) { a.run();}\n" + + " public static void callitTwo(AB a) { a.run();}\n" + + "}\n", + + "q/A.java", + "package q;\n" + + "public class A {\n" + + " public static void run() { System.out.print(\"q.A.run \");}\n" + + "}\n", + + "r/A.java", + "package r;\n" + + "public class A {\n" + + " public static void run() { System.out.print(\"r.A.run\");}\n" + + "}\n", + }, + "q.A.run r.A.run"); + } + + // Test that the alias is recognized when referenced as superclass + // WMTW: the code Scope.getShortNameFor() + @Test + public void testImportAliasingGoober() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import java.util.HashMap as Goober;\n" + + "public class C extends Goober {\n" + + " public static void main(String[] argv) {\n" + + " print 'q.A.run'\n" + + " }\n" + + "}\n", + }, + "q.A.run"); + } + + @Test + public void testImportAliasingStatic() { + runConformTest(new String[] { + "p/Run.groovy", + "package p\n" + + "import static java.lang.Math.PI as pi\n" + + "import static java.lang.Math.sin as sine\n" + + "import static java.lang.Math.cos as cosine\n" + + "\n" + + "print sine(pi / 6) + cosine(pi / 3)\n", + }, + "1.0"); + } + + @Test + public void testImportAliasingAndOldReference() { + runNegativeTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import q.A as AA;\n" + + "import r.A as AB;\n" + + "public class C {\n" + + " public static void main(String[] argv) {\n" + + " callitOne(new AA());\n" + + " }\n" + + " public static void callitOne(A a) { }\n" + // no A imported! + "}\n", + + "q/A.java", + "package q;\n" + + "public class A {\n" + + " public static void run() { System.out.print(\"q.A.run \");}\n" + + "}\n", + + "r/A.java", + "package r;\n" + + "public class A {\n" + + " public static void run() { System.out.print(\"r.A.run\");}\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in p\\C.groovy (at line 8)\n" + + "\tpublic static void callitOne(A a) { }\n" + + "\t ^\n" + + "Groovy:unable to resolve class A\n" + + "----------\n"); + } + + @Test + public void testAliasing_GRE473() { + runConformTest(new String[] { + "Foo.groovy", + "import java.util.regex.Pattern as JavaPattern\n" + + "class Pattern {JavaPattern javaPattern}\n" + + "def p = new Pattern(javaPattern:~/\\d+/)\n" + + "assert \"123\" ==~ p.javaPattern\n" + + "print 'success '\n" + + "print '['+p.class.name+']['+JavaPattern.class.name+']'\n", + }, + "success [Pattern][java.util.regex.Pattern]"); + } + + @Test + public void testAliasing_GRE473_2() { + runNegativeTest(new String[] { + "Foo.groovy", + "import java.util.regex.Pattern\n" + + "class Pattern {Pattern javaPattern}\n" + + "def p = new Pattern(javaPattern:~/\\d+/)\n" + + "assert \"123\" ==~ p.javaPattern\n" + + "print 'success'\n", + }, + "----------\n" + + "1. ERROR in Foo.groovy (at line 1)\n" + + "\timport java.util.regex.Pattern\n" + + "\t ^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The import java.util.regex.Pattern conflicts with a type defined in the same file\n" + + "----------\n"); + } + + @Test + public void testImportInnerInner01() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "public class C {\n" + + " private static Wibble.Inner.Inner2 wibbleInner = new G();\n" + + " public static void main(String[] argv) {\n" + + " wibbleInner.run();\n" + + " }\n" + + "}\n" + + "class G extends Wibble.Inner.Inner2 {}", + + "p/Wibble.java", + "package p;\n" + + "public class Wibble {\n" + + " public static class Inner {\n" + + " public static class Inner2 {\n" + + " public static void run() { System.out.print(\"p.Wibble.Inner.Inner2.run \");}\n" + + " }\n" + + " }\n" + + "}\n", + }, + "p.Wibble.Inner.Inner2.run"); + } + + @Test + public void testImportInnerClass01_JavaCase() { + runConformTest(new String[] { + "p/C.java", + "package p;\n" + + "import x.y.z.Wibble.Inner;\n" + + "\n" + + "public class C {\n" + + " private static Inner wibbleInner = new Inner();\n" + + " public static void main(String[] argv) {\n" + + " wibbleInner.run();\n" + + " }\n" + + "}\n", + + "x/y/z/Wibble.java", + "package x.y.z;\n" + + "public class Wibble {\n" + + " public static class Inner {\n" + + " public static void run() { System.out.print(\"q.A.run \");}\n" + + " }\n" + + "}\n", + }, + "q.A.run"); + } + + // FIXASC need to look at all other kinds of import - statics/double nested static classes/etc + @Test + public void testImportInnerClass01_GroovyCase() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import x.y.z.Wibble.Inner\n" + + "\n" + + "public class C {\n" + + " private static Inner wibbleInner = new Inner();\n" + + " public static void main(String[] argv) {\n" + + " wibbleInner.run();\n" + + " }\n" + + "}\n", + + "x/y/z/Wibble.java", + "package x.y.z;\n" + + "public class Wibble {\n" + + " public static class Inner {\n" + + " public static void run() { System.out.print(\"q.A.run \");}\n" + + " }\n" + + "}\n", + }, + "q.A.run"); + } + + @Test + public void testImportInnerClass() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import x.y.z.Wibble.Inner /*as WibbleInner*/;\n" + + "public class C {\n" + + " private static Inner wibbleInner = new Inner();\n" + + " public static void main(String[] argv) {\n" + + " wibbleInner.run();\n" + + " }\n" + + //" public static void callitOne(WibbleInner a) { a.run();}\n" + + "}\n", + + "x/y/z/Wibble.java", + "package x.y.z;\n" + + "public class Wibble {\n" + + " public static class Inner {\n" + + " public void run() { System.out.print(\"run\");}\n" + + " }\n" + + "}\n", + }, + "run"); + } + + @Test + public void testImportAliasingInnerClass() { + runConformTest(new String[] { + "p/C.groovy", + "package p;\n" + + "import x.y.z.Wibble.Inner as WibbleInner;\n" + + "public class C {\n" + + " private static WibbleInner wibbleInner = new WibbleInner();\n" + + " public static void main(String[] argv) {\n" + + " wibbleInner.run();\n" + + " }\n" + + "}\n", + + "x/y/z/Wibble.java", + "package x.y.z;\n" + + "public class Wibble {\n" + + " public static class Inner {\n" + + " public void run() { System.out.print(\"run \");}\n" + + " }\n" + + "}\n", + }, + "run"); + } + + @Test + public void testExtraImports1() { + Map options = getCompilerOptions(); + // use the pre-2.1 verbose syntax for one test case to ensure it works as a fallback + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "import org.codehaus.groovy.control.customizers.ImportCustomizer\n" + + "def ic = new ImportCustomizer()\n" + + "ic.addStarImports 'com.foo'\n" + + "configuration.addCompilationCustomizers(ic)\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports2() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " star 'com.foo'\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports3() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports4() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " normal 'com.foo.Type2'\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " Type2.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + + "com/foo/Type2.groovy", + "package com.foo\n" + + "class Type2 {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports_extensionFilter1() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " source(extension: 'groovy') {\n" + + " imports {\n" + + " star 'com.foo'\n" + + " }\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports_extensionFilter2() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " source(extension: 'groovy') {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " }\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports_extensionFilter3() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " source(extension: 'groovy') {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " normal 'com.foo.TypeB'\n" + + " }\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " TypeB.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + + "com/foo/TypeB.groovy", + "package com.foo\n" + + "class TypeB {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testExtraImports_nonMatchingSuffix() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " source(extension: 'gradle') {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " }\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runNegativeTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + + "\tType.m()\n" + + "\t^^^^\n" + + "Groovy:Apparent variable 'Type' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:\n" + + "----------\n", + options); + } + + @Test + public void testExtraImports_typeDoesNotExist() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " normal 'com.foo.Type2'\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runNegativeTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in com\\bar\\Runner.groovy (at line 1)\n" + + "\tpackage com.bar\n" + + "\t^\n" + + "Groovy:unable to resolve class com.foo.Type2\n" + + "----------\n" + + "2. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + + "\tType.m()\n" + + "\t^^^^\n" + + "Groovy:Apparent variable \'Type\' was found in a static scope but doesn\'t refer to a local variable, static field or class. Possible causes:\n" + + "----------\n" + + "----------\n" + + "1. ERROR in com\\foo\\Type.groovy (at line 1)\n" + + "\tpackage com.foo\n" + + "\t^\n" + + "Groovy:unable to resolve class com.foo.Type2\n" + + "----------\n", + options); + } + + @Test + public void testExtraImports_packageDoesNotExist() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " star 'com.whatever'\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runNegativeTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in com\\bar\\Runner.groovy (at line 4)\n" + + "\tType.m()\n" + + "\t^^^^\n" + + "Groovy:Apparent variable \'Type\' was found in a static scope but doesn\'t refer to a local variable, static field or class. Possible causes:\n" + + "----------\n", + options); + } + + @Test + public void testExtraImports_mixedAdditions() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTIONG_GroovyCompilerConfigScript, createScript("config.groovy", + "withConfig(configuration) {\n" + + " imports {\n" + + " star 'com.whatever'\n" + + " }\n" + + " source(extension: 'groovy') {\n" + + " imports {\n" + + " normal 'com.foo.Type'\n" + + " }\n" + + " }\n" + + "}\n" + ).getAbsolutePath()); + + runConformTest(new String[] { + "com/bar/Runner.groovy", + "package com.bar\n" + + "class Runner {\n" + + " public static void main(args) {\n" + + " Type.m()\n" + // requires extra import + " print 'done'\n" + + " }\n" + + "}\n", + + "com/foo/Type.groovy", + "package com.foo\n" + + "class Type {\n" + + " public static void m() {}\n" + + "}\n", + }, + "done", options); + } + + @Test + public void testNonTerminalMissingImport() { + runNegativeTest(new String[] { + "p/X.groovy", + "package p;\n" + + "import a.b.c.D;\n"+ + "public class X {\n" + + " public static void main(String[]argv) {\n"+ + " print \"success\"\n"+ + " }\n"+ + "}\n", + }, + "----------\n" + + "1. ERROR in p\\X.groovy (at line 2)\n" + + "\timport a.b.c.D;\n" + + "\t ^^^^^^^\n" + + "Groovy:unable to resolve class a.b.c.D\n" + + "----------\n"); + } + + @Test + public void testAmbiguous_GRE945_gu() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static Factory fact = new Factory()\n" + + " public static void main(String[]argv) {\n" + + " fact.foo()\n" + + " }\n" + + "}\n", + + "Factory.groovy", + "package bug.factory\n" + + "class Factory { static foo() { print 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_jl() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static StringBuffer fact = new StringBuffer()\n" + + " public static void main(String[]argv) {\n" + + " print fact.foo()\n" + + " }\n" + + "}\n", + + "StringBuffer.groovy", + "package bug.factory\n" + + "class StringBuffer { static String foo() { return 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_bothFromSource() { + runConformTest(new String[] { + "Code.groovy", + "import a.*\n" + + "import b.*\n" + + "class Code {\n" + + " static A fact = new A()\n" + + " public static void main(String[]argv) {\n" + + " print fact.foo()\n" + + " }\n" + + "}\n", + + "a/A.groovy", + "package a\n" + + "class A { static String foo() { return 'abc'}}\n", + + "b/A.groovy", + "package b\n" + + "class A { static String foo() { return 'def'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_bothFromSource_2() { + runConformTest(new String[] { + "Code.groovy", + "import b.*\n" + + "import a.*\n" + + "class Code {\n" + + " static A fact = new A()\n" + + " public static void main(String[]argv) {\n" + + " print fact.foo()\n" + + " }\n" + + "}\n", + + "a/A.groovy", + "package a\n" + + "class A { static String foo() { return 'abc'}}\n", + + "b/A.groovy", + "package b\n" + + "class A { static String foo() { return 'def'}}\n", + }, + "def"); + } + + @Test + public void testAmbiguous_GRE945_bothFromSource_3() { + runConformTest(new String[] { + "Code.groovy", + "import b.*\n" + + "import a.*\n" + + "class Code {\n" + + " static Process fact = new Process()\n" + + " public static void main(String[]argv) {\n" + + " print fact.foo()\n" + + " }\n" + + "}\n", + + "a/Process.groovy", + "package a\n" + + "class Process { static String foo() { return 'abc'}}\n", + + "b/Process.groovy", + "package b\n" + + "class Process { static String foo() { return 'def'}}\n", + }, + "def"); + } + + @Test + public void testAmbiguous_GRE945_ju() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static List fact = new List()\n" + + " public static void main(String[]argv) {\n" + + " fact.foo()\n" + + " }\n" + + "}\n", + + "List.groovy", + "package bug.factory\n" + + "class List { static foo() { print 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_jn() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static Socket fact = new Socket()\n" + + " public static void main(String[]argv) {\n" + + " fact.foo()\n" + + " }\n" + + "}\n", + + "Socket.groovy", + "package bug.factory\n" + + "class Socket { static foo() { print 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_gl() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static Tuple fact = new Tuple()\n" + + " public static void main(String[]argv) {\n" + + " fact.foo()\n" + + " }\n" + + "}\n", + + "Tuple.groovy", + "package bug.factory\n" + + "class Tuple { static foo() { print 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testAmbiguous_GRE945_ji() { + runConformTest(new String[] { + "Code.groovy", + "import bug.factory.*\n" + + "class Code {\n" + + " static Serializable fact = new Serializable()\n" + + " public static void main(String[]argv) {\n" + + " fact.foo()\n" + + " }\n" + + "}\n", + + "Serializable.groovy", + "package bug.factory\n" + + "class Serializable { static foo() { print 'abc'}}\n", + }, + "abc"); + } + + @Test + public void testParsingBlankPackage() { + runNegativeTest(new String[] { + "Foo.groovy", + "package \n" + + "class Name { }\n", + }, + "----------\n" + + "1. ERROR in Foo.groovy (at line 1)\n" + + "\tpackage \n" + + "\t^\n" + + "Groovy:Invalid package specification @ line 1, column 0.\n" + + "----------\n"); + } + + @Test + public void testParsingBlankPackage2() { + runNegativeTest(new String[] { + "Foo.groovy", + "package ;\n" + + "class Name { }\n", + }, + "----------\n" + + "1. ERROR in Foo.groovy (at line 1)\n" + + "\tpackage ;\n" + + "\t^\n" + + "Groovy:Invalid package specification @ line 1, column 0.\n" + + "----------\n"); + } + + @Test // does the second error now get reported after the package problem + public void testParsingBlankPackage3() { + runNegativeTest(new String[] { + "Foo.groovy", + "package ;\n" + + "class Name { \n" + + " asdf\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in Foo.groovy (at line 1)\n" + + "\tpackage ;\n" + + "\t^\n" + + "Groovy:Invalid package specification @ line 1, column 0.\n" + + "----------\n" + + "2. ERROR in Foo.groovy (at line 3)\n" + + "\tasdf\n" + + "\t^\n" + + "Groovy:unexpected token: asdf @ line 3, column 3.\n" + + "----------\n"); + } + + @Test + public void testParsingBlankImport_538() { + runNegativeTest(new String[] { + "A.groovy", + "import " + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport \n" + + "\t^^^^^^^\n" + + "Groovy:unable to resolve class ?\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals(0, recoveredImport.getStart()); + assertEquals(7, recoveredImport.getEnd()); + assertEquals("?", recoveredImport.getType().getName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertTrue(cn.getName().equals("A")); + } + + @Test + public void testParsingBlankImport2_538() { + runNegativeTest(new String[] { + "A.groovy", + "import ;" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport ;\n" + + "\t^^^^^^^\n" + + "Groovy:unable to resolve class ?\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals(0, recoveredImport.getStart()); + assertEquals(7, recoveredImport.getEnd()); + assertEquals("?", recoveredImport.getType().getName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertTrue(cn.getName().equals("A")); + } + + @Test + public void testParsingDotTerminatedImport_538() { + runNegativeTest(new String[] { + "A.groovy", + "import foo." + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport foo.\n" + + "\t ^\n" + + "Groovy:Invalid import @ line 1, column 8.\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getStarImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals("foo.", recoveredImport.getPackageName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertTrue(cn.getName().equals("A")); + } + + @Test + public void testParsingBlankImportStatic_538() { + runNegativeTest(new String[] { + "A.groovy", + "import static \n" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport static \n" + + "\t^^^^^^^^^^^^^^\n" + + "Groovy:unable to resolve class ?\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals(0, recoveredImport.getStart()); + assertEquals(14, recoveredImport.getEnd()); + assertEquals("?", recoveredImport.getType().getName()); + assertTrue(mn.getStaticImports().isEmpty()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertTrue(cn.getName().equals("A")); + } + + @Test + public void testParsingBlankImportStatic2_538() { + runNegativeTest(new String[] { + "A.groovy", + "import static ;\n" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport static ;\n" + + "\t^^^^^^^^^^^^^^\n" + + "Groovy:unable to resolve class ?\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals(0, recoveredImport.getStart()); + assertEquals(14, recoveredImport.getEnd()); + assertEquals("?", recoveredImport.getType().getName()); + assertTrue(mn.getStaticImports().isEmpty()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertTrue(cn.getName().equals("A")); + } + + @Test + public void testParsingDotTerminatedImportStatic_538() { + runNegativeTest(new String[] { + "A.groovy", + "import static foo.Bar." + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport static foo.Bar.\n" + + "\t ^^^^^^^\n" + + "Groovy:unable to resolve class foo.Bar\n" + + "----------\n" + + "2. ERROR in A.groovy (at line 1)\n" + + "\timport static foo.Bar.\n" + + "\t ^\n" + + "Groovy:Invalid import @ line 1, column 15.\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + Map imports = mn.getStaticStarImports(); + ImportNode recoveredImport = imports.get("foo.Bar"); + assertEquals("foo.Bar", recoveredImport.getType().getName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertEquals("A", cn.getName()); + } + + @Test + public void testParsingDotTerminatedImportFollowedByClassDeclaration_538() { + runNegativeTest(new String[] { + "A.groovy", + "import foo.\n" + + "\n" + + "class Wibble {}\n" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport foo.\n" + + "\t ^\n" + + "Groovy:Invalid import @ line 1, column 8.\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getStarImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals("foo.", recoveredImport.getPackageName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertEquals("Wibble", cn.getName()); + } + + @Test + public void testParsingDotTerminatedImportFollowedByModifierAndClassDeclaration_538() { + runNegativeTest(new String[] { + "A.groovy", + "import foo.\n" + + "\n" + + "public class Wibble {}\n" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport foo.\n" + + "\t ^\n" + + "Groovy:Invalid import @ line 1, column 8.\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getStarImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals("foo.", recoveredImport.getPackageName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertEquals("Wibble", cn.getName()); + } + + @Test + public void testParsingBlankImportFollowedByClassDeclaration_538() { + runNegativeTest(new String[] { + "A.groovy", + "import\n" + + "\n" + + "public class Wibble {}\n" + }, + "----------\n" + + "1. ERROR in A.groovy (at line 1)\n" + + "\timport\n" + + "\t^^^^^^\n" + + "Groovy:unable to resolve class ?\n" + + "----------\n"); + + ModuleNode mn = getModuleNode("A.groovy"); + assertNotNull(mn); + assertFalse(mn.encounteredUnrecoverableError()); + + List imports = mn.getImports(); + ImportNode recoveredImport = imports.get(0); + assertEquals("?", recoveredImport.getType().getName()); + + ClassNode cn = mn.getClasses().get(0); + assertNotNull(cn); + assertEquals("Wibble", cn.getName()); + } +} diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/ResolveVisitor.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/ResolveVisitor.java index fce01ff2e5..8219aba3cb 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/ResolveVisitor.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/ResolveVisitor.java @@ -106,7 +106,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { private final Set resolutionFailedCache = new HashSet(); // GRECLIPSE end private boolean checkingVariableTypeInDeclaration = false; - private ImportNode currImportNode = null; + // GRECLIPSE private->protected + protected ImportNode currImportNode; private MethodNode currentMethod; private ClassNodeResolver classNodeResolver; @@ -1439,6 +1440,7 @@ public void visitClass(ClassNode node) { */ for (ImportNode importNode : module.getStarImports()) { if (importNode.getEnd() > 0) { + currImportNode = importNode; String importName = importNode.getPackageName(); importName = importName.substring(0, importName.length()-1); ClassNode type = ClassHelper.makeWithoutCaching(importName); @@ -1447,6 +1449,7 @@ public void visitClass(ClassNode node) { type.setStart(importNode.getStart() + 7); type.setEnd(type.getStart() + importName.length()); } + currImportNode = null; } } // GRECLIPSE end diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/ResolveVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/ResolveVisitor.java index 502dc6ab54..37d6a1d217 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/ResolveVisitor.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/ResolveVisitor.java @@ -111,7 +111,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { private final Set resolutionFailedCache = new HashSet(); // GRECLIPSE end private boolean checkingVariableTypeInDeclaration = false; - private ImportNode currImportNode = null; + // GRECLIPSE private->protected + protected ImportNode currImportNode; private MethodNode currentMethod; private ClassNodeResolver classNodeResolver; @@ -1505,6 +1506,7 @@ public void visitClass(ClassNode node) { */ for (ImportNode importNode : module.getStarImports()) { if (importNode.getEnd() > 0) { + currImportNode = importNode; String importName = importNode.getPackageName(); importName = importName.substring(0, importName.length()-1); ClassNode type = ClassHelper.makeWithoutCaching(importName); @@ -1513,6 +1515,7 @@ public void visitClass(ClassNode node) { type.setStart(importNode.getStart() + 7); type.setEnd(type.getStart() + importName.length()); } + currImportNode = null; } } // GRECLIPSE end diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java index 977642288c..68f26d018c 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java +++ b/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/ResolveVisitor.java @@ -111,7 +111,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { private final Set resolutionFailedCache = new HashSet(); // GRECLIPSE end private boolean checkingVariableTypeInDeclaration = false; - private ImportNode currImportNode = null; + // GRECLIPSE private->protected + protected ImportNode currImportNode; private MethodNode currentMethod; private ClassNodeResolver classNodeResolver; @@ -1504,6 +1505,7 @@ public void visitClass(ClassNode node) { */ for (ImportNode importNode : module.getStarImports()) { if (importNode.getEnd() > 0) { + currImportNode = importNode; String importName = importNode.getPackageName(); importName = importName.substring(0, importName.length()-1); ClassNode type = ClassHelper.makeWithoutCaching(importName); @@ -1512,6 +1514,7 @@ public void visitClass(ClassNode node) { type.setStart(importNode.getStart() + 7); type.setEnd(type.getStart() + importName.length()); } + currImportNode = null; } } // GRECLIPSE end diff --git a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/GroovyCompilationUnitScope.java b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/GroovyCompilationUnitScope.java index ccda212e12..772d9117f2 100644 --- a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/GroovyCompilationUnitScope.java +++ b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/GroovyCompilationUnitScope.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; -import org.codehaus.groovy.ast.ClassNode; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.groovy.core.util.ArrayUtils; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; @@ -27,7 +26,6 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; -import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; @@ -41,8 +39,6 @@ import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; -import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; -import org.eclipse.jdt.internal.core.builder.AbortIncrementalBuildException; import org.eclipse.jdt.internal.core.builder.NameEnvironment; /** @@ -147,55 +143,6 @@ public void augmentTypeHierarchy() { } } - public ClassNode lookupClassNodeForBinary(String typeName, JDTResolver jdtResolver) { - char[][] compoundName = CharOperation.splitOn('.', typeName.toCharArray()); - TypeBinding jdtBinding = getType(compoundName, compoundName.length); - - if (jdtBinding instanceof ProblemReferenceBinding) { - ProblemReferenceBinding prBinding = (ProblemReferenceBinding) jdtBinding; - if (prBinding.problemId() == ProblemReasons.InternalNameProvided) { - jdtBinding = prBinding.closestMatch(); - } - } - - if (jdtBinding instanceof BinaryTypeBinding) { - return jdtResolver.convertToClassNode(jdtBinding); - } - - return null; - } - - /* - * Not quite the right name for this method, because on an incremental build - * it will find BinaryTypeBindings for types that were SourceTypeBindings - * during the full build. - */ - public ClassNode lookupClassNodeForSource(String typeName, JDTResolver jdtResolver) { - char[][] compoundName = CharOperation.splitOn('.', typeName.toCharArray()); - TypeBinding jdtBinding = null; - try { - jdtBinding = getType(compoundName, compoundName.length); - } catch (AbortCompilation t) { - if (!(t.silentException instanceof AbortIncrementalBuildException)) { - throw t; - } - } - - if (jdtBinding instanceof ProblemReferenceBinding) { - ProblemReferenceBinding prBinding = (ProblemReferenceBinding) jdtBinding; - if (prBinding.problemId() == ProblemReasons.InternalNameProvided) { - jdtBinding = prBinding.closestMatch(); - } - } - - if ((jdtBinding instanceof SourceTypeBinding || jdtBinding instanceof BinaryTypeBinding) && - (CharOperation.equals(compoundName, ((ReferenceBinding) jdtBinding).compoundName) || typeName.equals(jdtBinding.debugName()))) { - return jdtResolver.convertToClassNode(jdtBinding); - } - - return null; - } - @Override protected void checkPublicTypeNameMatchesFilename(TypeDeclaration typeDecl) { } diff --git a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/JDTResolver.java b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/JDTResolver.java index 3732e42098..a2af894601 100644 --- a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/JDTResolver.java +++ b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/JDTResolver.java @@ -25,8 +25,6 @@ import java.util.Map; import java.util.Set; -import groovy.lang.GroovyClassLoader; - import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.control.CompilationFailedException; @@ -39,8 +37,16 @@ import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; +import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; +import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.core.builder.AbortIncrementalBuildException; /** * An extension to the standard groovy ResolveVisitor that can ask JDT for types when groovy cannot find them. A groovy project in @@ -329,21 +335,7 @@ protected boolean resolveFromCompileUnit(ClassNode type) { if (DEBUG) { log("resolveFromCompileUnit", type, foundit); } - if (foundit) { - return true; - } - if (activeScope != null) { - // Ask JDT for a source file, visible from this scope - ClassNode node = activeScope.lookupClassNodeForSource(type.getName(), this); - if (DEBUG) { - log("resolveFromCompileUnit (jdt) ", type, node != null); - } - if (node != null) { - type.setRedirect(node); - return true; - } - } - return false; + return foundit; } @Override @@ -368,9 +360,34 @@ protected boolean resolveFromStaticInnerClasses(ClassNode type, boolean testStat @Override protected boolean resolveToOuter(ClassNode type) { - ClassNode node; if (activeScope != null) { - node = activeScope.lookupClassNodeForBinary(type.getName(), this); + // ask the JDT for a binary or source type, visible from this scope + /*node = activeScope.lookupClassNodeForBinary(type.getName(), this);*/ + char[][] compoundName = CharOperation.splitOn('.', type.getName().toCharArray()); + TypeBinding jdtBinding = null; + try { + jdtBinding = activeScope.getType(compoundName, compoundName.length); // TODO: Use getImport(char[][], boolean, boolean) in some cases? + } catch (AbortCompilation t) { + if (!(t.silentException instanceof AbortIncrementalBuildException)) { + throw t; + } + } + if (jdtBinding instanceof ProblemReferenceBinding) { + ProblemReferenceBinding prBinding = (ProblemReferenceBinding) jdtBinding; + if (prBinding.problemId() == ProblemReasons.InternalNameProvided) { + jdtBinding = prBinding.closestMatch(); + } else if (prBinding.problemId() == ProblemReasons.NotFound && + prBinding.closestMatch() instanceof MissingTypeBinding && currImportNode != null && currImportNode.isStar()) { + MissingTypeBinding mtBinding = (MissingTypeBinding) prBinding.closestMatch(); + mtBinding.fPackage.knownTypes.put(compoundName[compoundName.length - 1], null); + } + } + + ClassNode node = null; + if ((jdtBinding instanceof BinaryTypeBinding || jdtBinding instanceof SourceTypeBinding) && + (CharOperation.equals(compoundName, ((ReferenceBinding) jdtBinding).compoundName) || type.getName().equals(jdtBinding.debugName()))) { + node = convertToClassNode(jdtBinding); + } if (DEBUG) { log("resolveToOuter (jdt)", type, node != null); } @@ -379,23 +396,17 @@ protected boolean resolveToOuter(ClassNode type) { return true; } } + // Rudimentary grab support - if the compilation unit has our special classloader and as grab has occurred, try and find the class through it - GroovyClassLoader loader = compilationUnit.getClassLoader(); - if (loader instanceof GrapeAwareGroovyClassLoader) { - GrapeAwareGroovyClassLoader gagcl = (GrapeAwareGroovyClassLoader) loader; - if (gagcl.grabbed) { - Class cls; + if (compilationUnit.getClassLoader() instanceof GrapeAwareGroovyClassLoader) { + GrapeAwareGroovyClassLoader loader = (GrapeAwareGroovyClassLoader) compilationUnit.getClassLoader(); + if (loader.grabbed) { try { - cls = loader.loadClass(type.getName(), false, true); - } catch (ClassNotFoundException | CompilationFailedException e) { - return false; - } - if (cls == null) { - return false; + Class cls = loader.loadClass(type.getName(), false, true); + type.setRedirect(ClassHelper.make(cls)); + return true; + } catch (ClassNotFoundException | CompilationFailedException ignore) { } - node = ClassHelper.make(cls); - type.setRedirect(node); - return true; } } return false; diff --git a/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/GroovyJDTTests.groovy b/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/GroovyJDTTests.groovy index 5c6372e134..80b5efd61c 100644 --- a/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/GroovyJDTTests.groovy +++ b/ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/GroovyJDTTests.groovy @@ -28,6 +28,7 @@ import org.junit.runners.Suite org.eclipse.jdt.groovy.core.tests.basic.GenericsTests, org.eclipse.jdt.groovy.core.tests.basic.GroovySimpleTests, org.eclipse.jdt.groovy.core.tests.basic.GroovySimpleTests_Compliance_1_8, + org.eclipse.jdt.groovy.core.tests.basic.ImportsTests, org.eclipse.jdt.groovy.core.tests.basic.TraitsTests, // Xform tests