use of com.github.javaparser.resolution.MethodUsage in project javaparser by javaparser.
the class MethodDeclarationCommonLogic method resolveTypeVariables.
public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
ResolvedType returnType = replaceTypeParams(methodDeclaration.getReturnType(), typeSolver, context);
List<ResolvedType> params = new ArrayList<>();
for (int i = 0; i < methodDeclaration.getNumberOfParams(); i++) {
ResolvedType replaced = replaceTypeParams(methodDeclaration.getParam(i).getType(), typeSolver, context);
params.add(replaced);
}
// We now look at the type parameter for the method which we can derive from the parameter types
// and then we replace them in the return type
// Map<TypeParameterDeclaration, Type> determinedTypeParameters = new HashMap<>();
InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
for (int i = 0; i < methodDeclaration.getNumberOfParams() - (methodDeclaration.hasVariadicParameter() ? 1 : 0); i++) {
ResolvedType formalParamType = methodDeclaration.getParam(i).getType();
ResolvedType actualParamType = parameterTypes.get(i);
inferenceContext.addPair(formalParamType, actualParamType);
}
returnType = inferenceContext.resolve(inferenceContext.addSingle(returnType));
return new MethodUsage(methodDeclaration, params, returnType);
}
use of com.github.javaparser.resolution.MethodUsage in project javaparser by javaparser.
the class MethodCallExprContext method solveMethodAsUsage.
// /
// / Private methods
// /
private Optional<MethodUsage> solveMethodAsUsage(ResolvedReferenceType refType, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
Optional<MethodUsage> ref = ContextHelper.solveMethodAsUsage(refType.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, refType.typeParametersValues());
if (ref.isPresent()) {
MethodUsage methodUsage = ref.get();
methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
// At this stage I should derive from the context and the value some information on the type parameters
// for example, when calling:
// myStream.collect(Collectors.toList())
// I should be able to figure out that considering the type of the stream (e.g., Stream<String>)
// and considering that Stream has this method:
//
// <R,A> R collect(Collector<? super T,A,R> collector)
//
// and collector has this method:
//
// static <T> Collector<T,?,List<T>> toList()
//
// In this case collect.R has to be equal to List<toList.T>
// And toList.T has to be equal to ? super Stream.T
// Therefore R has to be equal to List<? super Stream.T>.
// In our example Stream.T equal to String, so the R (and the result of the call to collect) is
// List<? super String>
Map<ResolvedTypeParameterDeclaration, ResolvedType> derivedValues = new HashMap<>();
for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
ResolvedParameterDeclaration parameter = methodUsage.getDeclaration().getParam(i);
ResolvedType parameterType = parameter.getType();
if (parameter.isVariadic()) {
parameterType = parameterType.asArrayType().getComponentType();
}
inferTypes(argumentsTypes.get(i), parameterType, derivedValues);
}
for (Map.Entry<ResolvedTypeParameterDeclaration, ResolvedType> entry : derivedValues.entrySet()) {
methodUsage = methodUsage.replaceTypeParameter(entry.getKey(), entry.getValue());
}
ResolvedType returnType = refType.useThisTypeParametersOnTheGivenType(methodUsage.returnType());
if (returnType != methodUsage.returnType()) {
methodUsage = methodUsage.replaceReturnType(returnType);
}
for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
ResolvedType replaced = refType.useThisTypeParametersOnTheGivenType(methodUsage.getParamTypes().get(i));
methodUsage = methodUsage.replaceParamType(i, replaced);
}
return Optional.of(methodUsage);
} else {
return ref;
}
}
use of com.github.javaparser.resolution.MethodUsage in project javaparser by javaparser.
the class LambdaExprContext method solveSymbolAsValue.
@Override
public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
for (Parameter parameter : wrappedNode.getParameters()) {
SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
int index = 0;
for (ResolvedValueDeclaration decl : sb.getSymbolDeclarations()) {
if (decl.getName().equals(name)) {
if (requireParentNode(wrappedNode) instanceof MethodCallExpr) {
MethodCallExpr methodCallExpr = (MethodCallExpr) requireParentNode(wrappedNode);
MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
int i = pos(methodCallExpr, wrappedNode);
ResolvedType lambdaType = methodUsage.getParamTypes().get(i);
// Get the functional method in order for us to resolve it's type arguments properly
Optional<MethodUsage> functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType);
if (functionalMethodOpt.isPresent()) {
MethodUsage functionalMethod = functionalMethodOpt.get();
InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
// Resolve each type variable of the lambda, and use this later to infer the type of each
// implicit parameter
inferenceContext.addPair(lambdaType, new ReferenceTypeImpl(lambdaType.asReferenceType().getTypeDeclaration(), typeSolver));
// Find the position of this lambda argument
boolean found = false;
int lambdaParamIndex;
for (lambdaParamIndex = 0; lambdaParamIndex < wrappedNode.getParameters().size(); lambdaParamIndex++) {
if (wrappedNode.getParameter(lambdaParamIndex).getName().getIdentifier().equals(name)) {
found = true;
break;
}
}
if (!found) {
return Optional.empty();
}
// Now resolve the argument type using the inference context
ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(functionalMethod.getParamType(lambdaParamIndex)));
ResolvedLambdaConstraintType conType;
if (argType.isWildcard()) {
conType = ResolvedLambdaConstraintType.bound(argType.asWildcard().getBoundedType());
} else {
conType = ResolvedLambdaConstraintType.bound(argType);
}
Value value = new Value(conType, name);
return Optional.of(value);
} else {
return Optional.empty();
}
} else if (requireParentNode(wrappedNode) instanceof VariableDeclarator) {
VariableDeclarator variableDeclarator = (VariableDeclarator) requireParentNode(wrappedNode);
ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator);
Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t);
if (functionalMethod.isPresent()) {
ResolvedType lambdaType = functionalMethod.get().getParamType(index);
// Replace parameter from declarator
Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
if (lambdaType.isReferenceType()) {
for (com.github.javaparser.utils.Pair<ResolvedTypeParameterDeclaration, ResolvedType> entry : lambdaType.asReferenceType().getTypeParametersMap()) {
if (entry.b.isTypeVariable() && entry.b.asTypeParameter().declaredOnType()) {
ResolvedType ot = t.asReferenceType().typeParametersMap().getValue(entry.a);
lambdaType = lambdaType.replaceTypeVariables(entry.a, ot, inferredTypes);
}
}
} else if (lambdaType.isTypeVariable() && lambdaType.asTypeParameter().declaredOnType()) {
lambdaType = t.asReferenceType().typeParametersMap().getValue(lambdaType.asTypeParameter());
}
Value value = new Value(lambdaType, name);
return Optional.of(value);
} else {
throw new UnsupportedOperationException();
}
} else {
throw new UnsupportedOperationException();
}
}
index++;
}
}
// if nothing is found we should ask the parent context
return getParent().solveSymbolAsValue(name, typeSolver);
}
use of com.github.javaparser.resolution.MethodUsage in project javaparser by javaparser.
the class ReflectionMethodResolutionLogic method replaceParams.
private static MethodUsage replaceParams(List<ResolvedType> typeParameterValues, ResolvedReferenceTypeDeclaration typeParametrizable, ResolvedMethodDeclaration methodDeclaration) {
MethodUsage methodUsage = new MethodUsage(methodDeclaration);
int i = 0;
// Only replace if we have enough values provided
if (typeParameterValues.size() == typeParametrizable.getTypeParameters().size()) {
for (ResolvedTypeParameterDeclaration tp : typeParametrizable.getTypeParameters()) {
methodUsage = methodUsage.replaceTypeParameter(tp, typeParameterValues.get(i));
i++;
}
}
for (ResolvedTypeParameterDeclaration methodTypeParameter : methodDeclaration.getTypeParameters()) {
methodUsage = methodUsage.replaceTypeParameter(methodTypeParameter, new ResolvedTypeVariable(methodTypeParameter));
}
return methodUsage;
}
use of com.github.javaparser.resolution.MethodUsage in project javaparser by javaparser.
the class ReflectionMethodResolutionLogic method solveMethodAsUsage.
static Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext, List<ResolvedType> typeParameterValues, ResolvedReferenceTypeDeclaration 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()) {
ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
MethodUsage methodUsage = replaceParams(typeParameterValues, scopeType, methodDeclaration);
methods.add(methodUsage);
}
}
for (ResolvedReferenceType ancestor : scopeType.getAncestors()) {
SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
ResolvedMethodDeclaration 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<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, argumentsTypes, typeSolver);
if (ref.isSolved()) {
MethodUsage usage = replaceParams(typeParameterValues, objectClass.getTypeDeclaration(), ref.getCorrespondingDeclaration());
methods.add(usage);
}
}
final List<ResolvedType> finalTypeParameterValues = typeParameterValues;
argumentsTypes = argumentsTypes.stream().map((pt) -> {
int i = 0;
for (ResolvedTypeParameterDeclaration tp : scopeType.getTypeParameters()) {
pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
i++;
}
return pt;
}).collect(Collectors.toList());
return MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver);
}
Aggregations