Search in sources :

Example 21 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method inferFromAssignment.

/**
 * The Second half of step 6. Use the assignment context to infer a result.
 */
private InferenceResult inferFromAssignment(final AnnotatedTypeMirror assignedTo, final AnnotatedTypeMirror boxedReturnType, final AnnotatedExecutableType methodType, final Set<AFConstraint> afArgumentConstraints, final InferenceResult inferredArgs, final Set<TypeVariable> targets, final AnnotatedTypeFactory typeFactory) {
    ConstraintMap assignmentConstraints = createAssignmentConstraints(assignedTo, boxedReturnType, methodType, afArgumentConstraints, inferredArgs.toAtmMap(), targets, typeFactory);
    InferenceResult equalitiesResult = equalitiesSolver.solveEqualities(targets, assignmentConstraints, typeFactory);
    Set<TypeVariable> remainingTargets = equalitiesResult.getRemainingTargets(targets, true);
    InferenceResult subtypesResult = subtypesSolver.solveFromSubtypes(remainingTargets, assignmentConstraints, typeFactory);
    equalitiesResult.mergeSubordinate(subtypesResult);
    return equalitiesResult;
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) ConstraintMap(org.checkerframework.framework.util.typeinference.solver.ConstraintMap) InferenceResult(org.checkerframework.framework.util.typeinference.solver.InferenceResult)

Example 22 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method combineSupertypeAndAssignmentResults.

/**
 * Step 4. Combine the results from using the Supertype constraints the Equality constraints from
 * the assignment context.
 */
private InferenceResult combineSupertypeAndAssignmentResults(Set<TypeVariable> targets, AnnotatedTypeFactory typeFactory, InferenceResult equalityResult, InferenceResult supertypeResult) {
    final TypeHierarchy typeHierarchy = typeFactory.getTypeHierarchy();
    final InferenceResult result = new InferenceResult();
    for (final TypeVariable target : targets) {
        final InferredValue equalityInferred = equalityResult.get(target);
        final InferredValue supertypeInferred = supertypeResult.get(target);
        final InferredValue outputValue;
        if (equalityInferred instanceof InferredType) {
            if (supertypeInferred instanceof InferredType) {
                AnnotatedTypeMirror superATM = ((InferredType) supertypeInferred).type;
                AnnotatedTypeMirror equalityATM = ((InferredType) equalityInferred).type;
                if (TypesUtils.isErasedSubtype(equalityATM.getUnderlyingType(), superATM.getUnderlyingType(), typeFactory.getChecker().getTypeUtils())) {
                    // If the underlying type of equalityATM is a subtype of the underlying
                    // type of superATM, then the call to isSubtype below will issue an error.
                    // So call asSuper so that the isSubtype call below works correctly.
                    equalityATM = AnnotatedTypes.asSuper(typeFactory, equalityATM, superATM);
                }
                if (typeHierarchy.isSubtype(superATM, equalityATM)) {
                    outputValue = equalityInferred;
                } else {
                    outputValue = supertypeInferred;
                }
            } else {
                outputValue = equalityInferred;
            }
        } else {
            if (supertypeInferred != null) {
                outputValue = supertypeInferred;
            } else {
                outputValue = null;
            }
        }
        if (outputValue != null) {
            result.put(target, outputValue);
        }
    }
    return result;
}
Also used : InferredValue(org.checkerframework.framework.util.typeinference.solver.InferredValue) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) InferenceResult(org.checkerframework.framework.util.typeinference.solver.InferenceResult) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 23 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method addConstraintsBetweenTargets.

/**
 * Declarations of the form: {@code <A, B extends A>} implies a TUConstraint of {@code B <: A}.
 * Add these to the constraint list.
 */
public void addConstraintsBetweenTargets(Set<TUConstraint> constraints, Set<TypeVariable> targets, boolean asSubtype, AnnotatedTypeFactory typeFactory) {
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    final List<TypeVariable> targetList = new ArrayList<>(targets);
    final Map<TypeVariable, AnnotatedTypeVariable> paramDeclarations = new HashMap<>();
    for (int i = 0; i < targetList.size(); i++) {
        final TypeVariable earlierTarget = targetList.get(i);
        for (int j = i + 1; j < targetList.size(); j++) {
            final TypeVariable laterTarget = targetList.get(j);
            if (types.isSameType(earlierTarget.getUpperBound(), laterTarget)) {
                final AnnotatedTypeVariable headDecl = addOrGetDeclarations(earlierTarget, typeFactory, paramDeclarations);
                final AnnotatedTypeVariable nextDecl = addOrGetDeclarations(laterTarget, typeFactory, paramDeclarations);
                if (asSubtype) {
                    constraints.add(new TSubU(headDecl, nextDecl));
                } else {
                    constraints.add(new TSuperU(nextDecl, headDecl));
                }
            } else if (types.isSameType(laterTarget.getUpperBound(), earlierTarget)) {
                final AnnotatedTypeVariable headDecl = addOrGetDeclarations(earlierTarget, typeFactory, paramDeclarations);
                final AnnotatedTypeVariable nextDecl = addOrGetDeclarations(laterTarget, typeFactory, paramDeclarations);
                if (asSubtype) {
                    constraints.add(new TSubU(nextDecl, headDecl));
                } else {
                    constraints.add(new TSuperU(headDecl, nextDecl));
                }
            }
        }
    }
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) TSuperU(org.checkerframework.framework.util.typeinference.constraint.TSuperU) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AFConstraint(org.checkerframework.framework.util.typeinference.constraint.AFConstraint) TUConstraint(org.checkerframework.framework.util.typeinference.constraint.TUConstraint) TSubU(org.checkerframework.framework.util.typeinference.constraint.TSubU)

Example 24 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method inferFromArguments.

/**
 * Step 2. Infer type arguments from the equality (TisU) and the supertype (TSuperU) constraints
 * of the methods arguments.
 */
private Pair<InferenceResult, InferenceResult> inferFromArguments(final AnnotatedTypeFactory typeFactory, final Set<AFConstraint> afArgumentConstraints, final Set<TypeVariable> targets) {
    Set<TUConstraint> tuArgConstraints = afToTuConstraints(afArgumentConstraints, targets);
    addConstraintsBetweenTargets(tuArgConstraints, targets, false, typeFactory);
    ConstraintMap argConstraints = constraintMapBuilder.build(targets, tuArgConstraints, typeFactory);
    InferenceResult inferredFromArgEqualities = equalitiesSolver.solveEqualities(targets, argConstraints, typeFactory);
    Set<TypeVariable> remainingTargets = inferredFromArgEqualities.getRemainingTargets(targets, true);
    InferenceResult fromSupertypes = supertypesSolver.solveFromSupertypes(remainingTargets, argConstraints, typeFactory);
    InferenceResult fromSubtypes = subtypesSolver.solveFromSubtypes(remainingTargets, argConstraints, typeFactory);
    fromSupertypes.mergeSubordinate(fromSubtypes);
    return Pair.of(inferredFromArgEqualities, fromSupertypes);
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) ConstraintMap(org.checkerframework.framework.util.typeinference.solver.ConstraintMap) InferenceResult(org.checkerframework.framework.util.typeinference.solver.InferenceResult) TUConstraint(org.checkerframework.framework.util.typeinference.constraint.TUConstraint)

Example 25 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class DefaultTypeArgumentInference method inferTypeArgs.

@Override
public Map<TypeVariable, AnnotatedTypeMirror> inferTypeArgs(AnnotatedTypeFactory typeFactory, ExpressionTree expressionTree, ExecutableElement methodElem, AnnotatedExecutableType methodType) {
    final List<AnnotatedTypeMirror> argTypes = TypeArgInferenceUtil.getArgumentTypes(expressionTree, typeFactory);
    final TreePath pathToExpression = typeFactory.getPath(expressionTree);
    assert pathToExpression != null;
    AnnotatedTypeMirror assignedTo = TypeArgInferenceUtil.assignedTo(typeFactory, pathToExpression);
    SourceChecker checker = typeFactory.getChecker();
    if (showInferenceSteps) {
        checker.message(Kind.NOTE, "DTAI: expression: %s%n  argTypes: %s%n  assignedTo: %s", expressionTree.toString().replace(System.lineSeparator(), " "), argTypes, assignedTo);
    }
    final Set<TypeVariable> targets = TypeArgInferenceUtil.methodTypeToTargets(methodType);
    if (TreePathUtil.enclosingNonParen(pathToExpression).first.getKind() == Tree.Kind.LAMBDA_EXPRESSION || (assignedTo == null && TreePathUtil.getAssignmentContext(pathToExpression) != null)) {
        // If the type of the assignment context isn't found, but the expression is assigned,
        // then don't attempt to infer type arguments, because the Java type inferred will be
        // incorrect.  The assignment type is null when it includes uninferred type arguments.
        // For example:
        // <T> T outMethod()
        // <U> void inMethod(U u);
        // inMethod(outMethod())
        // would require solving the constraints for both type argument inferences
        // simultaneously
        // Also, if the parent of the expression is a lambda, then the type arguments cannot be
        // inferred.
        Map<TypeVariable, AnnotatedTypeMirror> inferredArgs = new LinkedHashMap<>();
        handleUninferredTypeVariables(typeFactory, methodType, targets, inferredArgs);
        return inferredArgs;
    }
    if (assignedTo == null) {
        assignedTo = typeFactory.getDummyAssignedTo(expressionTree);
    }
    Map<TypeVariable, AnnotatedTypeMirror> inferredArgs;
    try {
        inferredArgs = infer(typeFactory, argTypes, assignedTo, methodElem, methodType, targets, true);
        if (showInferenceSteps) {
            checker.message(Kind.NOTE, "  after infer: %s", inferredArgs);
        }
        handleNullTypeArguments(typeFactory, methodElem, methodType, argTypes, assignedTo, targets, inferredArgs);
        if (showInferenceSteps) {
            checker.message(Kind.NOTE, "  after handleNull: %s", inferredArgs);
        }
    } catch (Exception ex) {
        // Catch any errors thrown by inference.
        inferredArgs = new LinkedHashMap<>();
        if (showInferenceSteps) {
            checker.message(Kind.NOTE, "  exception: %s", ex.getLocalizedMessage());
        }
    }
    handleUninferredTypeVariables(typeFactory, methodType, targets, inferredArgs);
    if (showInferenceSteps) {
        checker.message(Kind.NOTE, "  results: %s", inferredArgs);
    }
    try {
        return TypeArgInferenceUtil.correctResults(inferredArgs, expressionTree, (ExecutableType) methodElem.asType(), typeFactory);
    } catch (Throwable ex) {
        // Ignore any exceptions
        return inferredArgs;
    }
}
Also used : TreePath(com.sun.source.util.TreePath) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) SourceChecker(org.checkerframework.framework.source.SourceChecker) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

TypeVariable (javax.lang.model.type.TypeVariable)80 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)38 TypeMirror (javax.lang.model.type.TypeMirror)30 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)22 TypeElement (javax.lang.model.element.TypeElement)21 ArrayList (java.util.ArrayList)16 DeclaredType (javax.lang.model.type.DeclaredType)15 HashMap (java.util.HashMap)14 LinkedHashMap (java.util.LinkedHashMap)13 Map (java.util.Map)13 ExecutableElement (javax.lang.model.element.ExecutableElement)12 TypeParameterElement (javax.lang.model.element.TypeParameterElement)12 Test (org.junit.Test)10 ArrayType (javax.lang.model.type.ArrayType)9 WildcardType (javax.lang.model.type.WildcardType)9 AnnotationMirror (javax.lang.model.element.AnnotationMirror)8 Element (javax.lang.model.element.Element)8 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)8 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)8 VariableElement (javax.lang.model.element.VariableElement)7