framework.src.org.checkerframework.framework.util.element.TypeDeclarationApplier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checker Show documentation
Show all versions of checker Show documentation
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.
package org.checkerframework.framework.util.element;
import static com.sun.tools.javac.code.TargetType.CAST;
import static com.sun.tools.javac.code.TargetType.CLASS_EXTENDS;
import static com.sun.tools.javac.code.TargetType.CLASS_TYPE_PARAMETER;
import static com.sun.tools.javac.code.TargetType.CLASS_TYPE_PARAMETER_BOUND;
import static com.sun.tools.javac.code.TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
import static com.sun.tools.javac.code.TargetType.CONSTRUCTOR_REFERENCE;
import static com.sun.tools.javac.code.TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
import static com.sun.tools.javac.code.TargetType.EXCEPTION_PARAMETER;
import static com.sun.tools.javac.code.TargetType.INSTANCEOF;
import static com.sun.tools.javac.code.TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
import static com.sun.tools.javac.code.TargetType.METHOD_REFERENCE;
import static com.sun.tools.javac.code.TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
import static com.sun.tools.javac.code.TargetType.NEW;
import static com.sun.tools.javac.code.TargetType.RESOURCE_VARIABLE;
import static org.checkerframework.framework.util.element.ElementAnnotationUtil.applyAllElementAnnotations;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import java.util.List;
import javax.lang.model.element.Element;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.TargetType;
/**
* Apply annotations to a declared type based on its declaration.
*/
public class TypeDeclarationApplier extends TargetedElementAnnotationApplier {
public static void apply(final AnnotatedTypeMirror type, final Element element, final AnnotatedTypeFactory typeFactory) {
new TypeDeclarationApplier(type, element, typeFactory).extractAndApply();
}
/**
* If a type_index == -1 it means that the index refers to the immediate supertype class
* of the declaration. There is only ever one of these since java has no multiple inheritance
*/
public static int SUPERCLASS_INDEX = -1;
/**
* @return true if type is an annotated declared type and element is a ClassSymbol
*/
public static boolean accepts(final AnnotatedTypeMirror type, final Element element) {
return type instanceof AnnotatedDeclaredType &&
element instanceof Symbol.ClassSymbol;
}
private final AnnotatedTypeFactory typeFactory;
private final Symbol.ClassSymbol typeSymbol;
private final AnnotatedDeclaredType declaredType;
TypeDeclarationApplier(final AnnotatedTypeMirror type, final Element element, final AnnotatedTypeFactory typeFactory) {
super(type, element);
this.typeFactory = typeFactory;
this.typeSymbol = (Symbol.ClassSymbol) element;
this.declaredType = (AnnotatedDeclaredType) type;
}
@Override
protected TargetType[] validTargets() {
return new TargetType[]{
RESOURCE_VARIABLE, EXCEPTION_PARAMETER, NEW, CAST, INSTANCEOF, METHOD_INVOCATION_TYPE_ARGUMENT,
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, METHOD_REFERENCE, CONSTRUCTOR_REFERENCE,
METHOD_REFERENCE_TYPE_ARGUMENT, CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
CLASS_TYPE_PARAMETER, CLASS_TYPE_PARAMETER_BOUND
};
}
@Override
protected TargetType[] annotatedTargets() {
return new TargetType[]{ CLASS_EXTENDS };
}
/**
* All TypeCompounds (annotations) on the ClassSymbol
*/
@Override
protected Iterable getRawTypeAttributes() {
return typeSymbol.getRawTypeAttributes();
}
/**
* While more than just annotations on extends or implements clause are annotated by this
* class, only these annotations are passed to handleTargeted (as they are the only in the annotatedTargets
* list). See extractAndApply for type parameters
* @param extendsAndImplementsAnnos annotations with a TargetType of CLASS_EXTENDS
*/
@Override
protected void handleTargeted(List extendsAndImplementsAnnos ) {
for (final Attribute.TypeCompound anno : extendsAndImplementsAnnos) {
if (anno.position.type_index >= SUPERCLASS_INDEX && anno.position.location.isEmpty()) {
type.addAnnotation(anno);
}
}
}
/**
* Adds extends/implements and class annotations to type. Annotates type parameters.
*/
@Override
public void extractAndApply() {
// ensures that we check that there only valid target types on this class, there are no "targeted" locations
super.extractAndApply();
// Annotate raw types //TODO: ASK WERNER WHAT THIS MIGHT MEAN? WHAT ACTUALLY GOES HERE?
type.addAnnotations(typeSymbol.getAnnotationMirrors());
applyAllElementAnnotations(declaredType.getTypeArguments(), typeSymbol.getTypeParameters(), typeFactory);
}
@Override
protected boolean isAccepted() {
return accepts(type, element);
}
}