framework.src.org.checkerframework.framework.type.DeclarationsIntoElements 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.type;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.TreeUtils;
import org.checkerframework.javacutil.TypeAnnotationUtils;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.util.List;
/**
* A helper class that puts the declaration annotations from a method declaration
* back into the corresponding Elements, so that they get stored in the bytecode
* by the compiler.
*
* This is similar to {@code TypesIntoElements} but for declaration annotations.
*
* This class deals with javac internals and liberally imports such classes.
*/
public class DeclarationsIntoElements {
/**
* The entry point.
*
* @param atypeFactory the type factory
* @param tree the ClassTree to process
*/
public static void store(ProcessingEnvironment env,
AnnotatedTypeFactory atypeFactory, ClassTree tree) {
for (Tree mem : tree.getMembers()) {
if (mem.getKind() == Tree.Kind.METHOD) {
storeMethod(env, atypeFactory, (MethodTree) mem);
}
}
}
/**
* Add inherited declaration annotations from overridden methods into
* the corresponding Elements so they are written into bytecode.
* @param env ProcessingEnvironment
* @param atypeFactory the type factory
* @param meth the MethodTree to add the annotations
*/
private static void storeMethod(ProcessingEnvironment env,
AnnotatedTypeFactory atypeFactory, MethodTree meth) {
ExecutableElement element = TreeUtils.elementFromDeclaration(meth);
MethodSymbol sym = (MethodSymbol) element;
java.util.List elementAnnos = element.getAnnotationMirrors();
Set declAnnotations = atypeFactory.getDeclAnnotations(sym);
List tcs = List.nil();
for (AnnotationMirror anno : declAnnotations) {
// Only add the annotation if it isn't in the Element already.
if (!AnnotationUtils.containsSame(elementAnnos, anno)) {
tcs = tcs.append(TypeAnnotationUtils.createCompoundFromAnnotationMirror(env, anno));
}
}
sym.appendAttributes(tcs);
}
}