framework.src.org.checkerframework.framework.util.element.ClassTypeParamApplier 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 org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.javacutil.ErrorReporter;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.TargetType;
/**
* Applies the annotations present for a class type parameter onto an AnnotatedTypeVariable. See
* {@link TypeParamElementAnnotationApplier} for details.
*/
public class ClassTypeParamApplier extends TypeParamElementAnnotationApplier {
public static void apply(AnnotatedTypeVariable type, Element element, AnnotatedTypeFactory typeFactory) {
new ClassTypeParamApplier(type, element, typeFactory).extractAndApply();
}
/**
* @return true if element represents a type parameter for a class
*/
public static boolean accepts(final AnnotatedTypeMirror type, final Element element) {
return element.getKind() == ElementKind.TYPE_PARAMETER &&
element.getEnclosingElement() instanceof Symbol.ClassSymbol;
}
/**
* The class that holds the type parameter element
*/
private final Symbol.ClassSymbol enclosingClass;
ClassTypeParamApplier(AnnotatedTypeVariable type, Element element, AnnotatedTypeFactory typeFactory) {
super(type, element, typeFactory);
if (!( element.getEnclosingElement() instanceof Symbol.ClassSymbol )) {
ErrorReporter.errorAbort("TypeParameter not enclosed by class? Type( " + type + " ) " +
"Element ( " + element + " ) ");
}
enclosingClass = (Symbol.ClassSymbol) element.getEnclosingElement();
}
/**
* @return TargetType.CLASS_TYPE_PARAMETER
*/
@Override
protected TargetType lowerBoundTarget() {
return TargetType.CLASS_TYPE_PARAMETER;
}
/**
* @return TargetType.CLASS_TYPE_PARAMETER_BOUND
*/
@Override
protected TargetType upperBoundTarget() {
return TargetType.CLASS_TYPE_PARAMETER_BOUND;
}
/**
* @return the index of element in the type parameter list of its enclosing class
*/
@Override
public int getElementIndex() {
return enclosingClass.getTypeParameters().indexOf(element);
}
@Override
protected TargetType[] validTargets() {
return new TargetType[]{ TargetType.CLASS_EXTENDS };
}
/**
* @return the raw type attributes of the enclosing class
*/
@Override
protected Iterable getRawTypeAttributes() {
return enclosingClass.getRawTypeAttributes();
}
@Override
protected boolean isAccepted() {
return accepts(type, element);
}
}