77import org .checkerframework .framework .type .StructuralEqualityComparer ;
88import org .checkerframework .framework .type .StructuralEqualityVisitHistory ;
99import org .checkerframework .framework .type .SubtypeVisitHistory ;
10+ import org .checkerframework .javacutil .AnnotationUtils ;
1011import org .checkerframework .javacutil .BugInCF ;
1112
1213import javax .lang .model .element .AnnotationMirror ;
1314
15+ import checkers .inference .model .ConstantSlot ;
16+ import checkers .inference .model .ConstraintManager ;
1417import checkers .inference .model .Slot ;
18+ import checkers .inference .qual .VarAnnot ;
1519
1620/**
1721 * The InferenceTypeHierarchy along with the InferenceQualifierHierarchy is responsible for
@@ -27,6 +31,8 @@ public class InferenceTypeHierarchy extends DefaultTypeHierarchy {
2731 private final AnnotationMirror varAnnot ;
2832 // TODO: Think this through, add any missing constraints
2933
34+ private final SlotManager slotMgr ;
35+ private final ConstraintManager constraintMgr ;
3036
3137 /**
3238 * Constructs an instance of {@code TypeHierarchy} for the type system
@@ -41,6 +47,9 @@ public InferenceTypeHierarchy(final BaseTypeChecker checker, final QualifierHier
4147 checker .getOption ("ignoreRawTypeArguments" , "true" ).equals ("true" ),
4248 checker .hasOption ("invariantArrays" ));
4349 this .varAnnot = varAnnot ;
50+
51+ slotMgr = InferenceMain .getInstance ().getSlotManager ();
52+ constraintMgr = InferenceMain .getInstance ().getConstraintManager ();
4453 }
4554
4655 public boolean areEqual (AnnotatedTypeMirror type1 , AnnotatedTypeMirror type2 ) {
@@ -52,6 +61,37 @@ public StructuralEqualityComparer createEqualityComparer() {
5261 return new InferenceEqualityComparer (this .typeargVisitHistory ,
5362 InferenceQualifierHierarchy .findVarAnnot (qualifierHierarchy .getTopAnnotations ()));
5463 }
64+
65+ @ Override
66+ public boolean isSubtype (
67+ final AnnotatedTypeMirror subtype , final AnnotatedTypeMirror supertype ) {
68+ AnnotationMirror subAnno = subtype .getAnnotationInHierarchy (varAnnot );
69+ AnnotationMirror superAnno = supertype .getAnnotationInHierarchy (varAnnot );
70+
71+ if (!isVarAnnot (subAnno ) || !isVarAnnot (superAnno )) {
72+ return isSubtype (subtype , supertype , varAnnot );
73+ }
74+
75+ final Slot subSlot = slotMgr .getSlot (subAnno );
76+ final Slot superSlot = slotMgr .getSlot (superAnno );
77+
78+ if (subSlot instanceof ConstantSlot || superSlot instanceof ConstantSlot ) {
79+ return isSubtype (subtype , supertype , varAnnot );
80+ }
81+
82+ return constraintMgr .addSubtypeConstraintNoErrorMsg (subSlot , superSlot );
83+ }
84+
85+ /**
86+ * @return true if anno is an instance of @VarAnnot
87+ */
88+ public static boolean isVarAnnot (AnnotationMirror anno ) {
89+ if (InferenceMain .isHackMode (anno == null )) {
90+ return false ;
91+ }
92+
93+ return AnnotationUtils .areSameByClass (anno , VarAnnot .class );
94+ }
5595}
5696
5797class InferenceEqualityComparer extends StructuralEqualityComparer {
0 commit comments