Search in sources :

Example 31 with MethodUsage

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);
}
Also used : InferenceContext(com.github.javaparser.symbolsolver.logic.InferenceContext) ArrayList(java.util.ArrayList) MethodUsage(com.github.javaparser.resolution.MethodUsage) ResolvedType(com.github.javaparser.resolution.types.ResolvedType)

Example 32 with MethodUsage

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;
    }
}
Also used : HashMap(java.util.HashMap) MethodUsage(com.github.javaparser.resolution.MethodUsage) HashMap(java.util.HashMap) Map(java.util.Map)

Example 33 with MethodUsage

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);
}
Also used : SymbolDeclarator(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator) InferenceContext(com.github.javaparser.symbolsolver.logic.InferenceContext) ResolvedLambdaConstraintType(com.github.javaparser.resolution.types.ResolvedLambdaConstraintType) ReferenceTypeImpl(com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) Value(com.github.javaparser.symbolsolver.model.resolution.Value) Parameter(com.github.javaparser.ast.body.Parameter) MethodUsage(com.github.javaparser.resolution.MethodUsage) ResolvedValueDeclaration(com.github.javaparser.resolution.declarations.ResolvedValueDeclaration) ResolvedType(com.github.javaparser.resolution.types.ResolvedType) MethodCallExpr(com.github.javaparser.ast.expr.MethodCallExpr)

Example 34 with MethodUsage

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;
}
Also used : ResolvedTypeVariable(com.github.javaparser.resolution.types.ResolvedTypeVariable) MethodUsage(com.github.javaparser.resolution.MethodUsage) ResolvedTypeParameterDeclaration(com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration)

Example 35 with 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);
}
Also used : ResolvedReferenceType(com.github.javaparser.resolution.types.ResolvedReferenceType) ReferenceTypeImpl(com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ResolvedTypeParameterDeclaration(com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration) ResolvedMethodDeclaration(com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration) MethodUsage(com.github.javaparser.resolution.MethodUsage) ResolvedType(com.github.javaparser.resolution.types.ResolvedType)

Aggregations

MethodUsage (com.github.javaparser.resolution.MethodUsage)59 Test (org.junit.Test)39 CompilationUnit (com.github.javaparser.ast.CompilationUnit)36 MethodCallExpr (com.github.javaparser.ast.expr.MethodCallExpr)33 MethodDeclaration (com.github.javaparser.ast.body.MethodDeclaration)27 ReflectionTypeSolver (com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver)24 TypeSolver (com.github.javaparser.symbolsolver.model.resolution.TypeSolver)20 ClassOrInterfaceDeclaration (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)19 AbstractResolutionTest (com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest)14 ResolvedType (com.github.javaparser.resolution.types.ResolvedType)12 AbstractTest (com.github.javaparser.symbolsolver.AbstractTest)12 Context (com.github.javaparser.symbolsolver.core.resolution.Context)12 CombinedTypeSolver (com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver)11 ResolvedMethodDeclaration (com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration)7 ResolvedReferenceType (com.github.javaparser.resolution.types.ResolvedReferenceType)6 JavaParserFacade (com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade)6 ClassOrInterfaceDeclarationContext (com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext)6 CompilationUnitContext (com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext)6 InferenceContext (com.github.javaparser.symbolsolver.logic.InferenceContext)6 UnsolvedSymbolException (com.github.javaparser.resolution.UnsolvedSymbolException)5