Skip to content

Commit

Permalink
Prep for #395: add anonymous types back to JDT model
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Aug 24, 2018
1 parent 7b37389 commit 45aba9d
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,13 @@ private static void assertDeclaration(IMember decl, BodyDeclaration bd, int memb

// now check the AST
assertEquals(bd + "\nhas incorrect source start value", start, bd.getStartPosition());
int sourceEnd = bd.getStartPosition() + bd.getLength();
// It seems like field declarations should not include the trailing ';' in their source end if one exists
if (bd instanceof FieldDeclaration) sourceEnd -= 1;
assertEquals(bd + "\nhas incorrect source end value", end, sourceEnd);
int bodyEnd = bd.getStartPosition() + bd.getLength();
if (bd instanceof FieldDeclaration) {
bodyEnd -= 1; // fields seem to be including ';' or phantom semicolon
} else if (bd instanceof MethodDeclaration) {
end -= 1; // methods end body inside closing '}' or ';'
}
assertEquals(bd + "\nhas incorrect source end value", end, bodyEnd);

String nameStartTag = "/*" + astKind + memberNumber + "sn*/";
int nameStart = source.indexOf(nameStartTag) + nameStartTag.length();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,24 +689,6 @@ public void testPrimitiveLikeTypeNames_GRE891_3() {
assertEquals("[[Ljava.lang.String;", getReturnTypeOfMethod("Z.groovy", "zzz"));
}

@Test
public void testAnonymousClasses_GE1531() {
runNegativeTest(new String[] {
"Foo.groovy",
"class Foo {\n"+
" def foo () {\n"+
" new java.lang.Runnable() {}\n"+
" }\n"+
"}\n",
},
"----------\n" +
"1. ERROR in Foo.groovy (at line 3)\n" +
"\tnew java.lang.Runnable() {}\n" +
"\t ^^^^^^^^^^^^^^^^^^\n" +
"Groovy:Can\'t have an abstract method in a non-abstract class. The class 'Foo$1' must be declared abstract or the method 'void run()' must be implemented.\n" +
"----------\n");
}

@Test
public void testPrimitiveLikeTypeNames_GRE891_4() {
runConformTest(new String[] {
Expand Down Expand Up @@ -5878,136 +5860,222 @@ public void testParsingIncompleteClassDeclaration_495() {
assertEquals("BBB", cn.getName());
}

@Test @Ignore
public void testSts3930() {
runConformTest(new String[] {
"GroovyDemo.groovy",
"package demo\n"+
"class GroovyDemo {\n" +
" static <T> List someMethod(Class<T> factoryClass, ClassLoader classLoader = GroovyDemo.class.classLoader) {}\n" +
"}",

"JavaDemo.java",
"package demo;\n"+
"public class JavaDemo {\n" +
" public static void someMethod() {\n" +
" GroovyDemo.someMethod(JavaDemo.class);\n" +
" }\n" +
"}\n",
},
"");
}

@Test @Ignore("FIXASC testcase for this. infinite loops (B extends B<String>")
public void testCyclicReference() {
runConformTest(new String[] {
"p/B.groovy",
"package p;\n" +
"class B extends B<String> {\n" +
" public static void main(String[] argv) {\n"+
" new B();\n"+
" print \"success\"\n"+
" }\n"+
"}\n",

"p/A.java",
"package p;\n" +
"public class A<T> {}\n",
},
"");
}

@Test
public void testInnerClass1() {
runConformTest(new String[] {
"A.groovy",
"def foo = new Runnable() {\n" +
" void run() {\n" +
" println \"hi!\";\n" +
" }\n" +
" void run() {\n" +
" println 'hi!'\n" +
" }\n" +
"}\n" +
"foo.run()"
}, "hi!");
"foo.run()\n",
},
"hi!");

checkGCUDeclaration("A.groovy",
"public class A extends groovy.lang.Script {\n" +
" public A() {\n" +
" }\n" +
" public A(groovy.lang.Binding context) {\n" +
" }\n" +
" public static void main(java.lang.String... args) {\n" +
" }\n" +
" public java.lang.Object run() {\n" +
" new Runnable() {\n" +
" public 1() {\n" +
" }\n" +
" public void run() {\n" +
" }\n" +
" };\n" +
" }\n" +
"}");
}

@Test
public void testInnerClass1a() {
runConformTest(new String[] {
"A.groovy",
"class A {" +
" def foo = new Runnable() {\n" +
" void run() {\n" +
" println 'hi!'\n" +
" }\n" +
" }\n" +
" static main(args) {\n" +
" new A().foo.run()\n" +
" }\n" +
"}\n",
},
"hi!");

checkGCUDeclaration("A.groovy",
"public class A {\n" +
" private java.lang.Object foo;\n" +
// " {\n" +
// " new Runnable() {\n" +
// " public 1() {\n" +
// " }\n" +
// " public void run() {\n" +
// " }\n" +
// " };\n" +
// " }\n" +
" public A() {\n" +
" }\n" +
" public static void main(java.lang.String... args) {\n" +
" }\n" +
"}");
}

@Test
public void testInnerClass2() {
runConformTest(new String[] {
"A.groovy",
"def foo = new Runnable() {\n" +
" void run() {\n" +
" println \"bye!\";\n" +
" }\n" +
" void run() {\n" +
" println 'bye!'\n" +
" }\n" +
"}\n" +
"foo = new Runnable() {\n" +
" void run() {\n" +
" println \"hi!\";\n" +
" }\n" +
" void run() {\n" +
" println 'hi!'\n" +
" }\n" +
"}\n" +
"foo.run()"
}, "hi!");
"foo.run()",
},
"hi!");
}

@Test
public void testInnerClass3() {
runConformTest(new String[] {
"A.groovy",
"def foo() {\n" +
" new Runnable() {\n" +
" void run() {\n" +
" println \"hi!\";\n" +
" }\n" +
" }\n" +
" new Runnable() {\n" +
" void run() {\n" +
" println 'hi!'\n" +
" }\n" +
" }\n" +
"}\n" +
"foo().run()"
}, "hi!");
"foo().run()",
},
"hi!");
}

@Test
public void testInnerClass4() {
runConformTest(new String[] {
"A.groovy",
"class Foo {\n" +
" def foo = new Runnable() {\n" +
" void run() {\n" +
" println \"hi!\";\n" +
" }\n" +
" }\n" +
" def foo = new Runnable() {\n" +
" void run() {\n" +
" println 'hi!'\n" +
" }\n" +
" }\n" +
"}\n" +
"new Foo().foo.run()"
}, "hi!");
"new Foo().foo.run()\n",
},
"hi!");
}

@Test
public void testInnerClass5() {
runNegativeTest(new String[] {
"A.groovy",
"def foo = new Runnable() {\n" +
" void bad() {\n" +
" println \"hi!\";\n" +
" }\n" +
"}"
}, "----------\n" +
"1. ERROR in A.groovy (at line 1)\n" +
" def foo = new Runnable() {\n" +
" ^^^^^^^^\n" +
"Groovy:Can't have an abstract method in a non-abstract class. The class 'A$1' must be declared abstract or the method 'void run()' must be implemented.\n" +
"----------\n");
" void bad() {\n" +
" println 'hi!'\n" +
" }\n" +
"}\n",
},
"----------\n" +
"1. ERROR in A.groovy (at line 1)\n" +
"\tdef foo = new Runnable() {\n" +
"\t ^^^^^^^^\n" +
"Groovy:Can't have an abstract method in a non-abstract class. The class 'A$1' must be declared abstract or the method 'void run()' must be implemented.\n" +
"----------\n");
}

@Test
public void testAbstractMethodWithinEnum_STS3803() {
runConformTest(new String[] {
"Bad.groovy",
"enum Bad {\n" +
" A() {\n" +
" @Override\n" +
" int foo() {\n" +
" 1\n" +
" }\n" +
" }\n" +
" abstract int foo()\n" +
"}"});
}

@Test @Ignore
public void testSts3930() {
runConformTest(new String[] {
"GroovyDemo.groovy",
"package demo\n"+
"class GroovyDemo {\n" +
" static <T> List someMethod(Class<T> factoryClass, ClassLoader classLoader = GroovyDemo.class.classLoader) {}\n" +
"}",

"JavaDemo.java",
"package demo;\n"+
"public class JavaDemo {\n" +
" public static void someMethod() {\n" +
" GroovyDemo.someMethod(JavaDemo.class);\n" +
public void testAbstractMethodWithinEnum1() {
runNegativeTest(new String[] {
"Good.groovy",
"enum Good {\n" +
" A() {\n" +
" @Override\n" +
" int foo() {\n" +
" 1\n" +
" }\n" +
"}\n",
" }\n" +
" abstract int foo()\n" +
"}"
},
"");
}

@Test @Ignore("FIXASC testcase for this. infinite loops (B extends B<String>")
public void testInfiniteLoop() {
runConformTest(new String[] {
"p/B.groovy",
"package p;\n" +
"class B extends B<String> {\n" +
" public static void main(String[] argv) {\n"+
" new B();\n"+
" print \"success\"\n"+
" }\n"+
"}\n",
checkGCUDeclaration("Good.groovy",
"public enum Good {\n" +
" A,\n" +
" private Good() {\n" +
" }\n" +
" public abstract int foo();\n" +
"}");
}

"p/A.java",
"package p;\n" +
"public class A<T> {}\n"
@Test
public void testAbstractMethodWithinEnum2() {
runNegativeTest(new String[] {
"Bad.groovy",
"enum Bad {\n" +
" A() {\n" +
" }\n" +
" abstract int foo()\n" +
"}"
},
"");
"----------\n" +
"1. ERROR in Bad.groovy (at line 2)\n" +
"\tA() {\n" +
"\t^\n" +
"Groovy:Can't have an abstract method in enum constant A. Implement method 'int foo()'.\n" +
"----------\n");
}

//--------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,10 @@ protected void enumConstantDef(AST node) {
// a method in which case we need to configure the inner class
innerClass.setSuperClass(classNode.getPlainNodeReference());
innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
// GRECLIPSE add
innerClass.setNameStart(locations.findOffset(savedLine, savedColumn));
innerClass.setNameEnd(innerClass.getNameStart() + identifier.length() - 1);
// GRECLIPSE end
// we use a ClassExpression for transportation to EnumVisitor
Expression inner = new ClassExpression(innerClass);
if (init == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,10 @@ protected void enumConstantDef(AST node) {
// a method in which case we need to configure the inner class
innerClass.setSuperClass(classNode.getPlainNodeReference());
innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
// GRECLIPSE add
innerClass.setNameStart(locations.findOffset(savedLine, savedColumn));
innerClass.setNameEnd(innerClass.getNameStart() + identifier.length() - 1);
// GRECLIPSE end
// we use a ClassExpression for transportation to EnumVisitor
Expression inner = new ClassExpression(innerClass);
if (init == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,8 @@ public FieldNode visitEnumConstant(EnumConstantContext ctx) {
// GRECLIPSE add
ASTNode nameNode = configureAST(new ConstantExpression(enumConstant.getName()), ctx.identifier());
enumConstant.setNameStart(nameNode.getStart()); enumConstant.setNameEnd(nameNode.getEnd() - 1);
anonymousInnerClassNode.setNameStart(enumConstant.getNameStart());
anonymousInnerClassNode.setNameEnd(enumConstant.getNameEnd());
// GRECLIPSE end
return configureAST(enumConstant, ctx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,10 @@ protected void enumConstantDef(AST node) {
// a method in which case we need to configure the inner class
innerClass.setSuperClass(classNode.getPlainNodeReference());
innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
// GRECLIPSE add
innerClass.setNameStart(locations.findOffset(savedLine, savedColumn));
innerClass.setNameEnd(innerClass.getNameStart() + identifier.length() - 1);
// GRECLIPSE end
// we use a ClassExpression for transportation to EnumVisitor
Expression inner = new ClassExpression(innerClass);
if (init == null) {
Expand Down
Loading

0 comments on commit 45aba9d

Please sign in to comment.