framework.src.org.checkerframework.qualframework.poly.ContainmentHierarchy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checker Show documentation
Show all versions of checker Show documentation
The Checker Framework enhances Java’s type system to
make it more powerful and useful. This lets software developers
detect and prevent errors in their Java programs.
The Checker Framework includes compiler plug-ins ("checkers")
that find bugs or verify their absence. It also permits you to
write your own compiler plug-ins.
package org.checkerframework.qualframework.poly;
import org.checkerframework.qualframework.base.QualifierHierarchy;
/** A hierarchy of {@link Wildcard}s, ordered by the containment relation (JLS
* 4.5.1).
*/
public class ContainmentHierarchy implements QualifierHierarchy> {
private QualifierHierarchy> polyQualHierarchy;
/**
* @param polyQualHierarchy the hierarchy to use for comparing wildcard bounds
*/
public ContainmentHierarchy(QualifierHierarchy> polyQualHierarchy) {
this.polyQualHierarchy = polyQualHierarchy;
}
@Override
public boolean isSubtype(Wildcard subtype, Wildcard supertype) {
if (subtype.isEmpty()) {
return true;
}
if (supertype.isEmpty()) {
return false;
}
// We consider SUB to be a subtype of SUPER if SUB is contained by
// SUPER. SUPER contains SUB if the bounds of SUPER lie outside the
// bounds of SUB.
return polyQualHierarchy.isSubtype(supertype.getLowerBound(), subtype.getLowerBound())
&& polyQualHierarchy.isSubtype(subtype.getUpperBound(), supertype.getUpperBound());
}
@Override
public Wildcard leastUpperBound(Wildcard a, Wildcard b) {
if (a.isEmpty()) {
return b;
}
if (b.isEmpty()) {
return a;
}
// Take the more permissive input for each bound, to produce a new
// wildcard that contains both `a` and `b`.
return new Wildcard(
polyQualHierarchy.greatestLowerBound(a.getLowerBound(), b.getLowerBound()),
polyQualHierarchy.leastUpperBound(a.getUpperBound(), b.getUpperBound()));
}
@Override
public Wildcard greatestLowerBound(Wildcard a, Wildcard b) {
if (a.isEmpty()) {
return a;
}
if (b.isEmpty()) {
return b;
}
PolyQual newLower = polyQualHierarchy.leastUpperBound(a.getLowerBound(), b.getLowerBound());
PolyQual newUpper = polyQualHierarchy.greatestLowerBound(a.getUpperBound(), b.getUpperBound());
if (!polyQualHierarchy.isSubtype(newLower, newUpper)) {
return Wildcard.empty();
} else {
return new Wildcard(newLower, newUpper);
}
}
@Override
public Wildcard getTop() {
return new Wildcard(polyQualHierarchy.getBottom(), polyQualHierarchy.getTop());
}
@Override
public Wildcard getBottom() {
return Wildcard.empty();
}
}