Skip to content

Commit

Permalink
Merge branch 'master' into issue1806
Browse files Browse the repository at this point in the history
  • Loading branch information
matozoid authored Sep 2, 2018
2 parents 5804a1c + 5235045 commit fd013ad
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ public static ClassOrInterfaceDeclaration demandClass(CompilationUnit cu, String
return cd;
}

public static ClassOrInterfaceDeclaration demandInterface(CompilationUnit cu, String qualifiedName) {
ClassOrInterfaceDeclaration cd = demandClassOrInterface(cu, qualifiedName);
if (!cd.isInterface()) {
throw new IllegalStateException("Type is not an interface");
}
return cd;
}

public static EnumDeclaration demandEnum(CompilationUnit cu, String qualifiedName) {
Optional<TypeDeclaration<?>> res = findType(cu, qualifiedName);
if (!res.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
Expand Down Expand Up @@ -114,7 +116,10 @@ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String na

@Override
public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {

if (wrappedNode.getTypes() != null) {
// Look for types in this compilation unit. For instance, if the given name is "A", there may be a class or
// interface in this compilation unit called "A".
for (TypeDeclaration<?> type : wrappedNode.getTypes()) {
if (type.getName().getId().equals(name)) {
if (type instanceof ClassOrInterfaceDeclaration) {
Expand All @@ -128,6 +133,28 @@ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolve
}
}
}
// Look for member classes/interfaces of types in this compilation unit. For instance, if the given name is
// "A.B", there may be a class or interface in this compilation unit called "A" which has another member
// class or interface called "B". Since the type that we're looking for can be nested arbitrarily deeply
// ("A.B.C.D"), we look for the outermost type ("A" in the previous example) first, then recursively invoke
// this method for the remaining part of the given name.
if (name.indexOf('.') > -1) {
SymbolReference<ResolvedTypeDeclaration> ref = null;
SymbolReference<ResolvedTypeDeclaration> outerMostRef =
solveType(name.substring(0, name.indexOf(".")), typeSolver);
if (outerMostRef != null && outerMostRef.isSolved() &&
outerMostRef.getCorrespondingDeclaration() instanceof JavaParserClassDeclaration) {
ref = ((JavaParserClassDeclaration) outerMostRef.getCorrespondingDeclaration())
.solveType(name.substring(name.indexOf(".") + 1), typeSolver);
} else if (outerMostRef != null && outerMostRef.isSolved() &&
outerMostRef.getCorrespondingDeclaration() instanceof JavaParserInterfaceDeclaration) {
ref = ((JavaParserInterfaceDeclaration) outerMostRef.getCorrespondingDeclaration())
.solveType(name.substring(name.indexOf(".") + 1), typeSolver);
}
if (ref != null && ref.isSolved()) {
return ref;
}
}
}

// Look in current package
Expand Down Expand Up @@ -168,7 +195,7 @@ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolve
}
if (found) {
SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
if (ref.isSolved()) {
if (ref != null && ref.isSolved()) {
return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
}
}
Expand All @@ -179,7 +206,7 @@ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolve
if (importDecl.isAsterisk()) {
String qName = importDecl.getNameAsString() + "." + name;
SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
if (ref.isSolved()) {
if (ref != null && ref.isSolved()) {
return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
}
}
Expand All @@ -188,7 +215,7 @@ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolve

// Look in the java.lang package
SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType("java.lang." + name);
if (ref.isSolved()) {
if (ref != null && ref.isSolved()) {
return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public List<ResolvedConstructorDeclaration> getConstructors() {

private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterfaceType) {
SymbolReference<? extends ResolvedTypeDeclaration> ref = null;
String typeName = classOrInterfaceType.getNameAsString();
String typeName = classOrInterfaceType.asString();
if (typeName.indexOf('.') > -1) {
ref = typeSolver.tryToSolveType(typeName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,30 @@ public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolve
}
}

// Internal classes
// Member classes & interfaces
for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
String prefix = internalType.getName() + ".";
if (internalType.getName().getId().equals(name)) {
if (internalType instanceof ClassOrInterfaceDeclaration) {
return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
if (((ClassOrInterfaceDeclaration) internalType).isInterface()) {
return SymbolReference.solved(new JavaParserInterfaceDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
} else {
return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
}
} else if (internalType instanceof EnumDeclaration) {
return SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver));
} else {
throw new UnsupportedOperationException();
}
} else if (name.startsWith(prefix) && name.length() > prefix.length()) {
if (internalType instanceof ClassOrInterfaceDeclaration) {
return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
if (((ClassOrInterfaceDeclaration) internalType).isInterface()) {
return new JavaParserInterfaceDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
} else {
return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
}
} else if (internalType instanceof EnumDeclaration) {
return new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length()));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,55 @@ public void complexTypeSolving() {

assertEquals(mainClass, resolvedTypeDeclaration.getParentNode().get());
}

@Test
public void resolveMethodCallOfMethodInMemberClassOfAnotherClass() {
CompilationUnit cu = parseSample("NestedClasses");
ClassOrInterfaceDeclaration classA = Navigator.demandClass(cu, "A");

MethodDeclaration method = Navigator.demandMethod(classA, "foo");

MethodCallExpr callExpr = method.getBody().get().getStatement(1)
.asExpressionStmt().getExpression().asMethodCallExpr();

SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver())
.solve(callExpr);

assertTrue(reference.isSolved());
assertEquals("X.Y.bar()", reference.getCorrespondingDeclaration().getQualifiedSignature());
}

@Test
public void resolveMethodCallOfMethodInMemberInterfaceOfAnotherInterface() {
CompilationUnit cu = parseSample("NestedInterfaces");
ClassOrInterfaceDeclaration classA = Navigator.demandInterface(cu, "A");

MethodDeclaration method = Navigator.demandMethod(classA, "foo");

MethodCallExpr callExpr = method.getBody().get().getStatement(1)
.asExpressionStmt().getExpression().asMethodCallExpr();

SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver())
.solve(callExpr);

assertTrue(reference.isSolved());
assertEquals("X.Y.bar()", reference.getCorrespondingDeclaration().getQualifiedSignature());
}

@Test
public void resolveMethodCallOfMethodInMemberInterfaceWithIdenticalNameOfAnotherInterface() {
CompilationUnit cu = parseSample("NestedInterfacesWithIdenticalNames");
ClassOrInterfaceDeclaration classA = Navigator.demandInterface(cu, "A");

MethodDeclaration method = Navigator.demandMethod(classA, "foo");

MethodCallExpr callExpr = method.getBody().get().getStatement(1)
.asExpressionStmt().getExpression().asMethodCallExpr();

SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver())
.solve(callExpr);

assertTrue(reference.isSolved());
assertEquals("X.A.bar()", reference.getCorrespondingDeclaration().getQualifiedSignature());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class A extends X.Y {

void foo() {
X.Y xy = null;
xy.bar();
}
}

class X {
static class Y {
void bar() {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
interface A extends X.Y {

default void foo() {
X.Y xy = null;
xy.bar();
}
}

interface X {
interface Y {
void bar();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
interface A extends X.A {

default void foo() {
X.A xa = null;
xa.bar();
}
}

interface X {
interface A {
void bar();
}
}

0 comments on commit fd013ad

Please sign in to comment.