forked from typetools/checker-framework-inference
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathInferenceQualifierDefaults.java
More file actions
81 lines (70 loc) · 3.38 KB
/
InferenceQualifierDefaults.java
File metadata and controls
81 lines (70 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package checkers.inference.util.defaults;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.util.defaults.Default;
import org.checkerframework.framework.util.defaults.QualifierDefaults;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;
import checkers.inference.InferenceMain;
import checkers.inference.SlotManager;
import checkers.inference.qual.VarAnnot;
/**
* Apply default qualifiers in inference mode.
*
* <p>In inference mode, unchecked bytecode needs default qualifiers. To build constraints, these
* default qualifiers should be VarAnnots. The super class {@code QualifierDefaults} would determine
* real qualifiers for each type use location, and this class would replace those real qualifiers by
* equivalent VarAnnots, and apply these VarAnnots as defaults to a given type only if this type has
* not been annotated with a VarAnnot.
*
* @see org.checkerframework.framework.util.defaults.QualifierDefaults
*/
public class InferenceQualifierDefaults extends QualifierDefaults {
private final SlotManager slotManager;
public InferenceQualifierDefaults(Elements elements, AnnotatedTypeFactory atypeFactory) {
super(elements, atypeFactory);
slotManager = InferenceMain.getInstance().getSlotManager();
}
@Override
protected DefaultApplierElement createDefaultApplierElement(
AnnotatedTypeFactory atypeFactory,
Element annotationScope,
AnnotatedTypeMirror type,
boolean applyToTypeVar) {
return new InferenceDefaultApplierElement(
atypeFactory, annotationScope, type, applyToTypeVar);
}
public class InferenceDefaultApplierElement extends DefaultApplierElement {
public InferenceDefaultApplierElement(
AnnotatedTypeFactory atypeFactory,
Element scope,
AnnotatedTypeMirror type,
boolean applyToTypeVar) {
super(atypeFactory, scope, type, applyToTypeVar);
}
/**
* Instead of applying the real qualifier stored in the given {@code def}, replacing it with
* the equivalent VarAnnot and apply the VarAnnot on the applied type.
*/
@Override
public void applyDefault(Default def) {
this.location = def.location;
// We replace the real qualifier with equivalent varAnnot
// here, instead of mutating the annotation stored in `def`.
// The reason is mutating the annotation stored in `def`
// also needs to adapt logic of initializing sets of default
// qualifiers for checked and unchecked code, which needs
// more code and makes this class complicated.
// Since this is just two line duplication logic with super method
// here, we decided to replace real qualifier here instead of
// mutating the annotation in `def`.
AnnotationMirror equivalentVarAnno = slotManager.createEquivalentVarAnno(def.anno);
impl.visit(type, equivalentVarAnno);
}
@Override
protected boolean shouldBeAnnotated(AnnotatedTypeMirror type) {
return super.shouldBeAnnotated(type) && !type.hasAnnotation(VarAnnot.class);
}
}
}