use of javax.lang.model.element.AnnotationMirror in project checker-framework by typetools.
the class DefaultTypeHierarchy method visitTypeArgs.
/**
* A helper class for visitDeclared_Declared. There are subtypes of DefaultTypeHierarchy that
* need to customize the handling of type arguments. This method provides a convenient extension
* point.
*/
public Boolean visitTypeArgs(final AnnotatedDeclaredType subtype, final AnnotatedDeclaredType supertype, final VisitHistory visited, final boolean subtypeRaw, final boolean supertypeRaw) {
final boolean ignoreTypeArgs = ignoreRawTypes && (subtypeRaw || supertypeRaw);
if (!ignoreTypeArgs) {
final List<? extends AnnotatedTypeMirror> subtypeTypeArgs = subtype.getTypeArguments();
final List<? extends AnnotatedTypeMirror> supertypeTypeArgs = supertype.getTypeArguments();
// TYPES SEMANTICS?
if (subtypeTypeArgs.isEmpty() || supertypeTypeArgs.isEmpty()) {
return true;
}
final TypeElement supertypeElem = (TypeElement) supertype.getUnderlyingType().asElement();
List<Integer> covariantArgIndexes = null;
AnnotationMirror covam = supertype.atypeFactory.getDeclAnnotation(supertypeElem, Covariant.class);
if (covam == null) {
// Using String instead of .class to prevent dependency.
try {
@SuppressWarnings({ "unchecked", "LiteralClassName" }) Class<? extends Annotation> nncov = (Class<? extends Annotation>) Class.forName("org.checkerframework.checker.nullness.qual.Covariant");
covam = supertype.atypeFactory.getDeclAnnotation(supertypeElem, nncov);
} catch (ClassNotFoundException ex) {
covam = null;
}
}
if (covam != null) {
covariantArgIndexes = AnnotationUtils.getElementValueArray(covam, "value", Integer.class, false);
}
for (int i = 0; i < supertypeTypeArgs.size(); i++) {
final AnnotatedTypeMirror superTypeArg = supertypeTypeArgs.get(i);
final AnnotatedTypeMirror subTypeArg = subtypeTypeArgs.get(i);
final boolean covariant = covariantArgIndexes != null && covariantArgIndexes.contains(i);
if (!compareTypeArgs(subTypeArg, superTypeArg, supertypeRaw, subtypeRaw, covariant, visited)) {
return false;
}
}
}
return true;
}
use of javax.lang.model.element.AnnotationMirror in project checker-framework by typetools.
the class BaseTypeVisitor method checkContractsSubset.
/**
* Checks that {@code mustSubset} is a subset of {@code set} in the following sense: For every
* expression in {@code mustSubset} there must be the same expression in {@code set}, with the
* same (or a stronger) annotation.
*/
private void checkContractsSubset(String overriderMeth, String overriderTyp, String overriddenMeth, String overriddenTyp, Set<Pair<Receiver, AnnotationMirror>> mustSubset, Set<Pair<Receiver, AnnotationMirror>> set, @CompilerMessageKey String messageKey) {
for (Pair<Receiver, AnnotationMirror> weak : mustSubset) {
boolean found = false;
for (Pair<Receiver, AnnotationMirror> strong : set) {
// are we looking at a contract of the same receiver?
if (weak.first.equals(strong.first)) {
// check subtyping relationship of annotations
QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
if (qualifierHierarchy.isSubtype(strong.second, weak.second)) {
found = true;
break;
}
}
}
if (!found) {
MethodTree method = visitorState.getMethodTree();
checker.report(Result.failure(messageKey, overriderMeth, overriderTyp, overriddenMeth, overriddenTyp, weak.second, weak.first), method);
}
}
}
use of javax.lang.model.element.AnnotationMirror in project checker-framework by typetools.
the class QualifierHierarchy method greatestLowerBoundsTypeVariable.
/**
* Returns the type qualifiers that are the greatest lower bound of the qualifiers in annos1 and
* annos2.
*
* <p>The two qualifiers have to be from the same qualifier hierarchy. Otherwise, null will be
* returned.
*
* <p>This method works even if the underlying Java type is a type variable. In that case, a
* 'null' AnnnotationMirror and the empty set represent a meaningful value (namely, no
* annotation).
*
* @param annos1 first collection of qualifiers
* @param annos2 second collection of qualifiers
* @return greatest lower bound of the two collections of qualifiers
*/
public Set<? extends AnnotationMirror> greatestLowerBoundsTypeVariable(Collection<? extends AnnotationMirror> annos1, Collection<? extends AnnotationMirror> annos2) {
Set<AnnotationMirror> result = AnnotationUtils.createAnnotationSet();
for (AnnotationMirror top : getTopAnnotations()) {
AnnotationMirror anno1ForTop = null;
for (AnnotationMirror anno1 : annos1) {
if (isSubtypeTypeVariable(anno1, top)) {
anno1ForTop = anno1;
}
}
AnnotationMirror anno2ForTop = null;
for (AnnotationMirror anno2 : annos2) {
if (isSubtypeTypeVariable(anno2, top)) {
anno2ForTop = anno2;
}
}
AnnotationMirror t = greatestLowerBoundTypeVariable(anno1ForTop, anno2ForTop);
if (t != null) {
result.add(t);
}
}
return result;
}
use of javax.lang.model.element.AnnotationMirror in project checker-framework by typetools.
the class ImplicitsTreeAnnotator method visitLiteral.
/**
* Go through the string patterns and add the greatest lower bound of all matching patterns.
*/
@Override
public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) {
if (!stringPatterns.isEmpty() && tree.getKind() == Kind.STRING_LITERAL) {
List<Set<? extends AnnotationMirror>> matches = new ArrayList<>();
List<Set<? extends AnnotationMirror>> nonMatches = new ArrayList<>();
String string = (String) tree.getValue();
for (Pattern pattern : stringPatterns.keySet()) {
Set<AnnotationMirror> sam = stringPatterns.get(pattern);
if (pattern.matcher(string).matches()) {
matches.add(sam);
} else {
nonMatches.add(sam);
}
}
Set<? extends AnnotationMirror> res = null;
if (!matches.isEmpty()) {
res = matches.get(0);
for (Set<? extends AnnotationMirror> sam : matches) {
res = qualHierarchy.greatestLowerBounds(res, sam);
}
// Verify that res is not a subtype of any type in nonMatches
for (Set<? extends AnnotationMirror> sam : nonMatches) {
if (qualHierarchy.isSubtype(res, sam)) {
ErrorReporter.errorAbort("Bug in @ImplicitFor(stringpatterns=...) in type hierarchy definition: inferred type for \"" + string + "\" is " + res + " which is a subtype of " + sam + " but its pattern does not match the string. matches = " + matches + "; nonMatches = " + nonMatches);
}
}
type.addAnnotations(res);
}
}
return super.visitLiteral(tree, type);
}
use of javax.lang.model.element.AnnotationMirror in project checker-framework by typetools.
the class ContractsUtils method getPrecondition.
/**
* Returns the set of preconditions according to the given {@link RequiresQualifier}.
*/
private Set<Precondition> getPrecondition(AnnotationMirror requiresAnnotation) {
if (requiresAnnotation == null) {
return Collections.emptySet();
}
Set<Precondition> result = new LinkedHashSet<>();
List<String> expressions = AnnotationUtils.getElementValueArray(requiresAnnotation, "expression", String.class, false);
AnnotationMirror postcondAnno = getAnnotationMirrorOfContractAnnotation(requiresAnnotation);
if (postcondAnno == null) {
return result;
}
for (String expr : expressions) {
result.add(new Precondition(expr, postcondAnno));
}
return result;
}
Aggregations