Skip to content

Commit

Permalink
Fix for #954: infer anon. inner ctor call as extended/implemented type
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Sep 17, 2019
1 parent c73146d commit 3c30e9c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1714,49 +1714,57 @@ public void testInnerClass11() {

@Test
public void testAnonInner1() {
String contents = "def foo = new Object() {}";
int start = contents.lastIndexOf("Object");
int end = start + "Object".length();
assertType(contents, start, end, "java.lang.Object");
}

@Test
public void testAnonInner2() {
String contents = "def foo = new Runnable() { void run() {} }";
int start = contents.lastIndexOf("Runnable");
int end = start + "Runnable".length();
assertType(contents, start, end, "java.lang.Runnable");
}

@Test
public void testAnonInner2() {
public void testAnonInner3() {
String contents = "def foo = new Comparable<String>() { int compareTo(String a, String b) {} }";
int start = contents.lastIndexOf("Comparable");
int end = start + "Comparable".length();
assertType(contents, start, end, "java.lang.Comparable<java.lang.String>");
}

@Test
public void testAnonInner3() {
String contents = "def foo = new Comparable<String>() { int compareTo(String a, String b) { compareTo()} }";
public void testAnonInner4() {
String contents = "def foo = new Comparable<String>() { int compareTo(String a, String b) { compareTo() } }";
int start = contents.lastIndexOf("compareTo");
int end = start + "compareTo".length();
assertDeclaringType(contents, start, end, "Search$1");
}

@Test
public void testAnonInner4() {
public void testAnonInner5() {
String contents = "def foo = new Comparable<String>() { int compareTo(String a, String b) {} }\n" +
"foo.compareTo('one', 'two')";
int start = contents.lastIndexOf("compareTo");
int end = start + "compareTo".length();
assertDeclaringType(contents, start, end, "Search$1");
assertDeclaringType(contents, start, end, "java.lang.Comparable<java.lang.String>");
}

@Test
public void testAnonInner5() {
public void testAnonInner6() {
String contents = "def foo = new Comparable<String>() { int compareTo(String a, String b) {} }\n" +
"foo = new Comparable<String>() { int compareTo(String a, String b) {} }\n" +
"foo.compareTo('one', 'two')";
int start = contents.lastIndexOf("compareTo");
int end = start + "compareTo".length();
assertDeclaringType(contents, start, end, "Search$2");
assertDeclaringType(contents, start, end, "java.lang.Comparable<java.lang.String>");
}

@Test // https://github.com/groovy/groovy-eclipse/issues/378
public void testAnonInner6() {
public void testAnonInner7() {
String contents =
"class A {\n" +
" protected def f\n" +
Expand All @@ -1779,7 +1787,7 @@ public void testAnonInner6() {
}

@Test // https://github.com/groovy/groovy-eclipse/issues/383
public void testAnonInner7() {
public void testAnonInner8() {
String contents =
"class A {\n" +
" protected def m() { }\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,8 @@ public TypeLookupResult lookupType(final ClassNode node, final VariableScope sco
if (node.getOuterClass() != null) {
if (!node.isRedirectNode() && GroovyUtils.isAnonymous(node)) {
// return extended/implemented type for anonymous inner class
if (node.getUnresolvedSuperClass() == VariableScope.OBJECT_CLASS_NODE) {
type = node.getInterfaces()[0];
} else {
type = node.getSuperClass();
}
type = node.getUnresolvedSuperClass(false); if (type == VariableScope.OBJECT_CLASS_NODE) type = node.getInterfaces()[0];

} else if (Flags.isSynthetic(node.getModifiers()) && node.getName().endsWith("Helper") && node.getName().contains("$Trait$")) {
// return trait type for trait helper
type = node.getOuterClass();
Expand Down Expand Up @@ -265,7 +262,9 @@ protected TypeLookupResult findType(final Expression node, final ClassNode decla
resolvedDeclaringType = scope.getEnclosingMethodDeclaration().getDeclaringClass();
if (call.isSuperCall()) resolvedDeclaringType = resolvedDeclaringType.getUnresolvedSuperClass(false);
} else if (call.isUsingAnonymousInnerClass()) {
resolvedDeclaringType = resolvedDeclaringType.getUnresolvedSuperClass(false); // nodeType is anon. inner
nodeType = lookupType(call.getType(), scope).type;
// resolve declaring type of the referenced constructor
resolvedDeclaringType = resolvedDeclaringType.getUnresolvedSuperClass(false);
}

// try to find best match if there is more than one constructor to choose from
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,9 @@ public void visitConstructorCallExpression(ConstructorCallExpression node) {
final ClassNode type = node.getType();
if (node.isUsingAnonymousInnerClass()) {
// in "new Type() { ... }", Type is super class or interface
if (type.getSuperClass() != VariableScope.OBJECT_CLASS_NODE) {
visitClassReference(type.getUnresolvedSuperClass(false));
ClassNode superClass = type.getUnresolvedSuperClass(false);
if (superClass != VariableScope.OBJECT_CLASS_NODE) {
visitClassReference(superClass); // incl. Object
} else {
visitClassReference(type.getInterfaces()[0]);
}
Expand Down

0 comments on commit 3c30e9c

Please sign in to comment.