Skip to content

Commit 8a29a0e

Browse files
authored
Fix polymorphism check and introduce the concept of PolymorphicInstanceSlot (#381)
1 parent d59282a commit 8a29a0e

File tree

5 files changed

+50
-12
lines changed

5 files changed

+50
-12
lines changed

src/checkers/inference/DefaultSlotManager.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,11 @@ public int getNumberOfSlots() {
369369
return nextId - 1;
370370
}
371371

372-
@Override
373-
public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location, TypeMirror type) {
372+
private SourceVariableSlot createSourceVariableSlot(
373+
AnnotationLocation location,
374+
TypeMirror type,
375+
boolean insertable
376+
) {
374377
AnnotationMirror defaultAnnotation = null;
375378
if (!InferenceOptions.makeDefaultsExplicit) {
376379
// retrieve the default annotation when needed
@@ -381,7 +384,7 @@ public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location,
381384
if (location.getKind() == AnnotationLocation.Kind.MISSING) {
382385
if (InferenceMain.isHackMode()) {
383386
//Don't cache slot for MISSING LOCATION. Just create a new one and return.
384-
sourceVarSlot = new SourceVariableSlot(nextId(), location, type, defaultAnnotation, true);
387+
sourceVarSlot = new SourceVariableSlot(nextId(), location, type, defaultAnnotation, insertable);
385388
addToSlots(sourceVarSlot);
386389
} else {
387390
throw new BugInCF("Creating SourceVariableSlot on MISSING_LOCATION!");
@@ -391,13 +394,25 @@ public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location,
391394
int id = locationCache.get(location);
392395
sourceVarSlot = (SourceVariableSlot) getSlot(id);
393396
} else {
394-
sourceVarSlot = new SourceVariableSlot(nextId(), location, type, defaultAnnotation, true);
397+
sourceVarSlot = new SourceVariableSlot(nextId(), location, type, defaultAnnotation, insertable);
395398
addToSlots(sourceVarSlot);
396399
locationCache.put(location, sourceVarSlot.getId());
397400
}
398401
return sourceVarSlot;
399402
}
400403

404+
@Override
405+
public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location, TypeMirror type) {
406+
return createSourceVariableSlot(location, type, true);
407+
}
408+
409+
@Override
410+
public VariableSlot createPolymorphicInstanceSlot(AnnotationLocation location, TypeMirror type) {
411+
// TODO: For now, a polymorphic instance slot is just equivalent to a non-insertable
412+
// source variable slot. We may consider changing this implementation later.
413+
return createSourceVariableSlot(location, type, false);
414+
}
415+
401416
/**
402417
* Find the default annotation for this location by checking the real type factory.
403418
* @param location location to create a new {@link SourceVariableSlot}

src/checkers/inference/InferenceAnnotatedTypeFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,12 @@ public InferenceAnnotatedTypeFactory(
150150
existentialInserter = new ExistentialVariableInserter(slotManager, constraintManager,
151151
realTop, varAnnot, variableAnnotator);
152152

153-
inferencePoly = new InferenceQualifierPolymorphism(slotManager, variableAnnotator, this, varAnnot);
153+
inferencePoly = new InferenceQualifierPolymorphism(
154+
slotManager,
155+
variableAnnotator,
156+
this,
157+
realTypeFactory,
158+
varAnnot);
154159

155160
constantToVariableAnnotator = new ConstantToVariableAnnotator(realTop, varAnnot);
156161
// Every subclass must call postInit!

src/checkers/inference/InferenceQualifierPolymorphism.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package checkers.inference;
22

3+
import checkers.inference.model.VariableSlot;
4+
import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
35
import org.checkerframework.framework.type.AnnotatedTypeMirror;
46
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
57
import org.checkerframework.framework.type.visitor.AnnotatedTypeScanner;
@@ -26,14 +28,17 @@ public class InferenceQualifierPolymorphism {
2628
private final AnnotationMirror varAnnot;
2729
private final SlotManager slotManager;
2830
private final InferenceAnnotatedTypeFactory atypeFactory;
31+
private final BaseAnnotatedTypeFactory realTypeFactory;
2932

3033
public InferenceQualifierPolymorphism(final SlotManager slotManager,
3134
final VariableAnnotator variableAnnotator,
3235
final InferenceAnnotatedTypeFactory atypeFactory,
36+
final BaseAnnotatedTypeFactory realTypeFactory,
3337
final AnnotationMirror varAnnot) {
3438
this.slotManager = slotManager;
3539
this.variableAnnotator = variableAnnotator;
3640
this.atypeFactory = atypeFactory;
41+
this.realTypeFactory = realTypeFactory;
3742
this.varAnnot = varAnnot;
3843
}
3944

@@ -57,13 +62,13 @@ private class PolyReplacer extends AnnotatedTypeScanner<Void, Void> {
5762
/**
5863
* The variable slot created for this method call
5964
*/
60-
private SourceVariableSlot polyVar = null;
65+
private VariableSlot polyVar = null;
6166

6267
private PolyReplacer(Tree methodCall) {
6368
this.methodCall = methodCall;
6469
}
6570

66-
private SourceVariableSlot getOrCreatePolyVar() {
71+
private VariableSlot getOrCreatePolyVar() {
6772
if (polyVar == null) {
6873
polyVar = variableAnnotator.getOrCreatePolyVar(methodCall);
6974
}
@@ -80,7 +85,7 @@ public Void scan(AnnotatedTypeMirror type, Void v) {
8085
if (InferenceMain.isHackMode(slot == null)) {
8186
} else if (slot instanceof ConstantSlot) {
8287
AnnotationMirror constant = ((ConstantSlot) slot).getValue();
83-
if (atypeFactory.getQualifierHierarchy().isPolymorphicQualifier(constant)) {
88+
if (realTypeFactory.getQualifierHierarchy().isPolymorphicQualifier(constant)) {
8489
type.replaceAnnotation(slotManager.getAnnotation(getOrCreatePolyVar()));
8590
}
8691
}

src/checkers/inference/SlotManager.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ public interface SlotManager {
4646
*/
4747
SourceVariableSlot createSourceVariableSlot(AnnotationLocation location, TypeMirror type);
4848

49+
/**
50+
* Create new VariableSlot and return the reference to it if no VariableSlot
51+
* on this location exists. Otherwise return the reference to existing VariableSlot
52+
* on this location. Each location uniquely identifies a polymorphic instance.
53+
* For now, there's no dedicated slot for polymorphic instance, but we may add one
54+
* in the future.
55+
*
56+
* @param location
57+
* used to locate this variable in code
58+
* @return VariableSlot that corresponds to this location
59+
*/
60+
VariableSlot createPolymorphicInstanceSlot(AnnotationLocation location, TypeMirror type);
61+
4962
/**
5063
* Create new RefinementVariableSlot (as well as the refinement constraint if
5164
* possible) and return the reference to it if no RefinementVariableSlot on this

src/checkers/inference/VariableAnnotator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public class VariableAnnotator extends AnnotatedTypeScanner<Void,Tree> {
134134
* methodCall -> variable created to represent Poly qualifiers
135135
* See InferenceQualifierPolymorphism.
136136
*/
137-
private final Map<Tree, SourceVariableSlot> treeToPolyVar;
137+
private final Map<Tree, VariableSlot> treeToPolyVar;
138138

139139
// An instance of @VarAnnot
140140
private final AnnotationMirror varAnnot;
@@ -206,10 +206,10 @@ protected AnnotationLocation treeToLocation(Tree tree) {
206206
* one and return it, if we haven't created one for the given tree. see InferenceQualifierPolymorphism
207207
* @return The Variable representing PolymorphicQualifier for the given tree
208208
*/
209-
public SourceVariableSlot getOrCreatePolyVar(Tree tree) {
210-
SourceVariableSlot polyVar = treeToPolyVar.get(tree);
209+
public VariableSlot getOrCreatePolyVar(Tree tree) {
210+
VariableSlot polyVar = treeToPolyVar.get(tree);
211211
if (polyVar == null) {
212-
polyVar = slotManager.createSourceVariableSlot(treeToLocation(tree), TreeUtils.typeOf(tree));
212+
polyVar = slotManager.createPolymorphicInstanceSlot(treeToLocation(tree), TreeUtils.typeOf(tree));
213213
treeToPolyVar.put(tree, polyVar);
214214
}
215215

0 commit comments

Comments
 (0)