Skip to content

Commit

Permalink
Fix for #771: check JDT model for classes in CompilationUnit.ClassWriter
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Dec 10, 2018
1 parent fe2f0b3 commit 62e8018
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -461,20 +549,20 @@ public void testCompileStatic_1506() throws Exception {
"@CompileStatic\n" +
"void method(String message) {\n" +
" Collection<Integer> cs;\n" +
// " List<Integer> ls = new ArrayList<Integer>();\n" +
// " ls.add(123);\n" +
// " ls.add('abc');\n" +
// " List<Integer> ls = new ArrayList<Integer>();\n" +
// " ls.add(123);\n" +
// " ls.add('abc');\n" +
// GRECLIPSE-1511 code
" List<String> second = []\n" +
" List<String> artefactResources2\n" +
" second.addAll(artefactResources2)\n" +
" List<String> second = []\n" +
" List<String> artefactResources2\n" +
" second.addAll(artefactResources2)\n" +
"}\n" +
"interface ListOfFile extends ArrayList<File> {\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)
Expand All @@ -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<File> C = new ArrayList<File>();
// List<File> C = new ArrayList<File>();
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);
Expand Down Expand Up @@ -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<String, String> data = [:]\n" +
" Map<String, Set<String>> 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<File> pluginDependencies\n" +
" for (zip in pluginDependencies) {\n" +
" registerPluginZipWithScope(zip);\n" +
"class Foo {\n" +
" private populateSourceDirectories() {\n" +
" List<File> pluginDependencies\n" +
" foo(pluginDependencies);\n" +
" }\n" +
"}\n" +
"private void registerPluginZipWithScope(File pluginzip) {}\n" +
" private void foo(Iterable<File> iterable) {}\n" +
"}\n");

incrementalBuild(paths[0]);
Expand All @@ -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<File> pluginDependencies\n" +
" foo(pluginDependencies);\n" +
"@CompileStatic\n" +
"private populateSourceDirectories() {\n" +
" List<File> pluginDependencies\n" +
" for (zip in pluginDependencies) {\n" +
" registerPluginZipWithScope(zip);\n" +
" }\n" +
" private void foo(Iterable<File> iterable) {}\n" +
"}\n" +
"private void registerPluginZipWithScope(File pluginzip) {}\n" +
"}\n");

incrementalBuild(paths[0]);
Expand Down Expand Up @@ -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<String, String> data = [:]\n" +
" Map<String, Set<String>> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -921,7 +925,6 @@ protected String getCommonSuperClass(String arg1, String arg2) {
ClassNode b = getClassNode(arg2.replace('/', '.'));
return getCommonSuperClassNode(a,b).getName().replace('.','/');
}

};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 62e8018

Please sign in to comment.