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;
}
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;
}
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));
}
}
}
}
}
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);
}
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;
}
}
Aggregations