diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java index 96dcb45e54..288ab772e4 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/builder/BasicGroovyBuildTests.java @@ -382,6 +382,94 @@ public void testGenericsDefaultParams_1717() throws Exception { expectingNoProblems(); } + @Test + public void testCompileStatic1() throws Exception { + IPath[] paths = createSimpleProject("Project", true); + + env.addGroovyClass(paths[1], "", "Outer", + "import groovy.transform.CompileStatic;\n" + + "@CompileStatic \n" + + "int fact(int n) {\n" + + " if (n==1) {return 1;\n" + + " } else {return n+fact(n-1);}\n" + + "}\n"); + + incrementalBuild(paths[0]); + expectingCompiledClasses("Outer"); + expectingNoProblems(); + } + + @Test // verify generics are correct for the 'Closure' as CompileStatic will attempt an exact match + public void testCompileStatic2() throws Exception { + IPath[] paths = createSimpleProject("Project", true); + + env.addGroovyClass(paths[1], "", "A", + "class A {\n" + + " public void profile(String name, groovy.lang.Closure callable) {}\n" + + "}\n"); + + incrementalBuild(paths[0]); + expectingNoProblems(); + expectingCompiledClasses("A"); + + env.addGroovyClass(paths[1], "", "B", + "@groovy.transform.CompileStatic\n" + + "class B extends A {\n" + + "\n" + + " def foo() {\n" + + " profile(\"creating plugin manager with classes\") {\n" + + " System.out.println('abc');\n" + + " }\n" + + " }\n" + + "\n" + + "}\n"); + + incrementalBuild(paths[0]); + expectingNoProblems(); + expectingCompiledClasses("B", "B$_foo_closure1"); + } + + @Test + public void testCompileStatic3() throws Exception { + IPath[] paths = createSimpleProject("Project", true); + + env.addGroovyClass(paths[1], "", "Foo", + "class Foo {\n" + + " @groovy.transform.CompileStatic\n" + + " public static void main(String[] args) {\n" + + " ((GroovyObject)new Foo());\n" + + " }\n" + + "}\n"); + + incrementalBuild(paths[0]); + expectingNoProblems(); + expectingCompiledClasses("Foo"); + } + + @Test // https://github.com/groovy/groovy-eclipse/issues/771 + public void testCompileStatic771() throws Exception { + IPath[] paths = createSimpleProject("Project", true); + + env.addClass(env.addPackageFragmentRoot(paths[0], "src2", null, "bin2"), "foobar", "DefaultRunnable", + "package foobar;\n" + + "public class DefaultRunnable implements Runnable {\n" + + " @Override public void run() {\n" + + " }\n" + + "}"); + + env.addGroovyClass(paths[1], "foobar", "UtilityClass", + "package foobar\n" + + "@groovy.transform.CompileStatic\n" + + "public final class UtilityClass {\n" + + " public static void doIt(Runnable runner = null) {\n" + + " runner = runner ?: new DefaultRunnable()\n" + // DefaultRunnable is a Java type, so it's not in the CompileUnit + " }\n" + + "}"); + + fullBuild(paths[0]); + expectingNoProblems(); + } + @Test @Ignore public void testCompileStatic_1505() throws Exception { JDTResolver.recordInstances = true; @@ -417,21 +505,21 @@ public void testCompileStatic_1505() throws Exception { assertNotNull(jcn); System.out.println("JDT ClassNode=" +jcn); -// JDTClassNode jcn2 = jdtr.getCachedNode("List2"); -// System.out.println(jcn2); +// JDTClassNode jcn2 = jdtr.getCachedNode("List2"); +// System.out.println(jcn2); ClassNode listcn = new ClassNode(java.util.Collection.class); VMPluginFactory.getPlugin().setAdditionalClassInformation(listcn); listcn.lazyClassInit(); System.out.println("Groovy ClassNode=" +listcn); -// IJavaProject ijp = env.getJavaProject("Project"); -// GroovyCompilationUnit unit = (GroovyCompilationUnit) ijp.findType("Foo") -// .getCompilationUnit(); +// IJavaProject ijp = env.getJavaProject("Project"); +// GroovyCompilationUnit unit = (GroovyCompilationUnit) ijp.findType("Foo") +// .getCompilationUnit(); // now find the class reference -// ClassNode cn = unit.getModuleNode().getClasses().get(1); -// System.out.println(cn); +// ClassNode cn = unit.getModuleNode().getClasses().get(1); +// System.out.println(cn); // Compare java.util.List from JDTClassNode and List2 from groovy compareClassNodes(jcn.redirect(),listcn.redirect(),0); @@ -461,20 +549,20 @@ public void testCompileStatic_1506() throws Exception { "@CompileStatic\n" + "void method(String message) {\n" + " Collection cs;\n" + -// " List ls = new ArrayList();\n" + -// " ls.add(123);\n" + -// " ls.add('abc');\n" + +// " List ls = new ArrayList();\n" + +// " ls.add(123);\n" + +// " ls.add('abc');\n" + // GRECLIPSE-1511 code - " List second = []\n" + - " List artefactResources2\n" + - " second.addAll(artefactResources2)\n" + + " List second = []\n" + + " List artefactResources2\n" + + " second.addAll(artefactResources2)\n" + "}\n" + "interface ListOfFile extends ArrayList {\n" + "}" ); incrementalBuild(paths[0]); -// expectingCompiledClasses("Foo","List2"); +// expectingCompiledClasses("Foo","List2"); expectingNoProblems(); // Now compare the generics structure for List (built by jdtresolver mapping into groovy) against List2 (built by groovy) @@ -485,22 +573,22 @@ public void testCompileStatic_1506() throws Exception { assertNotNull(jcn); System.out.println("JDT ClassNode=" +jcn); -// JDTClassNode jcn2 = jdtr.getCachedNode("List2"); -// System.out.println(jcn2); +// JDTClassNode jcn2 = jdtr.getCachedNode("List2"); +// System.out.println(jcn2); -// List C = new ArrayList(); +// List C = new ArrayList(); ClassNode listcn = new ClassNode(java.util.Collection.class); VMPluginFactory.getPlugin().setAdditionalClassInformation(listcn); listcn.lazyClassInit(); System.out.println("Groovy ClassNode=" +listcn); -// IJavaProject ijp = env.getJavaProject("Project"); -// GroovyCompilationUnit unit = (GroovyCompilationUnit) ijp.findType("Foo") -// .getCompilationUnit(); +// IJavaProject ijp = env.getJavaProject("Project"); +// GroovyCompilationUnit unit = (GroovyCompilationUnit) ijp.findType("Foo") +// .getCompilationUnit(); // now find the class reference -// ClassNode cn = unit.getModuleNode().getClasses().get(1); -// System.out.println(cn); +// ClassNode cn = unit.getModuleNode().getClasses().get(1); +// System.out.println(cn); // Compare java.util.List from JDTClassNode and List2 from groovy compareClassNodes(jcn.redirect(),listcn.redirect(),0); @@ -572,21 +660,41 @@ public void testCompileStatic_FileAddAll() throws Exception { } @Test - public void testCompileStatic_ListFileArgIteratedOver() throws Exception { + public void testCompileStatic_MapEachClosure() throws Exception { + IPath[] paths = createSimpleProject("Project", true); + + env.addGroovyClass(paths[1], "", "Demo", + "@groovy.transform.CompileStatic\n" + + "class Demo {\n" + + " void doit() {\n" + + " def c = {\n" + + " Map data = [:]\n" + + " Map> otherData = [:]\n" + + " data.each { String k, String v ->\n" + + " def foo = otherData.get(k)\n" + + " }\n" + + " }\n" + + " }\n" + + "}"); + + incrementalBuild(paths[0]); + expectingNoProblems(); + } + + @Test + public void testCompileStatic_IterableParameter() throws Exception { JDTResolver.recordInstances = true; IPath[] paths = createSimpleProject("Project", true); env.addGroovyClass(paths[1], "", "Foo", "import groovy.transform.CompileStatic\n" + - "class Foo {\n" + "@CompileStatic\n" + - "private populateSourceDirectories() {\n" + - " List pluginDependencies\n" + - " for (zip in pluginDependencies) {\n" + - " registerPluginZipWithScope(zip);\n" + + "class Foo {\n" + + " private populateSourceDirectories() {\n" + + " List pluginDependencies\n" + + " foo(pluginDependencies);\n" + " }\n" + - "}\n" + - "private void registerPluginZipWithScope(File pluginzip) {}\n" + + " private void foo(Iterable iterable) {}\n" + "}\n"); incrementalBuild(paths[0]); @@ -596,19 +704,21 @@ public void testCompileStatic_ListFileArgIteratedOver() throws Exception { } @Test - public void testCompileStatic_IterableParameter() throws Exception { + public void testCompileStatic_ListFileArgIteratedOver() throws Exception { JDTResolver.recordInstances = true; IPath[] paths = createSimpleProject("Project", true); env.addGroovyClass(paths[1], "", "Foo", "import groovy.transform.CompileStatic\n" + - "@CompileStatic\n" + "class Foo {\n" + - " private populateSourceDirectories() {\n" + - " List pluginDependencies\n" + - " foo(pluginDependencies);\n" + + "@CompileStatic\n" + + "private populateSourceDirectories() {\n" + + " List pluginDependencies\n" + + " for (zip in pluginDependencies) {\n" + + " registerPluginZipWithScope(zip);\n" + " }\n" + - " private void foo(Iterable iterable) {}\n" + + "}\n" + + "private void registerPluginZipWithScope(File pluginzip) {}\n" + "}\n"); incrementalBuild(paths[0]); @@ -643,92 +753,6 @@ public void testCompileStatic_BuildSettings() throws Exception { // TODO: compare the generics structure for List (built by jdtresolver mapping into groovy) against List2 (built by groovy) } - @Test - public void testCompileStatic() throws Exception { - IPath[] paths = createSimpleProject("Project", true); - - env.addGroovyClass(paths[1], "", "Outer", - "import groovy.transform.CompileStatic;\n" + - "@CompileStatic \n" + - "int fact(int n) {\n" + - " if (n==1) {return 1;\n" + - " } else {return n+fact(n-1);}\n" + - "}\n"); - - incrementalBuild(paths[0]); - expectingCompiledClasses("Outer"); - expectingNoProblems(); - } - - @Test // verify generics are correct for the 'Closure' as CompileStatic will attempt an exact match - public void testCompileStatic2() throws Exception { - IPath[] paths = createSimpleProject("Project", true); - - env.addGroovyClass(paths[1], "", "A", - "class A {\n" + - " public void profile(String name, groovy.lang.Closure callable) {}\n" + - "}\n"); - - incrementalBuild(paths[0]); - expectingNoProblems(); - expectingCompiledClasses("A"); - - env.addGroovyClass(paths[1], "", "B", - "@groovy.transform.CompileStatic\n" + - "class B extends A {\n" + - "\n" + - " def foo() {\n" + - " profile(\"creating plugin manager with classes\") {\n" + - " System.out.println('abc');\n" + - " }\n" + - " }\n" + - "\n" + - "}\n"); - - incrementalBuild(paths[0]); - expectingNoProblems(); - expectingCompiledClasses("B", "B$_foo_closure1"); - } - - @Test - public void testCompileStatic3() throws Exception { - IPath[] paths = createSimpleProject("Project", true); - - env.addGroovyClass(paths[1], "", "Foo", - "class Foo {\n" + - " @groovy.transform.CompileStatic\n" + - " public static void main(String[] args) {\n" + - " ((GroovyObject)new Foo());\n" + - " }\n" + - "}\n"); - - incrementalBuild(paths[0]); - expectingNoProblems(); - expectingCompiledClasses("Foo"); - } - - @Test - public void testCompileStatic_MapEachClosure() throws Exception { - IPath[] paths = createSimpleProject("Project", true); - - env.addGroovyClass(paths[1], "", "Demo", - "@groovy.transform.CompileStatic\n" + - "class Demo {\n" + - " void doit() {\n" + - " def c = {\n" + - " Map data = [:]\n" + - " Map> otherData = [:]\n" + - " data.each { String k, String v ->\n" + - " def foo = otherData.get(k)\n" + - " }\n" + - " }\n" + - " }\n" + - "}"); - - incrementalBuild(paths[0]); - expectingNoProblems(); - } - @Test public void test1167() throws Exception { IPath[] paths = createSimpleProject("Project", true); diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/CompilationUnit.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/CompilationUnit.java index 95d0e78279..f113d389e6 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/CompilationUnit.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/control/CompilationUnit.java @@ -894,13 +894,17 @@ private ClassNode getClassNode(String name) { // try inner classes cn = cu.getGeneratedInnerClass(name); if (cn!=null) return cn; + // GRECLIPSE add -- try JDT model + cn = getResolveVisitor().resolve(name); + if (cn!=null) return cn; + // GRECLIPSE end // try class loader classes try { cn = ClassHelper.make( cu.getClassLoader().loadClass(name,false,true), false); } catch (Exception e) { - throw new GroovyBugError(e); + throw new GroovyBugError(/*GRECLIPSE add*/e.toString(),/*GRECLIPSE end*/e); } return cn; } @@ -921,7 +925,6 @@ protected String getCommonSuperClass(String arg1, String arg2) { ClassNode b = getClassNode(arg2.replace('/', '.')); return getCommonSuperClassNode(a,b).getName().replace('.','/'); } - }; } 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 8219aba3cb..057148b217 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 @@ -336,6 +336,12 @@ private void resolveOrFail(ClassNode type, ASTNode node) { resolveOrFail(type, "", node); } + // GRECLIPSE add + public ClassNode resolve(String name) { + return null; + } + // GRECLIPSE end + // GRECLIPSE private->protected protected boolean resolve(ClassNode type) { return resolve(type, true, true, true); diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilationUnit.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilationUnit.java index 2b076754de..b915d5383b 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilationUnit.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilationUnit.java @@ -907,13 +907,17 @@ private ClassNode getClassNode(String name) { // try inner classes cn = cu.getGeneratedInnerClass(name); if (cn!=null) return cn; + // GRECLIPSE add -- try JDT model + cn = getResolveVisitor().resolve(name); + if (cn!=null) return cn; + // GRECLIPSE end // try class loader classes try { cn = ClassHelper.make( cu.getClassLoader().loadClass(name,false,true), false); } catch (Exception e) { - throw new GroovyBugError(e); + throw new GroovyBugError(/*GRECLIPSE add*/e.toString(),/*GRECLIPSE end*/e); } return cn; } @@ -934,7 +938,6 @@ protected String getCommonSuperClass(String arg1, String arg2) { ClassNode b = getClassNode(arg2.replace('/', '.')); return getCommonSuperClassNode(a,b).getName().replace('.','/'); } - }; } 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 2d5a03ea3f..9e564d6380 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 @@ -378,6 +378,12 @@ private void resolveOrFail(ClassNode type, ASTNode node) { resolveOrFail(type, "", node); } + // GRECLIPSE add + public ClassNode resolve(String name) { + return null; + } + // GRECLIPSE end + // GRECLIPSE private->protected protected boolean resolve(ClassNode type) { return resolve(type, true, true, true); diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java index 7187a2d9f3..67d4f9b18f 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java +++ b/base/org.codehaus.groovy26/src/org/codehaus/groovy/control/CompilationUnit.java @@ -899,13 +899,17 @@ private ClassNode getClassNode(String name) { // try inner classes cn = cu.getGeneratedInnerClass(name); if (cn!=null) return cn; + // GRECLIPSE add -- try JDT model + cn = getResolveVisitor().resolve(name); + if (cn!=null) return cn; + // GRECLIPSE end // try class loader classes try { cn = ClassHelper.make( cu.getClassLoader().loadClass(name,false,true), false); } catch (Exception e) { - throw new GroovyBugError(e); + throw new GroovyBugError(/*GRECLIPSE add*/e.toString(),/*GRECLIPSE end*/e); } return cn; } @@ -926,7 +930,6 @@ protected String getCommonSuperClass(String arg1, String arg2) { ClassNode b = getClassNode(arg2.replace('/', '.')); return getCommonSuperClassNode(a,b).getName().replace('.','/'); } - }; } 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 68f26d018c..58063d6bad 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 @@ -375,6 +375,12 @@ private void resolveOrFail(ClassNode type, ASTNode node) { resolveOrFail(type, "", node); } + // GRECLIPSE add + public ClassNode resolve(String name) { + return null; + } + // GRECLIPSE end + // GRECLIPSE private->protected protected boolean resolve(ClassNode type) { return resolve(type, true, true, true); 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 4bf22c8ad3..7e11b0c218 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 @@ -253,6 +253,7 @@ public synchronized void cleanUp() { // TODO: Reset things like currentMethod, currImportNode, etc.? } + @Override public ClassNode resolve(String name) { if (name.charAt(0) == 'j' || name.length() <= BOOLEAN_LENGTH) { ClassNode commonType = COMMON_TYPES.get(name);