Skip to content

Commit

Permalink
introduce cache in JavaParserFacade
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Aug 5, 2015
1 parent c1925c6 commit 627b563
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 30 deletions.
31 changes: 29 additions & 2 deletions src/main/java/me/tomassetti/symbolsolver/JavaParserFacade.java
Expand Up @@ -45,11 +45,19 @@ public class JavaParserFacade {
logger.addHandler(consoleHandler);
}

public JavaParserFacade(TypeSolver typeSolver) {
private JavaParserFacade(TypeSolver typeSolver) {
this.typeSolver = typeSolver;
this.symbolSolver = new SymbolSolver(typeSolver);
}

public static JavaParserFacade get(TypeSolver typeSolver){
if (!instances.containsKey(typeSolver)){
instances.put(typeSolver, new JavaParserFacade(typeSolver));
}
return instances.get(typeSolver);
}


public SymbolReference solve(NameExpr nameExpr) {
return symbolSolver.solveSymbol(nameExpr.getName(), nameExpr);
}
Expand Down Expand Up @@ -90,11 +98,30 @@ public TypeUsage getType(Node node) {
return getType(node, true);
}

private Map<Node, TypeUsage> cacheWithLambadsSolved = new WeakHashMap<>();
private Map<Node, TypeUsage> cacheWithoutLambadsSolved = new WeakHashMap<>();

private static Map<TypeSolver, JavaParserFacade> instances = new HashMap<>();

public TypeUsage getType(Node node, boolean solveLambdas) {
if (solveLambdas){
if (!cacheWithLambadsSolved.containsKey(node)){
cacheWithLambadsSolved.put(node, getTypeConcrete(node, solveLambdas));
}
return cacheWithLambadsSolved.get(node);
} else {
if (!cacheWithoutLambadsSolved.containsKey(node)){
cacheWithoutLambadsSolved.put(node, getTypeConcrete(node, solveLambdas));
}
return cacheWithoutLambadsSolved.get(node);
}
}

/**
* Should return more like a TypeApplication: a TypeDeclaration and possible parameters or array modifiers.
* @return
*/
public TypeUsage getType(Node node, boolean solveLambdas) {
private TypeUsage getTypeConcrete(Node node, boolean solveLambdas) {
if (node == null) throw new IllegalArgumentException();
if (node instanceof NameExpr) {
NameExpr nameExpr = (NameExpr) node;
Expand Down
Expand Up @@ -44,7 +44,7 @@ public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsag
@Override
public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
Expression scope = wrappedNode.getScope();
TypeUsage typeOfScope = new JavaParserFacade(typeSolver).getType(scope);
TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
return typeOfScope.getField(name, typeSolver);
}
}
Expand Up @@ -26,7 +26,7 @@ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
if (wrappedNode.getParentNode() instanceof MethodCallExpr){
MethodCallExpr methodCallExpr = (MethodCallExpr)wrappedNode.getParentNode();
MethodUsage methodUsage = new JavaParserFacade(typeSolver).solveMethodAsUsage(methodCallExpr);
MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
int i = pos(methodCallExpr, wrappedNode);
TypeUsage lambdaType = methodUsage.getParamTypes().get(i);
Value value = new Value(lambdaType.parameters().get(0), name, false);
Expand Down
Expand Up @@ -25,7 +25,7 @@ public MethodCallExprContext(MethodCallExpr wrappedNode) {
@Override
public Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {
if (wrappedNode.getScope() != null) {
TypeUsage typeOfScope = new JavaParserFacade(typeSolver).getType(wrappedNode.getScope());
TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope());
return typeOfScope.solveMethodAsUsage(name, parameterTypes, typeSolver);
} else {
throw new UnsupportedOperationException();
Expand All @@ -51,7 +51,7 @@ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
@Override
public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {
if (wrappedNode.getScope() != null) {
TypeUsage typeOfScope = new JavaParserFacade(typeSolver).getType(wrappedNode.getScope());
TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope());
return typeOfScope.solveMethod(name, parameterTypes, typeSolver);
} else {
throw new UnsupportedOperationException();
Expand Down
Expand Up @@ -34,7 +34,7 @@ public TypeDeclaration asTypeDeclaration() {

@Override
public TypeUsage getTypeUsage(TypeSolver typeSolver) {
return new JavaParserFacade(typeSolver).convertToUsage(fieldDeclaration.getType(), fieldDeclaration);
return JavaParserFacade.get(typeSolver).convertToUsage(fieldDeclaration.getType(), fieldDeclaration);
/*TypeUsage typeUsage = new TypeUsageOfTypeDeclaration(typeDeclaration);
if (!typeUsage.parameters().isEmpty()) {
throw new UnsupportedOperationException(typeUsage.toString()+" "+fieldDeclaration.getType());
Expand Down Expand Up @@ -73,7 +73,7 @@ public TypeUsage getTypeUsage(TypeSolver typeSolver) {

@Override
public TypeDeclaration getType(TypeSolver typeSolver) {
return new JavaParserFacade(typeSolver).convert(fieldDeclaration.getType(), fieldDeclaration);
return JavaParserFacade.get(typeSolver).convert(fieldDeclaration.getType(), fieldDeclaration);
}

@Override
Expand Down
Expand Up @@ -80,11 +80,11 @@ public TypeDeclaration getType(TypeSolver typeSolver) {
Parameter parameter = (Parameter) wrappedNode;
if (wrappedNode.getParentNode() instanceof LambdaExpr) {
int pos = getParamPos(parameter);
TypeUsage lambdaType = new JavaParserFacade(typeSolver).getType(wrappedNode.getParentNode());
TypeUsage lambdaType = JavaParserFacade.get(typeSolver).getType(wrappedNode.getParentNode());

// TODO understand from the context to which method this corresponds
//MethodDeclaration methodDeclaration = new JavaParserFacade(typeSolver).getMethodCalled
//MethodDeclaration methodCalled = new JavaParserFacade(typeSolver).solve()
//MethodDeclaration methodDeclaration = JavaParserFacade.get(typeSolver).getMethodCalled
//MethodDeclaration methodCalled = JavaParserFacade.get(typeSolver).solve()
throw new UnsupportedOperationException(wrappedNode.getClass().getCanonicalName());
} else {
return new SymbolSolver(typeSolver).solveType(parameter.getType());
Expand All @@ -93,10 +93,10 @@ public TypeDeclaration getType(TypeSolver typeSolver) {
VariableDeclarator variableDeclarator = (VariableDeclarator)wrappedNode;
if (wrappedNode.getParentNode() instanceof VariableDeclarationExpr) {
VariableDeclarationExpr variableDeclarationExpr = (VariableDeclarationExpr)variableDeclarator.getParentNode();
return new JavaParserFacade(typeSolver).convert(variableDeclarationExpr.getType(), JavaParserFactory.getContext(wrappedNode));
return JavaParserFacade.get(typeSolver).convert(variableDeclarationExpr.getType(), JavaParserFactory.getContext(wrappedNode));
} else if (wrappedNode.getParentNode() instanceof FieldDeclaration) {
FieldDeclaration fieldDeclaration = (FieldDeclaration)variableDeclarator.getParentNode();
return new JavaParserFacade(typeSolver).convert(fieldDeclaration.getType(), JavaParserFactory.getContext(wrappedNode));
return JavaParserFacade.get(typeSolver).convert(fieldDeclaration.getType(), JavaParserFactory.getContext(wrappedNode));
} else {
throw new UnsupportedOperationException(wrappedNode.getParentNode().getClass().getCanonicalName());
}
Expand Down Expand Up @@ -131,6 +131,6 @@ public static int getParamPos(Node node) {

@Override
public TypeUsage getTypeUsage(TypeSolver typeSolver) {
return new JavaParserFacade(typeSolver).getType(wrappedNode);
return JavaParserFacade.get(typeSolver).getType(wrappedNode);
}
}
Expand Up @@ -4,6 +4,8 @@
import me.tomassetti.symbolsolver.model.TypeSolver;
import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
import me.tomassetti.symbolsolver.model.usages.TypeUsage;
import me.tomassetti.symbolsolver.model.usages.TypeUsageOfTypeDeclaration;

/**
* Created by federico on 02/08/15.
Expand All @@ -16,6 +18,11 @@ public String toString() {
'}';
}

@Override
public TypeUsage getTypeUsage(TypeSolver typeSolver) {
return new TypeUsageOfTypeDeclaration(getType(typeSolver));
}

private CtClass type;

public JavassistParameterDeclaration(CtClass type) {
Expand Down
Expand Up @@ -73,7 +73,7 @@ public Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> par
}
SymbolReference<MethodDeclaration> ref = MethodResolutionLogic.findMostApplicable(methods, name, parameterTypes, typeSolver);
if (ref.isSolved()) {
return Optional.of(new JavaParserFacade(typeSolver).convertToUsage(ref.getCorrespondingDeclaration(), getContext()));
return Optional.of(JavaParserFacade.get(typeSolver).convertToUsage(ref.getCorrespondingDeclaration(), getContext()));
} else {
return Optional.empty();
}
Expand Down
Expand Up @@ -35,9 +35,14 @@ public boolean isPrimitive() {
return false;
}

@Override
public Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {
return Optional.empty();
}

@Override
public Optional<TypeUsage> parameterByName(String name) {
throw new UnsupportedOperationException();
return Optional.empty();
}

@Override
Expand Down
20 changes: 9 additions & 11 deletions src/test/java/me/tomassetti/symbolsolver/model/ContextTest.java
Expand Up @@ -221,7 +221,7 @@ public void resolveReferenceToJreType() throws ParseException, IOException {
Type streamJavaParserType = method.getParameters().get(0).getType();

TypeSolver typeSolver = new JreTypeSolver();
TypeDeclaration streamType = new JavaParserFacade(typeSolver).convert(streamJavaParserType, method);
TypeDeclaration streamType = JavaParserFacade.get(typeSolver).convert(streamJavaParserType, method);

assertEquals("Stream", streamType.getName());
assertEquals("java.util.stream.Stream",streamType.getQualifiedName());
Expand All @@ -235,7 +235,7 @@ public void resolveReferenceToMethodWithLambda() throws ParseException, IOExcept
MethodCallExpr methodCallExpr = Navigator.findMethodCall(method, "filter");

TypeSolver typeSolver = new JreTypeSolver();
TypeUsage ref = new JavaParserFacade(typeSolver).getType(methodCallExpr);
TypeUsage ref = JavaParserFacade.get(typeSolver).getType(methodCallExpr);

assertEquals("java.util.stream.Stream", ref.getTypeName());
assertEquals(1, ref.parameters().size());
Expand All @@ -250,7 +250,7 @@ public void resolveReferenceToLambdaParamBase() throws ParseException, IOExcepti
NameExpr refToT = Navigator.findNameExpression(method, "t");

TypeSolver typeSolver = new JreTypeSolver();
TypeUsage ref = new JavaParserFacade(typeSolver).getType(refToT);
TypeUsage ref = JavaParserFacade.get(typeSolver).getType(refToT);

assertEquals("java.lang.String", ref.getTypeName());
}
Expand All @@ -269,8 +269,8 @@ public void resolveReferenceToLambdaParamSimplified() throws ParseException, IOE
assertEquals("isEmpty", ref.getName());
assertEquals("java.lang.String", ref.declaringType().getQualifiedName());
}

/*@Test
/*
@Test
public void resolveReferenceToLambdaParam() throws ParseException, IOException {
CompilationUnit cu = parseSample("Navigator");
ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
Expand All @@ -279,13 +279,11 @@ public void resolveReferenceToLambdaParam() throws ParseException, IOException {
String pathToJar = "src/test/resources/javaparser-core-2.1.0.jar";
JarTypeSolver typeSolver = new JarTypeSolver(pathToJar);
SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
SymbolReference<me.tomassetti.symbolsolver.model.declarations.MethodDeclaration> ref = symbolSolver.solveMethod("getName", Collections.emptyList(), callToGetName);
MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToGetName);
assertEquals(true, ref.isSolved());
assertEquals("getName", ref.getCorrespondingDeclaration().getName());
assertEquals("com.github.javaparser.ast.body.TypeDeclaration", ref.getCorrespondingDeclaration().getType().getQualifiedName());
}*/
assertEquals("getName", methodUsage.getName());
assertEquals("com.github.javaparser.ast.body.TypeDeclaration", methodUsage.declaringType().getQualifiedName());
}
/*@Test
public void resolveReferenceToOverloadMethodWithNullParam() throws ParseException, IOException {
Expand Down
Expand Up @@ -144,7 +144,7 @@ public void resolveUsageOfGenericFieldSimpleCase() throws ParseException {

ExpressionStmt stmt = (ExpressionStmt)method.getBody().getStmts().get(0);
Expression expression = stmt.getExpression();
TypeUsage typeUsage = new JavaParserFacade(new JreTypeSolver()).getType(expression);
TypeUsage typeUsage = JavaParserFacade.get(new JreTypeSolver()).getType(expression);

assertEquals(false, typeUsage.isTypeVariable());
assertEquals("java.lang.String", typeUsage.getTypeName());
Expand All @@ -158,7 +158,7 @@ public void resolveUsageOfGenericFieldIntermediateCase() throws ParseException {

VariableDeclarator field = Navigator.demandField(clazz, "as");

TypeUsage typeUsage = new JavaParserFacade(new JreTypeSolver()).getType(field);
TypeUsage typeUsage = JavaParserFacade.get(new JreTypeSolver()).getType(field);

assertEquals(false, typeUsage.isTypeVariable());
assertEquals("java.util.List", typeUsage.getTypeName());
Expand All @@ -176,7 +176,7 @@ public void resolveUsageOfGenericFieldAdvancedCase() throws ParseException {

ExpressionStmt stmt = (ExpressionStmt)method.getBody().getStmts().get(0);
Expression expression = stmt.getExpression();
TypeUsage typeUsage = new JavaParserFacade(new JreTypeSolver()).getType(expression);
TypeUsage typeUsage = JavaParserFacade.get(new JreTypeSolver()).getType(expression);

assertEquals(false, typeUsage.isTypeVariable());
assertEquals("java.util.List", typeUsage.getTypeName());
Expand Down

0 comments on commit 627b563

Please sign in to comment.