use of org.checkerframework.framework.type.QualifierHierarchy in project checker-framework by typetools.
the class QualifierDefaults method addClimbStandardDefaults.
/**
* Add standard CLIMB defaults that do not conflict with previously added defaults.
*/
public void addClimbStandardDefaults() {
QualifierHierarchy qualHierarchy = this.atypeFactory.getQualifierHierarchy();
Set<? extends AnnotationMirror> tops = qualHierarchy.getTopAnnotations();
Set<? extends AnnotationMirror> bottoms = qualHierarchy.getBottomAnnotations();
for (TypeUseLocation loc : standardClimbDefaultsTop) {
for (AnnotationMirror top : tops) {
if (!conflictsWithExistingDefaults(checkedCodeDefaults, top, loc)) {
// Only add standard defaults in locations where a default has not been
// specified
addCheckedCodeDefault(top, loc);
}
}
}
for (TypeUseLocation loc : standardClimbDefaultsBottom) {
for (AnnotationMirror bottom : bottoms) {
if (!conflictsWithExistingDefaults(checkedCodeDefaults, bottom, loc)) {
// Only add standard defaults in locations where a default has not been
// specified
addCheckedCodeDefault(bottom, loc);
}
}
}
}
use of org.checkerframework.framework.type.QualifierHierarchy in project checker-framework by typetools.
the class SubtypesSolver method glbSubtypes.
public InferenceResult glbSubtypes(final Set<TypeVariable> remainingTargets, final ConstraintMap constraints, final AnnotatedTypeFactory typeFactory) {
final InferenceResult inferenceResult = new InferenceResult();
final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
final Types types = typeFactory.getProcessingEnv().getTypeUtils();
List<TypeVariable> targetsSubtypesLast = new ArrayList<>(remainingTargets);
// If we have two type variables <A, A extends B> order them A then B
// this is required because we will use the fact that B must be below A
// when determining the glb of B
Collections.sort(targetsSubtypesLast, new Comparator<TypeVariable>() {
@Override
public int compare(TypeVariable o1, TypeVariable o2) {
if (types.isSubtype(o1, o2)) {
return 1;
} else if (types.isSubtype(o2, o1)) {
return -1;
}
return 0;
}
});
for (final TypeVariable target : targetsSubtypesLast) {
Subtypes subtypes = constraints.getConstraints(target).subtypes;
if (subtypes.types.isEmpty()) {
continue;
}
propagatePreviousGlbs(subtypes, inferenceResult, subtypes.types);
// if the subtypes size is only 1 then we need not do any GLBing on the underlying types
// but we may have primary annotations that need to be GLBed
AnnotationMirrorMap<AnnotationMirrorSet> primaries = subtypes.primaries;
if (subtypes.types.size() == 1) {
final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> entry = subtypes.types.entrySet().iterator().next();
AnnotatedTypeMirror supertype = entry.getKey().deepCopy();
for (AnnotationMirror top : entry.getValue()) {
final AnnotationMirrorSet superAnnos = primaries.get(top);
// if it is null we're just going to use the anno already on supertype
if (superAnnos != null) {
final AnnotationMirror supertypeAnno = supertype.getAnnotationInHierarchy(top);
superAnnos.add(supertypeAnno);
}
}
if (!primaries.isEmpty()) {
for (AnnotationMirror top : qualifierHierarchy.getTopAnnotations()) {
final AnnotationMirror glb = greatestLowerBound(subtypes.primaries.get(top), qualifierHierarchy);
supertype.replaceAnnotation(glb);
}
}
inferenceResult.put(target, new InferredType(supertype));
} else {
// GLB all of the types than combine this with the GLB of primary annotation
// constraints
final AnnotatedTypeMirror glbType = GlbUtil.glbAll(subtypes.types, typeFactory);
if (glbType != null) {
if (!primaries.isEmpty()) {
for (AnnotationMirror top : qualifierHierarchy.getTopAnnotations()) {
final AnnotationMirror glb = greatestLowerBound(subtypes.primaries.get(top), qualifierHierarchy);
final AnnotationMirror currentAnno = glbType.getAnnotationInHierarchy(top);
if (currentAnno == null) {
glbType.addAnnotation(glb);
} else if (glb != null) {
glbType.replaceAnnotation(qualifierHierarchy.greatestLowerBound(glb, currentAnno));
}
}
}
inferenceResult.put(target, new InferredType(glbType));
}
}
}
return inferenceResult;
}
use of org.checkerframework.framework.type.QualifierHierarchy in project checker-framework by typetools.
the class BaseTypeVisitor method checkContractsSubset.
/**
* Checks that {@code mustSubset} is a subset of {@code set} in the following sense: For every
* expression in {@code mustSubset} there must be the same expression in {@code set}, with the
* same (or a stronger) annotation.
*/
private void checkContractsSubset(String overriderMeth, String overriderTyp, String overriddenMeth, String overriddenTyp, Set<Pair<Receiver, AnnotationMirror>> mustSubset, Set<Pair<Receiver, AnnotationMirror>> set, @CompilerMessageKey String messageKey) {
for (Pair<Receiver, AnnotationMirror> weak : mustSubset) {
boolean found = false;
for (Pair<Receiver, AnnotationMirror> strong : set) {
// are we looking at a contract of the same receiver?
if (weak.first.equals(strong.first)) {
// check subtyping relationship of annotations
QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
if (qualifierHierarchy.isSubtype(strong.second, weak.second)) {
found = true;
break;
}
}
}
if (!found) {
MethodTree method = visitorState.getMethodTree();
checker.report(Result.failure(messageKey, overriderMeth, overriderTyp, overriddenMeth, overriddenTyp, weak.second, weak.first), method);
}
}
}
use of org.checkerframework.framework.type.QualifierHierarchy in project checker-framework by typetools.
the class FieldInvariants method isSuperInvariant.
/**
* @return null if {@code superInvar} is a super invariant, otherwise returns a Result with the
* error message
*/
public Result isSuperInvariant(FieldInvariants superInvar, AnnotatedTypeFactory factory) {
QualifierHierarchy qualifierHierarchy = factory.getQualifierHierarchy();
if (!this.fields.containsAll(superInvar.fields)) {
List<String> missingFields = new ArrayList<>(superInvar.fields);
missingFields.removeAll(fields);
return Result.failure("field.invariant.not.found.superclass", PluginUtil.join(", ", missingFields));
}
for (String field : superInvar.fields) {
List<AnnotationMirror> superQualifiers = superInvar.getQualifiersFor(field);
List<AnnotationMirror> subQualifiers = this.getQualifiersFor(field);
for (AnnotationMirror superA : superQualifiers) {
AnnotationMirror sub = qualifierHierarchy.findAnnotationInSameHierarchy(subQualifiers, superA);
if (sub == null || !qualifierHierarchy.isSubtype(sub, superA)) {
return Result.failure("field.invariant.not.subtype.superclass", field, sub, superA);
}
}
}
return null;
}
use of org.checkerframework.framework.type.QualifierHierarchy in project checker-framework by typetools.
the class BaseTypeValidator method areBoundsValid.
/**
* @return true if the effective annotations on the upperBound are above those on the lowerBound
*/
public boolean areBoundsValid(final AnnotatedTypeMirror upperBound, final AnnotatedTypeMirror lowerBound) {
final QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
final Set<AnnotationMirror> upperBoundAnnos = AnnotatedTypes.findEffectiveAnnotations(qualifierHierarchy, upperBound);
final Set<AnnotationMirror> lowerBoundAnnos = AnnotatedTypes.findEffectiveAnnotations(qualifierHierarchy, lowerBound);
if (upperBoundAnnos.size() == lowerBoundAnnos.size()) {
return qualifierHierarchy.isSubtype(lowerBoundAnnos, upperBoundAnnos);
}
return true;
}
Aggregations