use of org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredTarget in project checker-framework by typetools.
the class EqualitiesSolver method findEqualTarget.
/**
* Attempt to find a target which is equal to this target.
*
* @return a target equal to this target in all hierarchies, or null
*/
public InferredTarget findEqualTarget(final Equalities equalities, AnnotationMirrorSet tops) {
for (Map.Entry<TypeVariable, AnnotationMirrorSet> targetToHierarchies : equalities.targets.entrySet()) {
final TypeVariable equalTarget = targetToHierarchies.getKey();
final AnnotationMirrorSet hierarchies = targetToHierarchies.getValue();
// Now see if target is equal to equalTarget in all hierarchies
boolean targetIsEqualInAllHierarchies = hierarchies.size() == tops.size();
if (targetIsEqualInAllHierarchies) {
return new InferredTarget(equalTarget, new AnnotationMirrorSet());
} else {
// annos in primaries that are not covered by the target's list of equal hierarchies
final AnnotationMirrorSet requiredPrimaries = new AnnotationMirrorSet(equalities.primaries.keySet());
requiredPrimaries.removeAll(hierarchies);
boolean typeWithPrimariesIsEqual = (requiredPrimaries.size() + hierarchies.size()) == tops.size();
if (typeWithPrimariesIsEqual) {
return new InferredTarget(equalTarget, requiredPrimaries);
}
}
}
return null;
}
use of org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredTarget in project checker-framework by typetools.
the class InferenceResult method mergeTarget.
/**
* Performs a merge for a specific target, we keep only results that lead to a concrete type
*/
protected InferredType mergeTarget(final TypeVariable target, final InferenceResult subordinate) {
final InferredValue inferred = this.get(target);
if (inferred instanceof InferredTarget) {
InferredType newType = mergeTarget(((InferredTarget) inferred).target, subordinate);
if (newType == null) {
final InferredValue subValue = subordinate.get(target);
if (subValue != null && subValue instanceof InferredType) {
this.put(target, subValue);
return null;
}
} else {
if (newType.type.getKind() == TypeKind.NULL) {
// If the newType is null, then use the subordinate type, but with the
// primary annotations on null.
final InferredValue subValue = subordinate.get(target);
if (subValue != null && subValue instanceof InferredType) {
AnnotatedTypeMirror copy = ((InferredType) subValue).type.deepCopy();
copy.replaceAnnotations(newType.type.getAnnotations());
newType = new InferredType(copy);
}
}
this.put(target, newType);
return newType;
}
return null;
}
return (InferredType) inferred;
}
use of org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredTarget in project checker-framework by typetools.
the class InferenceResult method resolveChainedTargets.
/**
* If we had a set of inferred results, (e.g. T1 = T2, T2 = T3, T3 = String) propagate any
* results we have (the above constraints become T1 = String, T2 = String, T3 = String)
*/
public void resolveChainedTargets() {
final Map<TypeVariable, InferredValue> inferredTypes = new LinkedHashMap<>(this.size());
// TODO: we can probably make this a bit more efficient
boolean grew = true;
while (grew == true) {
grew = false;
for (final Entry<TypeVariable, InferredValue> inferred : this.entrySet()) {
final TypeVariable target = inferred.getKey();
final InferredValue value = inferred.getValue();
if (value instanceof InferredType) {
inferredTypes.put(target, value);
} else {
final InferredTarget currentTarget = (InferredTarget) value;
final InferredType equivalentType = (InferredType) inferredTypes.get(((InferredTarget) value).target);
if (equivalentType != null) {
grew = true;
final AnnotatedTypeMirror type = equivalentType.type.deepCopy();
type.replaceAnnotations(currentTarget.additionalAnnotations);
final InferredType newConstraint = new InferredType(type);
inferredTypes.put(currentTarget.target, newConstraint);
}
}
}
}
this.putAll(inferredTypes);
}
Aggregations