org.checkerframework.framework.util.GraphQualifierHierarchy Maven / Gradle / Ivy
Show all versions of checker Show documentation
package org.checkerframework.framework.util;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.ErrorReporter;
/**
* Represents the type qualifier hierarchy of a type system.
*
* This class is immutable and can be only created through {@link
* MultiGraphQualifierHierarchy.MultiGraphFactory}.
*/
public class GraphQualifierHierarchy extends MultiGraphQualifierHierarchy {
public GraphQualifierHierarchy(MultiGraphFactory f, AnnotationMirror bottom) {
super(f, bottom);
// this.bottom = bottom;
}
// private final AnnotationMirror bottom;
@Override
protected void finish(
QualifierHierarchy qualHierarchy,
Map> fullMap,
Map polyQualifiers,
Set tops,
Set bottoms,
Object... args) {
// Careful, when this method is called, a field this.bottom would not be set yet.
if (args != null && args[0] != null) {
AnnotationMirror thebottom = (AnnotationMirror) args[0];
// A special bottom qualifier was provided; go through the existing
// bottom qualifiers and tie them all to this bottom qualifier.
// Set bottoms = findBottoms(supertypes);
Set allQuals = AnnotationUtils.createAnnotationSet();
allQuals.addAll(fullMap.keySet());
allQuals.remove(thebottom);
AnnotationUtils.updateMappingToImmutableSet(fullMap, thebottom, allQuals);
// thebottom is initially a top qualifier
tops.remove(thebottom);
// thebottom is now the single bottom qualifier
bottoms.clear();
bottoms.add(thebottom);
}
}
/**
* Returns the top qualifier for this hierarchy.
*
* The top qualifier is inferred from the hierarchy, as being the only one without any super
* qualifiers
*/
@Override
public Set getTopAnnotations() {
if (tops.size() != 1) {
ErrorReporter.errorAbort(
"Expected 1 possible top qualifier, found "
+ tops.size()
+ " (does the checker know about all type qualifiers?): "
+ tops);
}
return this.tops;
}
@Override
public Set getBottomAnnotations() {
// TODO: checks?
return this.bottoms;
}
@Override
public boolean isSubtype(
Collection rhs,
Collection lhs) {
rhs = replacePolyAll(rhs);
lhs = replacePolyAll(lhs);
if (lhs.isEmpty() || rhs.isEmpty()) {
ErrorReporter.errorAbort(
"GraphQualifierHierarchy: Empty annotations in lhs: "
+ lhs
+ " or rhs: "
+ rhs);
}
if (lhs.size() > 1) {
ErrorReporter.errorAbort(
"GraphQualifierHierarchy: Type with more than one annotation found: " + lhs);
}
if (rhs.size() > 1) {
ErrorReporter.errorAbort(
"GraphQualifierHierarchy: Type with more than one annotation found: " + rhs);
}
for (AnnotationMirror lhsAnno : lhs) {
for (AnnotationMirror rhsAnno : rhs) {
if (isSubtype(rhsAnno, lhsAnno)) {
return true;
}
}
}
return false;
}
}