Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Aug 19, 2015
1 parent a7fa0c3 commit c1e95ef
Show file tree
Hide file tree
Showing 17 changed files with 616 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/main/java/me/tomassetti/symbolsolver/model/Context.java
Expand Up @@ -20,14 +20,14 @@ public interface Context {
/* Type resolution */ /* Type resolution */


default Optional<TypeUsage> solveGenericType(String name, TypeSolver typeSolver) { default Optional<TypeUsage> solveGenericType(String name, TypeSolver typeSolver) {
throw new UnsupportedOperationException(this.getClass().getCanonicalName()); return Optional.empty();
} }


public SymbolReference<TypeDeclaration> solveType(String name, TypeSolver typeSolver); public SymbolReference<TypeDeclaration> solveType(String name, TypeSolver typeSolver);


/* Symbol resolution */ /* Symbol resolution */


public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver); public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver);


default Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) { default Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
throw new UnsupportedOperationException(this.getClass().getCanonicalName()); throw new UnsupportedOperationException(this.getClass().getCanonicalName());
Expand Down
Expand Up @@ -10,6 +10,13 @@ public interface TypeSolver {


public SymbolReference<TypeDeclaration> tryToSolveType(String name); public SymbolReference<TypeDeclaration> tryToSolveType(String name);


public TypeDeclaration solveType(String name) throws UnsolvedSymbolException; public default TypeDeclaration solveType(String name) throws UnsolvedSymbolException {
SymbolReference<TypeDeclaration> ref = tryToSolveType(name);
if (ref.isSolved()) {
return ref.getCorrespondingDeclaration();
} else {
throw new UnsolvedSymbolException(null, name);
}
}


} }
Expand Up @@ -18,7 +18,9 @@
public class JavaParserFactory { public class JavaParserFactory {


public static Context getContext(Node node){ public static Context getContext(Node node){
if (node instanceof CompilationUnit) { if (node == null) {
return null;
} else if (node instanceof CompilationUnit) {
return new CompilationUnitContext((CompilationUnit)node); return new CompilationUnitContext((CompilationUnit)node);
} else if (node instanceof Statement) { } else if (node instanceof Statement) {
return new StatementContext((Statement) node); return new StatementContext((Statement) node);
Expand Down
Expand Up @@ -30,7 +30,7 @@ public ClassOrInterfaceDeclarationContext(ClassOrInterfaceDeclaration wrappedNod
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
if (typeSolver == null) throw new IllegalArgumentException(); if (typeSolver == null) throw new IllegalArgumentException();


// first among declared fields // first among declared fields
Expand Down
Expand Up @@ -29,7 +29,42 @@ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {

// solve absolute references
TODO implement

// Look among statically imported values
if (wrappedNode.getImports() != null) {
for (ImportDeclaration importDecl : wrappedNode.getImports()) {
if (importDecl.isStatic()) {
if (importDecl.isAsterisk()) {
if (importDecl.getName() instanceof QualifiedNameExpr) {
throw new UnsupportedOperationException("A");
} else {
throw new UnsupportedOperationException("B");
}
} else {
if (importDecl.getName() instanceof QualifiedNameExpr) {
String qName = importDecl.getName().toString();
// split in field/method name and type name
int index = qName.lastIndexOf('.');
if (index == -1) {
throw new UnsupportedOperationException();
}
String typeName = qName.substring(0, index);
String memberName = qName.substring(index + 1);

me.tomassetti.symbolsolver.model.declarations.TypeDeclaration importedType = typeSolver.solveType(typeName);
return importedType.solveSymbol(memberName, typeSolver);
} else {
throw new UnsupportedOperationException("C");
}
}
}
}
}

return SymbolReference.unsolved(ValueDeclaration.class); return SymbolReference.unsolved(ValueDeclaration.class);
} }


Expand Down Expand Up @@ -62,7 +97,6 @@ public SymbolReference<me.tomassetti.symbolsolver.model.declarations.TypeDeclara
} }
} }
} }

} }
} }


Expand Down
Expand Up @@ -28,7 +28,7 @@ public EnumDeclarationContext(EnumDeclaration wrappedNode) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
if (typeSolver == null) throw new IllegalArgumentException(); if (typeSolver == null) throw new IllegalArgumentException();


// first among declared fields // first among declared fields
Expand Down
Expand Up @@ -27,7 +27,7 @@ public FieldAccessContext(FieldAccessExpr wrappedNode) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
return JavaParserFactory.getContext(wrappedNode.getParentNode()).solveSymbol(name, typeSolver); return JavaParserFactory.getContext(wrappedNode.getParentNode()).solveSymbol(name, typeSolver);
} }


Expand Down
Expand Up @@ -76,7 +76,7 @@ public LambdaExprContext(LambdaExpr wrappedNode) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
for (Parameter parameter : wrappedNode.getParameters()) { for (Parameter parameter : wrappedNode.getParameters()) {
SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver); SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
SymbolReference symbolReference = solveWith(sb, name); SymbolReference symbolReference = solveWith(sb, name);
Expand Down
Expand Up @@ -43,7 +43,7 @@ public Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> par
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
return JavaParserFactory.getContext(wrappedNode.getParentNode()).solveSymbol(name, typeSolver); return JavaParserFactory.getContext(wrappedNode.getParentNode()).solveSymbol(name, typeSolver);
} }


Expand Down
Expand Up @@ -21,7 +21,7 @@ public MethodContext(MethodDeclaration wrappedNode) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
for (Parameter parameter : wrappedNode.getParameters()) { for (Parameter parameter : wrappedNode.getParameters()) {
SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver); SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
SymbolReference symbolReference = solveWith(sb, name); SymbolReference symbolReference = solveWith(sb, name);
Expand Down
Expand Up @@ -54,7 +54,7 @@ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
} }


@Override @Override
public SymbolReference<ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
// we should look in all the statements preceding, treating them as SymbolDeclarators // we should look in all the statements preceding, treating them as SymbolDeclarators
if (wrappedNode.getParentNode() instanceof com.github.javaparser.ast.body.MethodDeclaration){ if (wrappedNode.getParentNode() instanceof com.github.javaparser.ast.body.MethodDeclaration){
return getParent().solveSymbol(name, typeSolver); return getParent().solveSymbol(name, typeSolver);
Expand Down
Expand Up @@ -2,6 +2,7 @@


import com.github.javaparser.ast.Node; import com.github.javaparser.ast.Node;
import javassist.CtClass; import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod; import javassist.CtMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import javassist.bytecode.BadBytecode; import javassist.bytecode.BadBytecode;
Expand Down Expand Up @@ -116,8 +117,37 @@ public Optional<MethodUsage> solveMethodAsUsage(String name, List<TypeUsage> par
} }


@Override @Override
public SymbolReference<? extends ValueDeclaration> solveSymbol(String substring, TypeSolver typeSolver) { public SymbolReference<? extends ValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
throw new UnsupportedOperationException(); for (CtField field : ctClass.getDeclaredFields()) {
if (field.getName().equals(name)){
return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
}
}

try {
CtClass superClass = ctClass.getSuperclass();
if (superClass != null) {
SymbolReference<? extends ValueDeclaration> ref = new JavassistClassDeclaration(superClass).solveSymbol(name, typeSolver);
if (ref.isSolved()) {
return ref;
}
}
} catch (NotFoundException e) {
throw new RuntimeException(e);
}

try {
for (CtClass interfaze : ctClass.getInterfaces()) {
SymbolReference<? extends ValueDeclaration> ref = new JavassistClassDeclaration(interfaze).solveSymbol(name, typeSolver);
if (ref.isSolved()) {
return ref;
}
}
} catch (NotFoundException e) {
throw new RuntimeException(e);
}

return SymbolReference.unsolved(ValueDeclaration.class);
} }


@Override @Override
Expand All @@ -137,7 +167,6 @@ public Context getContext() {


@Override @Override
public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) { public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {

for (CtMethod method : ctClass.getDeclaredMethods()) { for (CtMethod method : ctClass.getDeclaredMethods()) {
if (method.getName().equals(name)){ if (method.getName().equals(name)){
// TODO check parameters // TODO check parameters
Expand Down
@@ -0,0 +1,69 @@
package me.tomassetti.symbolsolver.model.javassist;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.FieldDeclaration;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;
import me.tomassetti.symbolsolver.model.Context;
import me.tomassetti.symbolsolver.model.TypeParameter;
import me.tomassetti.symbolsolver.model.TypeSolver;
import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
import me.tomassetti.symbolsolver.model.declarations.ParameterDeclaration;
import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
import me.tomassetti.symbolsolver.model.usages.MethodUsage;

import java.util.List;

/**
* Created by federico on 01/08/15.
*/
public class JavassistFieldDeclaration implements me.tomassetti.symbolsolver.model.FieldDeclaration {
public JavassistFieldDeclaration(CtField ctField, TypeSolver typeSolver) {
this.ctField = ctField;
this.typeSolver = typeSolver;
}

private CtField ctField;
private TypeSolver typeSolver;

@Override
public TypeDeclaration getType(TypeSolver typeSolver) {
throw new UnsupportedOperationException();
}

@Override
public String getName() {
return ctField.getName();
}

@Override
public boolean isField() {
return true;
}

@Override
public boolean isParameter() {
return false;
}

@Override
public boolean isVariable() {
return false;
}

@Override
public boolean isType() {
return false;
}

@Override
public boolean isClass() {
return false;
}

@Override
public boolean isInterface() {
return false;
}
}
Expand Up @@ -25,8 +25,4 @@ public SymbolReference<TypeDeclaration> tryToSolveType(String name) {
} }
} }


@Override
public TypeDeclaration solveType(String name) throws UnsolvedSymbolException {
throw new UnsupportedOperationException();
}
} }
Expand Up @@ -78,7 +78,7 @@ public void solveSymbolReferringToDeclaredInstanceField() throws ParseException
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration); Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration);


SymbolReference<ValueDeclaration> ref = context.solveSymbol("i", new DummyTypeSolver()); SymbolReference<? extends ValueDeclaration> ref = context.solveSymbol("i", new DummyTypeSolver());
assertEquals(true, ref.isSolved()); assertEquals(true, ref.isSolved());
assertEquals("int", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName()); assertEquals("int", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName());
} }
Expand All @@ -89,7 +89,7 @@ public void solveSymbolReferringToDeclaredStaticField() throws ParseException {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration); Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration);


SymbolReference<ValueDeclaration> ref = context.solveSymbol("j", new DummyTypeSolver()); SymbolReference<? extends ValueDeclaration> ref = context.solveSymbol("j", new DummyTypeSolver());
assertEquals(true, ref.isSolved()); assertEquals(true, ref.isSolved());
assertEquals("long", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName()); assertEquals("long", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName());
} }
Expand All @@ -100,7 +100,7 @@ public void solveSymbolReferringToInehritedInstanceField() throws ParseException
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration); Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration);


SymbolReference<ValueDeclaration> ref = context.solveSymbol("k", new DummyTypeSolver()); SymbolReference<? extends ValueDeclaration> ref = context.solveSymbol("k", new DummyTypeSolver());
assertEquals(true, ref.isSolved()); assertEquals(true, ref.isSolved());
assertEquals("boolean", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName()); assertEquals("boolean", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName());
} }
Expand All @@ -111,7 +111,7 @@ public void solveSymbolReferringToInheritedStaticField() throws ParseException {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration); Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration);


SymbolReference<ValueDeclaration> ref = context.solveSymbol("m", new DummyTypeSolver()); SymbolReference<? extends ValueDeclaration> ref = context.solveSymbol("m", new DummyTypeSolver());
assertEquals(true, ref.isSolved()); assertEquals(true, ref.isSolved());
assertEquals("char", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName()); assertEquals("char", ref.getCorrespondingDeclaration().getType(new DummyTypeSolver()).getName());
} }
Expand All @@ -122,7 +122,7 @@ public void solveSymbolReferringToUnknownElement() throws ParseException {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration); Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration);


SymbolReference<ValueDeclaration> ref = context.solveSymbol("zzz", new DummyTypeSolver()); SymbolReference<? extends ValueDeclaration> ref = context.solveSymbol("zzz", new DummyTypeSolver());
assertEquals(false, ref.isSolved()); assertEquals(false, ref.isSolved());
} }


Expand Down

0 comments on commit c1e95ef

Please sign in to comment.