Skip to content

Commit

Permalink
Fix for #1132: infer indirect access for outer class reference
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jun 30, 2020
1 parent 0b1ffde commit c5018f0
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;

import org.codehaus.groovy.ast.MethodNode;
import org.junit.Ignore;
import org.junit.Test;

/**
Expand Down Expand Up @@ -769,6 +770,182 @@ public void testGetterAndField16a() {
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1132
public void testGetterAndField17() {
String contents =
//@formatter:off
"import groovy.transform.PackageScope\n" +
"class Foo {\n" +
" def a\n" +
" private b\n" +
" public c\n" +
" protected d\n" +
" @PackageScope e\n" +
" def getA() { 'A' }\n" +
" def getB() { 'B' }\n" +
" def getC() { 'C' }\n" +
" def getD() { 'D' }\n" +
" def getE() { 'E' }\n" +
" class Bar {\n" +
" void meth() {\n" +
" a\n" +
" b\n" +
" c\n" +
" d\n" +
" e\n" +
" this.a\n" +
" this.b\n" +
" this.c\n" +
" this.d\n" +
" this.e\n" +
" }\n" +
" }\n" +
"}\n";
//@formatter:on

int offset = contents.indexOf("a", contents.indexOf("meth"));
assertDeclaration(contents, offset, offset + 1, "Foo", "getA", DeclarationKind.METHOD);

offset = contents.indexOf("b", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getB", DeclarationKind.METHOD);

offset = contents.indexOf("c", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getC", DeclarationKind.METHOD);

offset = contents.indexOf("d", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getD", DeclarationKind.METHOD);

offset = contents.indexOf("e", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);

offset = contents.lastIndexOf("a");
assertDeclaration(contents, offset, offset + 1, "Foo", "getA", DeclarationKind.METHOD);

offset = contents.lastIndexOf("b");
assertDeclaration(contents, offset, offset + 1, "Foo", "getB", DeclarationKind.METHOD);

offset = contents.lastIndexOf("c");
assertDeclaration(contents, offset, offset + 1, "Foo", "getC", DeclarationKind.METHOD);

offset = contents.lastIndexOf("d");
assertDeclaration(contents, offset, offset + 1, "Foo", "getD", DeclarationKind.METHOD);

offset = contents.lastIndexOf("e");
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);
}

@Test @Ignore
public void testGetterAndField17b() {
String contents =
//@formatter:off
"import groovy.transform.PackageScope\n" +
"class Foo {\n" +
" class Bar {}\n" +
" def a\n" +
" private b\n" +
" public c\n" +
" protected d\n" +
" @PackageScope e\n" +
" def getA() { 'A' }\n" +
" def getB() { 'B' }\n" +
" def getC() { 'C' }\n" +
" def getD() { 'D' }\n" +
" def getE() { 'E' }\n" +
"}\n" +
"class Baz extends Foo.Bar {\n" +
" Baz() { super(new Foo()) }\n" + // seems odd, but does work
" void meth() {\n" +
" a\n" +
" b\n" +
" c\n" +
" d\n" +
" e\n" +
" this.a\n" +
" this.b\n" +
" this.c\n" +
" this.d\n" +
" this.e\n" +
" }\n" +
"}\n";
//@formatter:on

int offset = contents.indexOf("a", contents.indexOf("meth"));
assertDeclaration(contents, offset, offset + 1, "Foo", "getA", DeclarationKind.METHOD);

offset = contents.indexOf("b", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getB", DeclarationKind.METHOD);

offset = contents.indexOf("c", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getC", DeclarationKind.METHOD);

offset = contents.indexOf("d", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getD", DeclarationKind.METHOD);

offset = contents.indexOf("e", offset);
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);

offset = contents.lastIndexOf("a");
assertDeclaration(contents, offset, offset + 1, "Foo", "getA", DeclarationKind.METHOD);

offset = contents.lastIndexOf("b");
assertDeclaration(contents, offset, offset + 1, "Foo", "getB", DeclarationKind.METHOD);

offset = contents.lastIndexOf("c");
assertDeclaration(contents, offset, offset + 1, "Foo", "getC", DeclarationKind.METHOD);

offset = contents.lastIndexOf("d");
assertDeclaration(contents, offset, offset + 1, "Foo", "getD", DeclarationKind.METHOD);

offset = contents.lastIndexOf("e");
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);
}

@Test
public void testGetterAndField17c() {
String contents =
//@formatter:off
"import groovy.transform.PackageScope\n" +
"class Foo {\n" +
" class Bar {}\n" +
" def a\n" +
" private b\n" +
" public c\n" +
" protected d\n" +
" @PackageScope e\n" +
" def getA() { 'A' }\n" +
" def getB() { 'B' }\n" +
" def getC() { 'C' }\n" +
" def getD() { 'D' }\n" +
" def getE() { 'E' }\n" +
"}\n" +
"class Baz extends Foo.Bar {\n" +
" Baz() { super(new Foo()) }\n" + // seems odd, but does work
" void meth() {\n" +
" super.a\n" +
" super.b\n" +
" super.c\n" +
" super.d\n" +
" super.e\n" +
" }\n" +
"}\n";
//@formatter:on

int offset = contents.lastIndexOf("a");
assertDeclaration(contents, offset, offset + 1, "Foo", "getA", DeclarationKind.METHOD);

offset = contents.lastIndexOf("b");
assertDeclaration(contents, offset, offset + 1, "Foo", "getB", DeclarationKind.METHOD);

offset = contents.lastIndexOf("c");
assertDeclaration(contents, offset, offset + 1, "Foo", "getC", DeclarationKind.METHOD);

offset = contents.lastIndexOf("d");
assertDeclaration(contents, offset, offset + 1, "Foo", "getD", DeclarationKind.METHOD);

offset = contents.lastIndexOf("e");
assertDeclaration(contents, offset, offset + 1, "Foo", "getE", DeclarationKind.METHOD);
}

@Test
public void testSetterAndField1() {
String contents =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,6 @@ protected TypeLookupResult findTypeForVariable(final VariableExpression var, fin
if (decl instanceof MethodNode || !((Variable) decl).isDynamicTyped()) variableInfo = null;
}
} else if (accessedVar instanceof DynamicVariable) {
resolvedDeclaringType = getMorePreciseType(resolvedDeclaringType, variableInfo);
ASTNode candidate = findDeclarationForDynamicVariable(var, resolvedDeclaringType, scope, isAssignTarget, resolveStrategy);
if (candidate != null && (!(candidate instanceof MethodNode) || scope.isMethodCall() ||
((AccessorSupport.isGetter((MethodNode) candidate) || AccessorSupport.isSetter((MethodNode) candidate)) && !var.getName().equals(((MethodNode) candidate).getName())))) {
Expand Down Expand Up @@ -671,7 +670,7 @@ protected ASTNode findDeclaration(final String name, final ClassNode declaringTy
if (getBaseDeclaringType(declaringType).getOuterClass() != null) {
// search only for static declarations if inner class is static
boolean isStatic = (isStaticExpression || Flags.isStatic(declaringType.getModifiers()));
ASTNode declaration = findDeclaration(name, getBaseDeclaringType(declaringType).getOuterClass(), isLhsExpression, isStatic, directFieldAccess, methodCallArgumentTypes);
ASTNode declaration = findDeclaration(name, getBaseDeclaringType(declaringType).getOuterClass(), isLhsExpression, isStatic, 0, methodCallArgumentTypes);
if (declaration != null) {
return declaration;
}
Expand Down

0 comments on commit c5018f0

Please sign in to comment.