Search in sources :

Example 1 with CanonicalName

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;
}
Also used : DeclaredType(javax.lang.model.type.DeclaredType) ElementType(java.lang.annotation.ElementType) Type(com.sun.tools.javac.code.Type) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) BinaryName(org.checkerframework.checker.signature.qual.BinaryName) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) Name(javax.lang.model.element.Name) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName)

Example 2 with CanonicalName

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;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) FullyQualifiedName(org.checkerframework.checker.signature.qual.FullyQualifiedName) Name(javax.lang.model.element.Name)

Example 3 with CanonicalName

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);
}
Also used : FieldInvariants(org.checkerframework.framework.util.FieldInvariants) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayList(java.util.ArrayList) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) FullyQualifiedName(org.checkerframework.checker.signature.qual.FullyQualifiedName) Name(javax.lang.model.element.Name)

Example 4 with CanonicalName

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);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) BinaryName(org.checkerframework.checker.signature.qual.BinaryName) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) Name(javax.lang.model.element.Name) DotSeparatedIdentifiers(org.checkerframework.checker.signature.qual.DotSeparatedIdentifiers)

Example 5 with CanonicalName

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);
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) FullyQualifiedName(org.checkerframework.checker.signature.qual.FullyQualifiedName) MarkerAnnotationExpr(com.github.javaparser.ast.expr.MarkerAnnotationExpr) BugInCF(org.checkerframework.javacutil.BugInCF) SingleMemberAnnotationExpr(com.github.javaparser.ast.expr.SingleMemberAnnotationExpr) MemberValuePair(com.github.javaparser.ast.expr.MemberValuePair) AnnotationBuilder(org.checkerframework.javacutil.AnnotationBuilder) Expression(com.github.javaparser.ast.expr.Expression) ArrayList(java.util.ArrayList) NodeList(com.github.javaparser.ast.NodeList) List(java.util.List) NormalAnnotationExpr(com.github.javaparser.ast.expr.NormalAnnotationExpr) CanonicalName(org.checkerframework.checker.signature.qual.CanonicalName) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Aggregations

CanonicalName (org.checkerframework.checker.signature.qual.CanonicalName)8 Name (javax.lang.model.element.Name)5 AnnotationMirror (javax.lang.model.element.AnnotationMirror)3 TypeElement (javax.lang.model.element.TypeElement)3 DeclaredType (javax.lang.model.type.DeclaredType)3 BinaryName (org.checkerframework.checker.signature.qual.BinaryName)3 FullyQualifiedName (org.checkerframework.checker.signature.qual.FullyQualifiedName)3 Type (com.sun.tools.javac.code.Type)2 ElementType (java.lang.annotation.ElementType)2 ArrayList (java.util.ArrayList)2 NodeList (com.github.javaparser.ast.NodeList)1 Expression (com.github.javaparser.ast.expr.Expression)1 MarkerAnnotationExpr (com.github.javaparser.ast.expr.MarkerAnnotationExpr)1 MemberValuePair (com.github.javaparser.ast.expr.MemberValuePair)1 NormalAnnotationExpr (com.github.javaparser.ast.expr.NormalAnnotationExpr)1 SingleMemberAnnotationExpr (com.github.javaparser.ast.expr.SingleMemberAnnotationExpr)1 List (java.util.List)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 DotSeparatedIdentifiers (org.checkerframework.checker.signature.qual.DotSeparatedIdentifiers)1 FieldInvariants (org.checkerframework.framework.util.FieldInvariants)1