Search in sources :

Example 76 with ResolvedType

use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.

the class ExpressionCompatibleWithType method reduce.

@Override
public ReductionResult reduce(BoundSet currentBoundSet) {
    if (isProperType(T)) {
        if (isCompatibleInALooseInvocationContext(typeSolver, expression, T)) {
            return ReductionResult.trueResult();
        } else {
            return ReductionResult.falseResult();
        }
    }
    if (isStandaloneExpression(expression)) {
        ResolvedType s = JavaParserFacade.get(typeSolver).getType(expression, false);
        return ReductionResult.empty().withConstraint(new TypeCompatibleWithType(typeSolver, s, T));
    }
    if (isPolyExpression(expression)) {
        if (expression instanceof EnclosedExpr) {
            EnclosedExpr enclosedExpr = (EnclosedExpr) expression;
            return ReductionResult.oneConstraint(new ExpressionCompatibleWithType(typeSolver, enclosedExpr.getInner(), T));
        }
        if (expression instanceof ObjectCreationExpr) {
            BoundSet B3 = new TypeInference(typeSolver).invocationTypeInferenceBoundsSetB3();
            return ReductionResult.bounds(B3);
        }
        if (expression instanceof MethodCallExpr) {
            throw new UnsupportedOperationException();
        }
        if (expression instanceof ConditionalExpr) {
            ConditionalExpr conditionalExpr = (ConditionalExpr) expression;
            return ReductionResult.withConstraints(new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getThenExpr(), T), new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getElseExpr(), T));
        }
        if (expression instanceof LambdaExpr) {
            LambdaExpr lambdaExpr = (LambdaExpr) expression;
            if (!FunctionalInterfaceLogic.isFunctionalInterfaceType(T)) {
                return ReductionResult.falseResult();
            }
            // - Otherwise, let T' be the ground target type derived from T, as specified in §15.27.3. If §18.5.3
            // is used to derive a functional interface type which is parameterized, then the test that
            // F<A'1, ..., A'm> is a subtype of F<A1, ..., Am> is not performed (instead, it is asserted with a
            // constraint formula below). Let the target function type for the lambda expression be the
            // function type of T'. Then:
            Pair<ResolvedType, Boolean> result = TypeHelper.groundTargetTypeOfLambda(lambdaExpr, T, typeSolver);
            ResolvedType TFirst = result.a;
            MethodType targetFunctionType = TypeHelper.getFunctionType(TFirst);
            targetFunctionType = replaceTypeVariablesWithInferenceVariables(targetFunctionType);
            if (result.b) {
                throw new UnsupportedOperationException();
            }
            if (targetFunctionType.getFormalArgumentTypes().size() != lambdaExpr.getParameters().size()) {
                return ReductionResult.falseResult();
            }
            if (targetFunctionType.getReturnType().isVoid()) {
                throw new UnsupportedOperationException();
            }
            if (!targetFunctionType.getReturnType().isVoid() && lambdaExpr.getBody() instanceof BlockStmt && !isValueCompatibleBlock(lambdaExpr.getBody())) {
                return ReductionResult.falseResult();
            }
            // - Otherwise, the constraint reduces to all of the following constraint formulas:
            List<ConstraintFormula> constraints = new LinkedList<>();
            // - If the lambda parameters have explicitly declared types F1, ..., Fn and the function type
            // has parameter types G1, ..., Gn, then i) for all i (1 ≤ i ≤ n), ‹Fi = Gi›, and ii) ‹T' <: T›.
            boolean hasExplicitlyDeclaredTypes = lambdaExpr.getParameters().stream().anyMatch(p -> !(p.getType() instanceof UnknownType));
            if (hasExplicitlyDeclaredTypes) {
                throw new UnsupportedOperationException();
            }
            if (!targetFunctionType.getReturnType().isVoid()) {
                ResolvedType R = targetFunctionType.getReturnType();
                if (TypeHelper.isProperType(R)) {
                    if (lambdaExpr.getBody() instanceof BlockStmt) {
                        List<Expression> resultExpressions = ExpressionHelper.getResultExpressions((BlockStmt) lambdaExpr.getBody());
                        for (Expression e : resultExpressions) {
                            if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
                                return ReductionResult.falseResult();
                            }
                        }
                    } else {
                        Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
                        if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
                            return ReductionResult.falseResult();
                        }
                    }
                } else {
                    if (lambdaExpr.getBody() instanceof BlockStmt) {
                        getAllReturnExpressions((BlockStmt) lambdaExpr.getBody()).forEach(e -> constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R)));
                    } else {
                        // FEDERICO: Added - Start
                        for (int i = 0; i < lambdaExpr.getParameters().size(); i++) {
                            ResolvedType paramType = targetFunctionType.getFormalArgumentTypes().get(i);
                            TypeInferenceCache.record(typeSolver, lambdaExpr, lambdaExpr.getParameter(i).getNameAsString(), paramType);
                        }
                        // FEDERICO: Added - End
                        Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
                        constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R));
                    }
                }
            }
            return ReductionResult.withConstraints(constraints);
        }
        if (expression instanceof MethodReferenceExpr) {
            throw new UnsupportedOperationException();
        }
        throw new RuntimeException("This should not happen");
    }
    throw new RuntimeException("This should not happen");
}
Also used : ResolvedType(com.github.javaparser.resolution.types.ResolvedType) LinkedList(java.util.LinkedList) UnknownType(com.github.javaparser.ast.type.UnknownType) ExpressionHelper.isStandaloneExpression(com.github.javaparser.symbolsolver.resolution.typeinference.ExpressionHelper.isStandaloneExpression) ExpressionHelper.isPolyExpression(com.github.javaparser.symbolsolver.resolution.typeinference.ExpressionHelper.isPolyExpression)

Example 77 with ResolvedType

use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.

the class TypeSameAsType method reduce.

@Override
public ReductionResult reduce(BoundSet currentBoundSet) {
    if (!S.isWildcard() && !T.isWildcard()) {
        if (isProperType(S) && isProperType(T)) {
            if (S.equals(T)) {
                return ReductionResult.trueResult();
            } else {
                return ReductionResult.falseResult();
            }
        }
        if (S.isNull() || T.isNull()) {
            return ReductionResult.falseResult();
        }
        if (isInferenceVariable(S) && !T.isPrimitive()) {
            return ReductionResult.oneBound(new SameAsBound(S, T));
        }
        if (isInferenceVariable(T) && !S.isPrimitive()) {
            return ReductionResult.oneBound(new SameAsBound(S, T));
        }
        if (S.isReferenceType() && T.isReferenceType() && S.asReferenceType().toRawType().equals(T.asReferenceType().toRawType())) {
            ReductionResult res = ReductionResult.empty();
            List<ResolvedType> Bs = S.asReferenceType().typeParametersValues();
            List<ResolvedType> As = T.asReferenceType().typeParametersValues();
            for (int i = 0; i < Bs.size(); i++) {
                res = res.withConstraint(new TypeSameAsType(Bs.get(i), As.get(i)));
            }
            return res;
        }
        if (S.isArray() && T.isArray()) {
            return ReductionResult.oneConstraint(new TypeSameAsType(S.asArrayType().getComponentType(), T.asArrayType().getComponentType()));
        }
        return ReductionResult.falseResult();
    }
    throw new UnsupportedOperationException();
}
Also used : SameAsBound(com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SameAsBound) ResolvedType(com.github.javaparser.resolution.types.ResolvedType)

Example 78 with ResolvedType

use of com.github.javaparser.resolution.types.ResolvedType 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)

Example 79 with ResolvedType

use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.

the class ConstructorResolutionLogic method isApplicable.

private static boolean isApplicable(ResolvedConstructorDeclaration constructor, List<ResolvedType> 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
            ResolvedType expectedType = constructor.getLastParam().getType();
            ResolvedType actualType = argumentsTypes.get(pos);
            if (!expectedType.isAssignableBy(actualType)) {
                for (ResolvedTypeParameterDeclaration 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, ResolvedType> matchedParameters = new HashMap<>();
    boolean needForWildCardTolerance = false;
    for (int i = 0; i < constructor.getNumberOfParams(); i++) {
        ResolvedType expectedType = constructor.getParam(i).getType();
        ResolvedType 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 ResolvedArrayType(expectedType).isAssignableBy(actualType));
        if (!isAssignableWithoutSubstitution && expectedType.isReferenceType() && actualType.isReferenceType()) {
            isAssignableWithoutSubstitution = MethodResolutionLogic.isAssignableMatchTypeParameters(expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters);
        }
        if (!isAssignableWithoutSubstitution) {
            List<ResolvedTypeParameterDeclaration> typeParameters = constructor.getTypeParameters();
            typeParameters.addAll(constructor.declaringType().getTypeParameters());
            for (ResolvedTypeParameterDeclaration 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 ResolvedArrayType(expectedType).isAssignableBy(actualType)) {
                        continue;
                    }
                }
                return false;
            }
        }
    }
    return !withWildcardTolerance || needForWildCardTolerance;
}
Also used : ResolvedArrayType(com.github.javaparser.resolution.types.ResolvedArrayType) HashMap(java.util.HashMap) ResolvedTypeParameterDeclaration(com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration) ResolvedType(com.github.javaparser.resolution.types.ResolvedType)

Example 80 with ResolvedType

use of com.github.javaparser.resolution.types.ResolvedType in project javaparser by javaparser.

the class ConstructorResolutionLogic method isMoreSpecific.

private static boolean isMoreSpecific(ResolvedConstructorDeclaration constructorA, ResolvedConstructorDeclaration constructorB, TypeSolver typeSolver) {
    boolean oneMoreSpecificFound = false;
    if (constructorA.getNumberOfParams() < constructorB.getNumberOfParams()) {
        return true;
    }
    if (constructorA.getNumberOfParams() > constructorB.getNumberOfParams()) {
        return false;
    }
    for (int i = 0; i < constructorA.getNumberOfParams(); i++) {
        ResolvedType tdA = constructorA.getParam(i).getType();
        ResolvedType tdB = constructorB.getParam(i).getType();
        // B is more specific
        if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) {
            oneMoreSpecificFound = true;
        }
        // A is more specific
        if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) {
            return false;
        }
        // FIXME
        if (i == (constructorA.getNumberOfParams() - 1) && tdA.arrayLevel() > tdB.arrayLevel()) {
            return true;
        }
    }
    return oneMoreSpecificFound;
}
Also used : ResolvedType(com.github.javaparser.resolution.types.ResolvedType)

Aggregations

ResolvedType (com.github.javaparser.resolution.types.ResolvedType)119 Test (org.junit.Test)78 CompilationUnit (com.github.javaparser.ast.CompilationUnit)68 ReflectionTypeSolver (com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver)58 MethodDeclaration (com.github.javaparser.ast.body.MethodDeclaration)41 ClassOrInterfaceDeclaration (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)39 TypeSolver (com.github.javaparser.symbolsolver.model.resolution.TypeSolver)32 Expression (com.github.javaparser.ast.expr.Expression)27 JavaParserFacade (com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade)22 ReturnStmt (com.github.javaparser.ast.stmt.ReturnStmt)21 ReferenceTypeImpl (com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl)20 MethodCallExpr (com.github.javaparser.ast.expr.MethodCallExpr)18 AbstractResolutionTest (com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest)18 MethodUsage (com.github.javaparser.resolution.MethodUsage)17 VariableDeclarator (com.github.javaparser.ast.body.VariableDeclarator)15 Context (com.github.javaparser.symbolsolver.core.resolution.Context)15 ResolvedReferenceType (com.github.javaparser.resolution.types.ResolvedReferenceType)14 ResolvedMethodDeclaration (com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration)10 ResolvedTypeParameterDeclaration (com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration)10 Collectors (java.util.stream.Collectors)10