Search in sources :

Example 1 with InferredValue

use of org.checkerframework.framework.util.typeinference.solver.InferredValue 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 != null && equalityInferred instanceof InferredType) {
            if (supertypeInferred != null && supertypeInferred instanceof InferredType) {
                AnnotatedTypeMirror superATM = ((InferredType) supertypeInferred).type;
                AnnotatedTypeMirror equalityATM = ((InferredType) equalityInferred).type;
                if (TypesUtils.isErasedSubtype(equalityATM.getUnderlyingType(), superATM.getUnderlyingType(), typeFactory.getContext().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 2 with InferredValue

use of org.checkerframework.framework.util.typeinference.solver.InferredValue in project checker-framework by typetools.

the class DefaultTypeArgumentInference method clampToLowerBound.

/**
 * If we have inferred a type argument from the supertype constraints and this type argument is
 * BELOW the lower bound, make it AT the lower bound
 *
 * <p>e.g.
 *
 * <pre>{@code
 * <@Initialized T extends @Initialized Object> void id(T t) { return t; }
 * id(null);
 *
 * // The invocation of id will result in a type argument with primary annotations of @FBCBottom @Nullable
 * // but this is below the lower bound of T in the initialization hierarchy so instead replace
 * //@FBCBottom with @Initialized
 *
 * // This should happen ONLY with supertype constraints because raising the primary annotation would still
 * // be valid for these constraints (since we just LUB the arguments involved) but would violate any
 * // equality constraints
 * }</pre>
 *
 * TODO: NOTE WE ONLY DO THIS FOR InferredType results for now but we should probably include
 * targest as well
 *
 * @param fromArgSupertypes types inferred from LUBbing types from the arguments to the formal
 *     parameters
 * @param targetDeclarations the declared types of the type parameters whose arguments are being
 *     inferred
 */
private void clampToLowerBound(InferenceResult fromArgSupertypes, List<AnnotatedTypeVariable> targetDeclarations, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    for (AnnotatedTypeVariable targetDecl : targetDeclarations) {
        InferredValue inferred = fromArgSupertypes.get(targetDecl.getUnderlyingType());
        if (inferred != null && inferred instanceof InferredType) {
            final AnnotatedTypeMirror lowerBoundAsArgument = targetDecl.getLowerBound();
            for (AnnotationMirror top : tops) {
                final AnnotationMirror lowerBoundAnno = lowerBoundAsArgument.getEffectiveAnnotationInHierarchy(top);
                final AnnotationMirror argAnno = ((InferredType) inferred).type.getEffectiveAnnotationInHierarchy(top);
                if (qualifierHierarchy.isSubtype(argAnno, lowerBoundAnno)) {
                    ((InferredType) inferred).type.replaceAnnotation(lowerBoundAnno);
                }
            }
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) InferredValue(org.checkerframework.framework.util.typeinference.solver.InferredValue) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)2 InferredValue (org.checkerframework.framework.util.typeinference.solver.InferredValue)2 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 TypeVariable (javax.lang.model.type.TypeVariable)1 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)1 TypeHierarchy (org.checkerframework.framework.type.TypeHierarchy)1 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)1 InferenceResult (org.checkerframework.framework.util.typeinference.solver.InferenceResult)1