Skip to content

Commit

Permalink
Implemented removing duplicate method entries in MethodResolutionLogi…
Browse files Browse the repository at this point in the history
…c when trying to find the most applicable method. This fixes issue #60.
  • Loading branch information
mlangkabel committed Sep 27, 2016
1 parent 30ae58b commit dfbc101
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
Expand Up @@ -2,6 +2,8 @@

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.EnumDeclaration;

import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFactory;
import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
Expand Down Expand Up @@ -39,7 +41,14 @@ public String toString() {
@Override
public TypeDeclaration declaringType() {
if (wrappedNode.getParentNode() instanceof ClassOrInterfaceDeclaration) {
return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) wrappedNode.getParentNode(), typeSolver);
ClassOrInterfaceDeclaration parent = (ClassOrInterfaceDeclaration) wrappedNode.getParentNode();
if (parent.isInterface()) {
return new JavaParserInterfaceDeclaration(parent, typeSolver);
} else {
return new JavaParserClassDeclaration(parent, typeSolver);
}
} else if (wrappedNode.getParentNode() instanceof EnumDeclaration) {
return new JavaParserEnumDeclaration((EnumDeclaration) wrappedNode.getParentNode(), typeSolver);
} else {
throw new UnsupportedOperationException();
}
Expand Down
Expand Up @@ -7,6 +7,7 @@
import me.tomassetti.symbolsolver.model.typesystem.PrimitiveTypeUsage;
import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
import me.tomassetti.symbolsolver.model.typesystem.VoidTypeUsage;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;

public class JavassistFactory {
Expand All @@ -16,7 +17,11 @@ public static TypeUsage typeUsageFor(CtClass ctClazz, TypeSolver typeSolver) {
if (ctClazz.isArray()) {
return new ArrayTypeUsage(typeUsageFor(ctClazz.getComponentType(), typeSolver));
} else if (ctClazz.isPrimitive()) {
return PrimitiveTypeUsage.byName(ctClazz.getName());
if (ctClazz.getName().equals("void")) {
return VoidTypeUsage.INSTANCE;
} else {
return PrimitiveTypeUsage.byName(ctClazz.getName());
}
} else {
if (ctClazz.isInterface()) {
return new ReferenceTypeUsageImpl(new JavassistInterfaceDeclaration(ctClazz, typeSolver), typeSolver);
Expand Down
@@ -1,5 +1,6 @@
package me.tomassetti.symbolsolver.resolution;

import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
import me.tomassetti.symbolsolver.model.declarations.MethodAmbiguityException;
import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
Expand Down Expand Up @@ -219,6 +220,23 @@ public static boolean isApplicable(MethodUsage method, String name, List<TypeUsa
return true;
}

private static List<MethodDeclaration> getMethodsWithoutDuplicates(List<MethodDeclaration> methods) {
Set<MethodDeclaration> s = new TreeSet<MethodDeclaration>(new Comparator<MethodDeclaration>() {
@Override
public int compare(MethodDeclaration m1, MethodDeclaration m2) {
if (m1 instanceof JavaParserMethodDeclaration && m2 instanceof JavaParserMethodDeclaration &&
((JavaParserMethodDeclaration)m1).getWrappedNode().equals(((JavaParserMethodDeclaration)m2).getWrappedNode())) {
return 0;
}
return 1;
}
});
s.addAll(methods);
List<MethodDeclaration> res = new ArrayList<>();
res.addAll(s);
return res;
}

/**
* @param methods we expect the methods to be ordered such that inherited methods are later in the list
* @param name
Expand All @@ -227,7 +245,7 @@ public static boolean isApplicable(MethodUsage method, String name, List<TypeUsa
* @return
*/
public static SymbolReference<MethodDeclaration> findMostApplicable(List<MethodDeclaration> methods, String name, List<TypeUsage> paramTypes, TypeSolver typeSolver) {
List<MethodDeclaration> applicableMethods = methods.stream().filter((m) -> isApplicable(m, name, paramTypes, typeSolver)).collect(Collectors.toList());
List<MethodDeclaration> applicableMethods = getMethodsWithoutDuplicates(methods).stream().filter((m) -> isApplicable(m, name, paramTypes, typeSolver)).collect(Collectors.toList());
if (applicableMethods.isEmpty()) {
return SymbolReference.unsolved(MethodDeclaration.class);
}
Expand Down

0 comments on commit dfbc101

Please sign in to comment.