use of org.checkerframework.checker.signature.qual.CanonicalName in project checker-framework by typetools.
the class AnnotationUtils method getElementValueClassName.
/**
* Get the Name of the class that is referenced by element {@code elementName}.
*
* <p>This is a convenience method for the most common use-case. It is like {@code
* getElementValue(anno, elementName, ClassType.class).getQualifiedName()}, but this method
* ensures consistent use of the qualified name.
*
* <p>This method is intended only for use by the framework. A checker implementation should use
* {@code anno.getElementValues().get(someElement).getValue().asElement().getQualifiedName();}.
*
* @param anno the annotation to disassemble
* @param elementName the name of the element to access; it must be present in the annotation
* @param useDefaults whether to apply default values to the element
* @return the name of the class that is referenced by element with the given name; may be an
* empty name, for a local or anonymous class
* @deprecated use an ExecutableElement
*/
// permitted for use by the framework
@Deprecated
@CanonicalName
public static Name getElementValueClassName(AnnotationMirror anno, CharSequence elementName, boolean useDefaults) {
Type.ClassType ct = getElementValue(anno, elementName, Type.ClassType.class, useDefaults);
// TODO: Is it a problem that this returns the type parameters too? Should I cut them off?
@CanonicalName Name result = ct.asElement().getQualifiedName();
return result;
}
use of org.checkerframework.checker.signature.qual.CanonicalName in project checker-framework by typetools.
the class AnnotatedTypeFactory method getSupportedAnnotationsInElementAnnotation.
/**
* Returns a set of supported annotation mirrors corresponding to the annotation classes listed in
* the value element of an annotation with class {@code annoClass} on {@code element}.
*
* @param element the Element to check
* @param annoClass the class for an annotation that's written on elements, whose value element is
* a list of annotation classes. It is always HasQualifierParameter or NoQualifierParameter
* @param valueElement the {@code value} field/element of an annotation with class {@code
* annoClass}
* @return the set of supported annotations with classes listed in the value element of an
* annotation with class {@code annoClass} on the {@code element}. Returns an empty set if
* {@code annoClass} is not written on {@code element} or {@code element} is null.
*/
private Set<AnnotationMirror> getSupportedAnnotationsInElementAnnotation(@Nullable Element element, Class<? extends Annotation> annoClass, ExecutableElement valueElement) {
if (element == null) {
return Collections.emptySet();
}
// TODO: caching
AnnotationMirror annotation = getDeclAnnotation(element, annoClass);
if (annotation == null) {
return Collections.emptySet();
}
Set<AnnotationMirror> found = AnnotationUtils.createAnnotationSet();
List<@CanonicalName Name> qualClasses = AnnotationUtils.getElementValueClassNames(annotation, valueElement);
for (Name qual : qualClasses) {
AnnotationMirror annotationMirror = AnnotationBuilder.fromName(elements, qual);
if (isSupportedQualifier(annotationMirror)) {
found.add(annotationMirror);
}
}
return found;
}
use of org.checkerframework.checker.signature.qual.CanonicalName in project checker-framework by typetools.
the class AnnotatedTypeFactory method getFieldInvariants.
/**
* Returns the field invariants for the given class, as expressed by the user in {@link
* FieldInvariant @FieldInvariant} method annotations.
*
* <p>Subclasses may implement their own field invariant annotations if {@link
* FieldInvariant @FieldInvariant} is not expressive enough. They must override this method to
* properly create AnnotationMirror and also override {@link
* #getFieldInvariantDeclarationAnnotations()} to return their field invariants.
*
* @param element class for which to get invariants
* @return field invariants for {@code element}
*/
public FieldInvariants getFieldInvariants(TypeElement element) {
if (element == null) {
return null;
}
AnnotationMirror fieldInvarAnno = getDeclAnnotation(element, FieldInvariant.class);
if (fieldInvarAnno == null) {
return null;
}
List<String> fields = AnnotationUtils.getElementValueArray(fieldInvarAnno, fieldInvariantFieldElement, String.class);
List<@CanonicalName Name> classes = AnnotationUtils.getElementValueClassNames(fieldInvarAnno, fieldInvariantQualifierElement);
List<AnnotationMirror> qualifiers = CollectionsPlume.mapList((Name name) -> AnnotationBuilder.fromName(elements, name), classes);
if (qualifiers.size() == 1) {
while (fields.size() > qualifiers.size()) {
qualifiers.add(qualifiers.get(0));
}
}
if (fields.size() != qualifiers.size()) {
// FieldInvariants object. The BaseTypeVisitor will issue an error.
return new FieldInvariants(fields, qualifiers);
}
// Only keep qualifiers that are supported by this checker. (The other qualifiers cannot
// be checked by this checker, so they must be ignored.)
List<String> annotatedFields = new ArrayList<>();
List<AnnotationMirror> supportedQualifiers = new ArrayList<>();
for (int i = 0; i < fields.size(); i++) {
if (isSupportedQualifier(qualifiers.get(i))) {
annotatedFields.add(fields.get(i));
supportedQualifiers.add(qualifiers.get(i));
}
}
if (annotatedFields.isEmpty()) {
return null;
}
return new FieldInvariants(annotatedFields, supportedQualifiers);
}
use of org.checkerframework.checker.signature.qual.CanonicalName in project checker-framework by typetools.
the class UnitsAnnotatedTypeFactory method addUnitToExternalQualMap.
/**
* Adds the annotation class to the external qualifier map if it is not an alias annotation.
*/
private void addUnitToExternalQualMap(final Class<? extends Annotation> annoClass) {
AnnotationMirror mirror = UnitsRelationsTools.buildAnnoMirrorWithNoPrefix(processingEnv, annoClass.getCanonicalName());
// if it is not an aliased annotation, add to external quals map if it isn't already in map
if (!isAliasedAnnotation(mirror)) {
String unitClassName = annoClass.getCanonicalName();
if (!externalQualsMap.containsKey(unitClassName)) {
externalQualsMap.put(unitClassName, annoClass);
}
} else // if it is an aliased annotation
{
// ensure it has a base unit
@CanonicalName Name baseUnitClass = getBaseUnitAnno(mirror);
if (baseUnitClass != null) {
// if the base unit isn't already added, add that first
// https://tinyurl.com/cfissue/658
@SuppressWarnings("signature") @DotSeparatedIdentifiers String baseUnitClassName = baseUnitClass.toString();
if (!externalQualsMap.containsKey(baseUnitClassName)) {
loadExternalUnit(baseUnitClassName);
}
// then add the aliased annotation to the alias map
// TODO: refactor so we can directly add to alias map, skipping the assert check in
// canonicalAnnotation.
canonicalAnnotation(mirror);
} else {
// error: somehow the aliased annotation has @UnitsMultiple meta annotation, but no
// base class defined in that meta annotation
// TODO: error abort
}
}
// process the units annotation and add its corresponding units relations class
addUnitsRelations(annoClass);
}
use of org.checkerframework.checker.signature.qual.CanonicalName in project checker-framework by typetools.
the class AnnotationFileParser method getAnnotation.
/**
* Convert {@code annotation} into an AnnotationMirror. Returns null if the annotation isn't
* supported by the checker or if some error occurred while converting it.
*
* @param annotation syntax tree for an annotation
* @param allAnnotations map from simple name to annotation definition; side-effected by this
* method
* @return the AnnotationMirror for the annotation, or null if it cannot be built
*/
@Nullable
private AnnotationMirror getAnnotation(AnnotationExpr annotation, Map<String, TypeElement> allAnnotations) {
// https://tinyurl.com/cfissue/3094
@SuppressWarnings("signature") @FullyQualifiedName String annoNameFq = annotation.getNameAsString();
TypeElement annoTypeElt = allAnnotations.get(annoNameFq);
if (annoTypeElt == null) {
// If the annotation was not imported, then #getImportedAnnotations did not add it to the
// allAnnotations field. This code adds the annotation when it is encountered (i.e. here).
// Note that this does not call AnnotationFileParser#getTypeElement to avoid a spurious
// diagnostic if the annotation is actually unknown.
annoTypeElt = elements.getTypeElement(annoNameFq);
if (annoTypeElt == null) {
// Not a supported annotation -> ignore
return null;
}
putAllNew(allAnnotations, createNameToAnnotationMap(Collections.singletonList(annoTypeElt)));
}
// not anonymous, so name is not empty
@SuppressWarnings("signature") @CanonicalName String annoName = annoTypeElt.getQualifiedName().toString();
if (annotation instanceof MarkerAnnotationExpr) {
return AnnotationBuilder.fromName(elements, annoName);
} else if (annotation instanceof NormalAnnotationExpr) {
NormalAnnotationExpr nrmanno = (NormalAnnotationExpr) annotation;
AnnotationBuilder builder = new AnnotationBuilder(processingEnv, annoName);
List<MemberValuePair> pairs = nrmanno.getPairs();
if (pairs != null) {
for (MemberValuePair mvp : pairs) {
String member = mvp.getNameAsString();
Expression exp = mvp.getValue();
try {
builderAddElement(builder, member, exp);
} catch (AnnotationFileParserException e) {
warn(exp, "For annotation %s, could not add %s=%s because %s", annotation, member, exp, e.getMessage());
return null;
}
}
}
return builder.build();
} else if (annotation instanceof SingleMemberAnnotationExpr) {
SingleMemberAnnotationExpr sglanno = (SingleMemberAnnotationExpr) annotation;
AnnotationBuilder builder = new AnnotationBuilder(processingEnv, annoName);
Expression valExpr = sglanno.getMemberValue();
try {
builderAddElement(builder, "value", valExpr);
} catch (AnnotationFileParserException e) {
warn(valExpr, "For annotation %s, could not add value=%s because %s", annotation, valExpr, e.getMessage());
return null;
}
return builder.build();
} else {
throw new BugInCF("AnnotationFileParser: unknown annotation type: " + annotation);
}
}
Aggregations