All Downloads are FREE. Search and download functionalities are using the official Maven repository.

framework.src.org.checkerframework.framework.type.typeannotator.ImplicitsTypeAnnotator Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java’s type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.42.0
Show newest version
package org.checkerframework.framework.type.typeannotator;

import org.checkerframework.framework.qual.ImplicitFor;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.ErrorReporter;
import org.checkerframework.javacutil.TypesUtils;

import java.lang.annotation.Annotation;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;

import com.sun.source.tree.Tree;

/**
 * Adds annotations to a type based on the contents of a type. By default, this
 * class honors the {@link ImplicitFor} annotation and applies implicit
 * annotations specified by {@link ImplicitFor} for any type whose visitor is
 * not overridden or does not call {@code super}; it is designed to be invoked
 * from
 * {@link org.checkerframework.framework.type.AnnotatedTypeFactory#addComputedTypeAnnotations(Element, org.checkerframework.framework.type.AnnotatedTypeMirror)}
 * and
 * {@link org.checkerframework.framework.type.AnnotatedTypeFactory#addComputedTypeAnnotations(Tree, org.checkerframework.framework.type.AnnotatedTypeMirror)}.
 *
 * 

* * {@link ImplicitsTypeAnnotator} traverses types deeply by default, except that it skips * the method receiver of executable types (for interoperability with * {@link org.checkerframework.framework.type.AnnotatedTypeFactory#annotateInheritedFromClass(org.checkerframework.framework.type.AnnotatedTypeMirror)}). * * This class takes care of two of the attributes of {@link ImplicitFor}; * the others are handled in {@link org.checkerframework.framework.type.treeannotator.TreeAnnotator}. * * @see org.checkerframework.framework.type.treeannotator.TreeAnnotator */ public class ImplicitsTypeAnnotator extends TypeAnnotator { private final Map> typeKinds; private final Map, Set> typeClasses; private final Map> typeNames; private final QualifierHierarchy qualHierarchy; // private final AnnotatedTypeFactory atypeFactory; /** * Creates a {@link ImplicitsTypeAnnotator} from the given checker, using * that checker to determine the annotations that are in the type hierarchy. */ public ImplicitsTypeAnnotator(AnnotatedTypeFactory typeFactory) { super(typeFactory); this.typeKinds = new EnumMap>(TypeKind.class); this.typeClasses = new HashMap, Set>(); this.typeNames = new IdentityHashMap>(); this.qualHierarchy = typeFactory.getQualifierHierarchy(); // this.atypeFactory = atypeFactory; // Get type qualifiers from the checker. Set> quals = typeFactory.getSupportedTypeQualifiers(); // For each qualifier, read the @ImplicitFor annotation and put its type // classes and kinds into maps. for (Class qual : quals) { ImplicitFor implicit = qual.getAnnotation(ImplicitFor.class); if (implicit == null) continue; AnnotationMirror theQual = AnnotationUtils.fromClass(typeFactory.getElementUtils(), qual); for (TypeKind typeKind : implicit.types()) { addTypeKind(typeKind, theQual); } for (Class typeName : implicit.typeNames()) { addTypeName(typeName, theQual); } } } public void addTypeKind(TypeKind typeKind, AnnotationMirror theQual) { boolean res = qualHierarchy.updateMappingToMutableSet(typeKinds, typeKind, theQual); if (!res) { ErrorReporter.errorAbort("TypeAnnotator: invalid update of typeKinds " + typeKinds + " at " + typeKind + " with " + theQual); } } public void addTypeClass(Class typeClass, AnnotationMirror theQual) { boolean res = qualHierarchy.updateMappingToMutableSet(typeClasses, typeClass, theQual); if (!res) { ErrorReporter.errorAbort("TypeAnnotator: invalid update of typeClasses " + typeClasses + " at " + typeClass + " with " + theQual); } } public void addTypeName(Class typeName, AnnotationMirror theQual) { String typeNameString = typeName.getCanonicalName().intern(); boolean res = qualHierarchy.updateMappingToMutableSet(typeNames, typeNameString, theQual); if (!res) { ErrorReporter.errorAbort("TypeAnnotator: invalid update of typeNames " + typeNames + " at " + typeName + " with " + theQual); } } @Override protected Void scan(AnnotatedTypeMirror type, Void p) { if (type == null) // on bounds, etc. return super.scan(type, p); // If the type's fully-qualified name is in the appropriate map, annotate // the type. Do this before looking at kind or class, as this information // is more specific. String qname = null; if (type.getKind() == TypeKind.DECLARED) { qname = TypesUtils.getQualifiedName((DeclaredType)type.getUnderlyingType()).toString(); } else if (type.getKind().isPrimitive()) { qname = type.getUnderlyingType().toString(); } qname = (qname == null) ? null : qname.intern(); if (qname != null && typeNames.containsKey(qname)) { Set fnd = typeNames.get(qname); type.addMissingAnnotations(fnd); } // If the type's kind or class is in the appropriate map, annotate the // type. if (typeKinds.containsKey(type.getKind())) { Set fnd = typeKinds.get(type.getKind()); type.addMissingAnnotations(fnd); } else if (!typeClasses.isEmpty()) { Class t = type.getClass(); if (typeClasses.containsKey(t)) { Set fnd = typeClasses.get(t); type.addMissingAnnotations(fnd); } } return super.scan(type, p); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy