use of com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration in project javaparser by javaparser.
the class MethodUsage method replaceTypeParameter.
public MethodUsage replaceTypeParameter(TypeParameterDeclaration typeParameter, Type type) {
if (type == null) {
throw new IllegalArgumentException();
}
// TODO if the method declaration has a type param with that name ignore this call
MethodUsage res = new MethodUsage(declaration, paramTypes, returnType, typeParametersMap.toBuilder().setValue(typeParameter, type).build());
Map<TypeParameterDeclaration, Type> inferredTypes = new HashMap<>();
for (int i = 0; i < paramTypes.size(); i++) {
Type originalParamType = paramTypes.get(i);
Type newParamType = originalParamType.replaceTypeVariables(typeParameter, type, inferredTypes);
res = res.replaceParamType(i, newParamType);
}
Type oldReturnType = res.returnType;
Type newReturnType = oldReturnType.replaceTypeVariables(typeParameter, type, inferredTypes);
res = res.replaceReturnType(newReturnType);
return res;
}
use of com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration in project javaparser by javaparser.
the class ConstructorResolutionLogic method isApplicable.
private static boolean isApplicable(ConstructorDeclaration constructor, List<Type> argumentsTypes, TypeSolver typeSolver, boolean withWildcardTolerance) {
if (constructor.hasVariadicParameter()) {
int pos = constructor.getNumberOfParams() - 1;
if (constructor.getNumberOfParams() == argumentsTypes.size()) {
// check if the last value is directly assignable as an array
Type expectedType = constructor.getLastParam().getType();
Type actualType = argumentsTypes.get(pos);
if (!expectedType.isAssignableBy(actualType)) {
for (TypeParameterDeclaration tp : constructor.getTypeParameters()) {
expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
}
if (!expectedType.isAssignableBy(actualType)) {
if (actualType.isArray() && expectedType.isAssignableBy(actualType.asArrayType().getComponentType())) {
argumentsTypes.set(pos, actualType.asArrayType().getComponentType());
} else {
argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType());
}
}
}
// else it is already assignable, nothing to do
} else {
if (pos > argumentsTypes.size()) {
return false;
}
argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType());
}
}
if (constructor.getNumberOfParams() != argumentsTypes.size()) {
return false;
}
Map<String, Type> matchedParameters = new HashMap<>();
boolean needForWildCardTolerance = false;
for (int i = 0; i < constructor.getNumberOfParams(); i++) {
Type expectedType = constructor.getParam(i).getType();
Type actualType = argumentsTypes.get(i);
if ((expectedType.isTypeVariable() && !(expectedType.isWildcard())) && expectedType.asTypeParameter().declaredOnMethod()) {
matchedParameters.put(expectedType.asTypeParameter().getName(), actualType);
continue;
}
boolean isAssignableWithoutSubstitution = expectedType.isAssignableBy(actualType) || (constructor.getParam(i).isVariadic() && new ArrayType(expectedType).isAssignableBy(actualType));
if (!isAssignableWithoutSubstitution && expectedType.isReferenceType() && actualType.isReferenceType()) {
isAssignableWithoutSubstitution = MethodResolutionLogic.isAssignableMatchTypeParameters(expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters);
}
if (!isAssignableWithoutSubstitution) {
List<TypeParameterDeclaration> typeParameters = constructor.getTypeParameters();
typeParameters.addAll(constructor.declaringType().getTypeParameters());
for (TypeParameterDeclaration tp : typeParameters) {
expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
}
if (!expectedType.isAssignableBy(actualType)) {
if (actualType.isWildcard() && withWildcardTolerance && !expectedType.isPrimitive()) {
needForWildCardTolerance = true;
continue;
}
if (constructor.hasVariadicParameter() && i == constructor.getNumberOfParams() - 1) {
if (new ArrayType(expectedType).isAssignableBy(actualType)) {
continue;
}
}
return false;
}
}
}
return !withWildcardTolerance || needForWildCardTolerance;
}
use of com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration in project javaparser by javaparser.
the class ReflectionFactory method typeUsageFor.
public static Type typeUsageFor(java.lang.reflect.Type type, TypeSolver typeSolver) {
if (type instanceof java.lang.reflect.TypeVariable) {
java.lang.reflect.TypeVariable<?> tv = (java.lang.reflect.TypeVariable<?>) type;
boolean declaredOnClass = tv.getGenericDeclaration() instanceof java.lang.reflect.Type;
TypeParameterDeclaration typeParameter = new ReflectionTypeParameter(tv, declaredOnClass, typeSolver);
return new com.github.javaparser.symbolsolver.model.typesystem.TypeVariable(typeParameter);
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
ReferenceType rawType = typeUsageFor(pt.getRawType(), typeSolver).asReferenceType();
List<java.lang.reflect.Type> actualTypes = new ArrayList<>();
actualTypes.addAll(Arrays.asList(pt.getActualTypeArguments()));
// we consume the actual types
rawType = rawType.transformTypeParameters(tp -> typeUsageFor(actualTypes.remove(0), typeSolver)).asReferenceType();
return rawType;
} else if (type instanceof Class) {
Class<?> c = (Class<?>) type;
if (c.isPrimitive()) {
if (c.getName().equals(Void.TYPE.getName())) {
return VoidType.INSTANCE;
} else {
return PrimitiveType.byName(c.getName());
}
} else if (c.isArray()) {
return new ArrayType(typeUsageFor(c.getComponentType(), typeSolver));
} else {
return new ReferenceTypeImpl(typeDeclarationFor(c, typeSolver), typeSolver);
}
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) type;
return new ArrayType(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 Wildcard.superBound(typeUsageFor(wildcardType.getLowerBounds()[0], typeSolver));
}
if (wildcardType.getUpperBounds().length > 0) {
if (wildcardType.getUpperBounds().length > 1) {
throw new UnsupportedOperationException();
}
return Wildcard.extendsBound(typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver));
}
return Wildcard.UNBOUNDED;
} else {
throw new UnsupportedOperationException(type.getClass().getCanonicalName() + " " + type);
}
}
use of com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration in project javaparser by javaparser.
the class ReflectionMethodResolutionLogic method solveMethodAsUsage.
static Optional<MethodUsage> solveMethodAsUsage(String name, List<Type> argumentsTypes, TypeSolver typeSolver, Context invokationContext, List<Type> typeParameterValues, ReferenceTypeDeclaration scopeType, Class clazz) {
if (typeParameterValues.size() != scopeType.getTypeParameters().size()) {
// if it is zero we are going to ignore them
if (!scopeType.getTypeParameters().isEmpty()) {
// Parameters not specified, so default to Object
typeParameterValues = new ArrayList<>();
for (int i = 0; i < scopeType.getTypeParameters().size(); i++) {
typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver));
}
}
}
List<MethodUsage> methods = new ArrayList<>();
for (Method method : clazz.getMethods()) {
if (method.getName().equals(name) && !method.isBridge() && !method.isSynthetic()) {
MethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
MethodUsage methodUsage = replaceParams(typeParameterValues, scopeType, methodDeclaration);
methods.add(methodUsage);
}
}
for (ReferenceType ancestor : scopeType.getAncestors()) {
SymbolReference<MethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
MethodDeclaration correspondingDeclaration = ref.getCorrespondingDeclaration();
MethodUsage methodUsage = replaceParams(typeParameterValues, ancestor.getTypeDeclaration(), correspondingDeclaration);
methods.add(methodUsage);
}
}
if (scopeType.getAncestors().isEmpty()) {
ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
SymbolReference<MethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
MethodUsage usage = replaceParams(typeParameterValues, objectClass.getTypeDeclaration(), ref.getCorrespondingDeclaration());
methods.add(usage);
}
}
final List<Type> finalTypeParameterValues = typeParameterValues;
argumentsTypes = argumentsTypes.stream().map((pt) -> {
int i = 0;
for (TypeParameterDeclaration tp : scopeType.getTypeParameters()) {
pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
i++;
}
return pt;
}).collect(Collectors.toList());
return MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver);
}
use of com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration in project javaparser by javaparser.
the class MethodCallExprContext method solveMethodAsUsage.
@Override
public Optional<MethodUsage> solveMethodAsUsage(String name, List<Type> argumentsTypes, TypeSolver typeSolver) {
if (wrappedNode.getScope().isPresent()) {
Expression scope = wrappedNode.getScope().get();
// Consider static method calls
if (scope instanceof NameExpr) {
String className = ((NameExpr) scope).getName().getId();
SymbolReference<TypeDeclaration> ref = solveType(className, typeSolver);
if (ref.isSolved()) {
SymbolReference<MethodDeclaration> m = MethodResolutionLogic.solveMethodInType(ref.getCorrespondingDeclaration(), name, argumentsTypes, typeSolver);
if (m.isSolved()) {
MethodUsage methodUsage = new MethodUsage(m.getCorrespondingDeclaration());
methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
methodUsage = resolveMethodTypeParameters(methodUsage, argumentsTypes);
return Optional.of(methodUsage);
} else {
throw new UnsolvedSymbolException(ref.getCorrespondingDeclaration().toString(), "Method '" + name + "' with parameterTypes " + argumentsTypes);
}
}
}
Type typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
// we can replace the parameter types from the scope into the typeParametersValues
Map<TypeParameterDeclaration, Type> inferredTypes = new HashMap<>();
for (int i = 0; i < argumentsTypes.size(); i++) {
// by replacing types I can also find new equivalences
// for example if I replace T=U with String because I know that T=String I can derive that also U equal String
Type originalArgumentType = argumentsTypes.get(i);
Type updatedArgumentType = usingParameterTypesFromScope(typeOfScope, originalArgumentType, inferredTypes);
argumentsTypes.set(i, updatedArgumentType);
}
for (int i = 0; i < argumentsTypes.size(); i++) {
Type updatedArgumentType = applyInferredTypes(argumentsTypes.get(i), inferredTypes);
argumentsTypes.set(i, updatedArgumentType);
}
return solveMethodAsUsage(typeOfScope, name, argumentsTypes, typeSolver, this);
} else {
Context parentContext = getParent();
while (parentContext instanceof MethodCallExprContext) {
parentContext = parentContext.getParent();
}
return parentContext.solveMethodAsUsage(name, argumentsTypes, typeSolver);
}
}
Aggregations