Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Nov 1, 2015
1 parent 52869e6 commit 965ab85
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 23 deletions.
Expand Up @@ -84,6 +84,10 @@ default PrimitiveTypeUsage asPrimitive() {
throw new UnsupportedOperationException(this.getClass().getCanonicalName()); throw new UnsupportedOperationException(this.getClass().getCanonicalName());
} }


default WildcardUsage asWildcard() {
throw new UnsupportedOperationException(this.getClass().getCanonicalName());
}

/// ///
/// Naming /// Naming
/// ///
Expand Down
@@ -1,14 +1,10 @@
package me.tomassetti.symbolsolver.model.typesystem; package me.tomassetti.symbolsolver.model.typesystem;


import com.github.javaparser.ast.type.WildcardType;

import java.util.List;

public class WildcardUsage implements TypeUsage { public class WildcardUsage implements TypeUsage {


//private WildcardType type; //private WildcardType type;
private BoundType type; private BoundType type;
private ReferenceTypeUsage boundedType; private TypeUsage boundedType;


public enum BoundType { public enum BoundType {
SUPER, SUPER,
Expand All @@ -21,15 +17,19 @@ public boolean isWildcard() {


public static WildcardUsage UNBOUNDED = new WildcardUsage(null, null); public static WildcardUsage UNBOUNDED = new WildcardUsage(null, null);


public static WildcardUsage superBound(ReferenceTypeUsage typeUsage) { public static WildcardUsage superBound(TypeUsage typeUsage) {
return new WildcardUsage(BoundType.SUPER, typeUsage); return new WildcardUsage(BoundType.SUPER, typeUsage);
} }


public static WildcardUsage extendsBound(ReferenceTypeUsage typeUsage) { public static WildcardUsage extendsBound(TypeUsage typeUsage) {
return new WildcardUsage(BoundType.EXTENDS, typeUsage); return new WildcardUsage(BoundType.EXTENDS, typeUsage);
} }


private WildcardUsage(BoundType type, ReferenceTypeUsage boundedType) { public WildcardUsage asWildcard() {
return this;
}

private WildcardUsage(BoundType type, TypeUsage boundedType) {
this.type = type; this.type = type;
this.boundedType = boundedType; this.boundedType = boundedType;
} }
Expand Down Expand Up @@ -75,7 +75,7 @@ public boolean isExtends() {
return type == BoundType.EXTENDS; return type == BoundType.EXTENDS;
} }


public ReferenceTypeUsage getBoundedType() { public TypeUsage getBoundedType() {
if (boundedType == null) { if (boundedType == null) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
Expand All @@ -87,4 +87,16 @@ public boolean isAssignableBy(TypeUsage other) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }


@Override
public TypeUsage replaceParam(String name, TypeUsage replaced) {
if (boundedType == null) {
return this;
}
TypeUsage boundedTypeReplaced = boundedType.replaceParam(name, replaced);
if (boundedTypeReplaced != boundedType) {
return new WildcardUsage(type, boundedTypeReplaced);
} else {
return this;
}
}
} }
Expand Up @@ -13,6 +13,7 @@
import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException; import me.tomassetti.symbolsolver.resolution.javaparser.UnsolvedSymbolException;
import me.tomassetti.symbolsolver.model.invokations.MethodUsage; import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
import me.tomassetti.symbolsolver.model.typesystem.TypeUsage; import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
import me.tomassetti.symbolsolver.resolution.reflection.ReflectionClassDeclaration;


import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
Expand Down Expand Up @@ -128,7 +129,15 @@ public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) { public SymbolReference<MethodDeclaration> solveMethod(String name, List<TypeUsage> parameterTypes, TypeSolver typeSolver) {
if (wrappedNode.getScope() != null) { if (wrappedNode.getScope() != null) {
TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope()); TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope());
return typeOfScope.asReferenceTypeUsage().solveMethod(name, parameterTypes, typeSolver); if (typeOfScope.isWildcard()) {
if (typeOfScope.asWildcard().isExtends() || typeOfScope.asWildcard().isSuper()) {
return typeOfScope.asWildcard().getBoundedType().asReferenceTypeUsage().solveMethod(name, parameterTypes, typeSolver);
} else {
return new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver).solveMethod(name, parameterTypes, typeSolver);
}
} else {
return typeOfScope.asReferenceTypeUsage().solveMethod(name, parameterTypes, typeSolver);
}
} else { } else {
TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode); TypeUsage typeOfScope = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
return typeOfScope.asReferenceTypeUsage().solveMethod(name, parameterTypes, typeSolver); return typeOfScope.asReferenceTypeUsage().solveMethod(name, parameterTypes, typeSolver);
Expand Down
Expand Up @@ -3,10 +3,7 @@
import me.tomassetti.symbolsolver.model.typesystem.*; import me.tomassetti.symbolsolver.model.typesystem.*;
import me.tomassetti.symbolsolver.resolution.TypeSolver; import me.tomassetti.symbolsolver.resolution.TypeSolver;


import java.lang.reflect.GenericArrayType; import java.lang.reflect.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;


/** /**
* Created by federico on 02/08/15. * Created by federico on 02/08/15.
Expand Down Expand Up @@ -36,8 +33,13 @@ public static TypeUsage typeUsageFor(Type type, TypeSolver typeSolver) {
return new TypeParameterUsage(typeParameter); return new TypeParameterUsage(typeParameter);
} else if (type instanceof ParameterizedType) { } else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type; ParameterizedType pt = (ParameterizedType) type;
// TODO deal with type parameters ReferenceTypeUsage rawType = typeUsageFor(pt.getRawType(), typeSolver).asReferenceTypeUsage();
return typeUsageFor(pt.getRawType(), typeSolver); int i=0;
for (Type actualTypeArgument : pt.getActualTypeArguments()) {
rawType = rawType.replaceParam(i, typeUsageFor(actualTypeArgument, typeSolver)).asReferenceTypeUsage();
i++;
}
return rawType;
} else if (type instanceof Class) { } else if (type instanceof Class) {
Class c = (Class) type; Class c = (Class) type;
if (c.isPrimitive()) { if (c.isPrimitive()) {
Expand All @@ -53,9 +55,29 @@ public static TypeUsage typeUsageFor(Type type, TypeSolver typeSolver) {
} else { } else {
return new ReferenceTypeUsage(new ReflectionClassDeclaration(c, typeSolver), typeSolver); return new ReferenceTypeUsage(new ReflectionClassDeclaration(c, typeSolver), typeSolver);
} }
} else if (type instanceof GenericArrayType){ } else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType)type; GenericArrayType genericArrayType = (GenericArrayType) type;
return new ArrayTypeUsage(typeUsageFor(genericArrayType.getGenericComponentType(), typeSolver)); return new ArrayTypeUsage(typeUsageFor(genericArrayType.getGenericComponentType(), typeSolver));
} else if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType)type;
if (wildcardType.getLowerBounds().length > 0 && wildcardType.getUpperBounds().length > 0) {
if (wildcardType.getUpperBounds().length == 1 && wildcardType.getUpperBounds()[0].getTypeName().equals("java.lang.Object")) {
// ok, it does not matter
}
}
if (wildcardType.getLowerBounds().length > 0) {
if (wildcardType.getLowerBounds().length > 1) {
throw new UnsupportedOperationException();
}
return WildcardUsage.superBound(typeUsageFor(wildcardType.getLowerBounds()[0], typeSolver));
}
if (wildcardType.getUpperBounds().length > 0) {
if (wildcardType.getUpperBounds().length > 1) {
throw new UnsupportedOperationException();
}
return WildcardUsage.extendsBound(typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver));
}
return WildcardUsage.UNBOUNDED;
} else { } else {
throw new UnsupportedOperationException(type.getClass().getCanonicalName()+" "+type); throw new UnsupportedOperationException(type.getClass().getCanonicalName()+" "+type);
} }
Expand Down
Expand Up @@ -251,7 +251,7 @@ public void resolveReferenceToLambdaParamBase() throws ParseException, IOExcepti
JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
TypeUsage ref = javaParserFacade.getType(refToT); TypeUsage ref = javaParserFacade.getType(refToT);


assertEquals("java.lang.String", ref.describe()); assertEquals("? super java.lang.String", ref.describe());
} }


@Test @Test
Expand Down
Expand Up @@ -393,9 +393,9 @@ public void typeParamOnReturnType() throws ParseException {
assertEquals("boolean", typeUsage.describe()); assertEquals("boolean", typeUsage.describe());
} }


@Test /*@Test
public void genericCollectionWithWildcardsPrep() throws ParseException { public void genericCollectionWithWildcardsAndExtensionsPrep() throws ParseException {
CompilationUnit cu = parseSample("GenericCollection"); CompilationUnit cu = parseSample("GenericCollectionWithExtension");
ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo"); ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
MethodDeclaration method = Navigator.demandMethod(clazz, "bar"); MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
ReturnStmt returnStmt = Navigator.findReturnStmt(method); ReturnStmt returnStmt = Navigator.findReturnStmt(method);
Expand All @@ -420,6 +420,11 @@ public void genericCollectionWithWildcardsPrep() throws ParseException {
for (Method m : List.class.getMethods()) { for (Method m : List.class.getMethods()) {
if (m.getName().equals("addAll") && !m.isBridge() && !m.isSynthetic()) { if (m.getName().equals("addAll") && !m.isBridge() && !m.isSynthetic()) {
me.tomassetti.symbolsolver.model.declarations.MethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(m, typeSolver); me.tomassetti.symbolsolver.model.declarations.MethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(m, typeSolver);
if (methods.size() == 0) {
// ok, e' il primo
ReferenceTypeUsage paramType = methodDeclaration.getParam(0).getType(typeSolver).asReferenceTypeUsage();
assertTrue(paramType.asReferenceTypeUsage().parameters().get(0).isWildcard());
}
MethodUsage mu = new MethodUsage(methodDeclaration, typeSolver); MethodUsage mu = new MethodUsage(methodDeclaration, typeSolver);
int i = 0; int i = 0;
for (TypeParameter tp : typeDeclaration.getTypeParameters()) { for (TypeParameter tp : typeDeclaration.getTypeParameters()) {
Expand All @@ -440,6 +445,23 @@ public void genericCollectionWithWildcardsPrep() throws ParseException {
//assertTrue(methodUsage.isPresent()); //assertTrue(methodUsage.isPresent());
}*/

@Test
public void genericCollectionWithWildcardsAndExtensions() throws ParseException {
CompilationUnit cu = parseSample("GenericCollectionWithExtension");
ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
ReturnStmt returnStmt = Navigator.findReturnStmt(method);

TypeSolver typeSolver = new JreTypeSolver();
Expression returnStmtExpr = returnStmt.getExpr();
JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);

TypeUsage typeUsage = javaParserFacade.getType(returnStmtExpr);

assertEquals(false, typeUsage.isTypeVariable());
assertEquals("boolean", typeUsage.describe());
} }


@Test @Test
Expand Down
15 changes: 15 additions & 0 deletions src/test/resources/GenericCollectionWithExtension.java.txt
@@ -0,0 +1,15 @@
class Node {
}

class Comment extends Node {
}

class Foo {

public Object bar() {
Node node;
java.util.List<Node> children = new java.util.LinkedList<Node>();
java.util.List<Comment> commentsToAttribute;
return children.addAll(commentsToAttribute);
}
}
@@ -1,5 +1,5 @@


[ Class com.github.javaparser.ast.internal.Utils ] [ Class com.github.javaparser.ast.internal.Utils ]
superclass: java.lang.Object superclass: java.lang.Object
Line 35) list == null ? Collections.<T>emptyList() : list ==> java.util.List<E> Line 35) list == null ? Collections.<T>emptyList() : list ==> java.util.List<T>
Line 39) collection == null || collection.isEmpty() ==> boolean Line 39) collection == null || collection.isEmpty() ==> boolean

0 comments on commit 965ab85

Please sign in to comment.