package checkers.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import checkers.source.SourceChecker;
import com.sun.source.util.AbstractTypeProcessor;
import com.sun.source.util.TreePath;
/**
* An aggregate checker that packages multiple checkers together. The
* resulting checker invokes the individual checkers together on the processed
* files.
*
* This class delegates {@code AbstractTypeProcessor} responsibilities to each
* of the checkers.
*
* Checker writers need to subclass this class and only override
* {@link #getSupportedCheckers()} to indicate the classes of the checkers
* to be bundled.
*/
public abstract class AggregateChecker extends AbstractTypeProcessor {
List<SourceChecker> checkers;
/**
* Returns the list of supported checkers to be run together.
* Subclasses need to override this method.
*/
protected abstract Collection<Class<? extends SourceChecker>> getSupportedCheckers();
public AggregateChecker() {
Collection<Class<? extends SourceChecker>> checkerClasses = getSupportedCheckers();
checkers = new ArrayList<SourceChecker>(checkerClasses.size());
for (Class<? extends SourceChecker> checkerClass : checkerClasses) {
try {
SourceChecker instance = checkerClass.newInstance();
checkers.add(instance);
} catch (Exception e) {
System.err.println("Couldn't instantiate an instance of " + checkerClass);
}
}
}
// AbstractTypeProcessor delegation
@Override
public final void typeProcess(TypeElement element, TreePath tree) {
for (SourceChecker checker : checkers) {
checker.typeProcess(element, tree);
}
}
@Override
public void typeProcessingOver() {
for (SourceChecker checker : checkers) {
checker.typeProcessingOver();
}
}
// Processor method delegation and implementation
@Override
public final void init(ProcessingEnvironment env) {
super.init(env);
for (SourceChecker checker : checkers) {
checker.init(env);
}
}
@Override
public final Set<String> getSupportedOptions() {
Set<String> options = new HashSet<String>();
for (SourceChecker checker : checkers) {
options.addAll(checker.getSupportedOptions());
}
return options;
}
@Override
public final Set<String> getSupportedAnnotationTypes() {
return Collections.singleton("*");
}
@Override
public final SourceVersion getSupportedSourceVersion() {
try {
return SourceVersion.RELEASE_7;
} catch (NoSuchFieldError e) {
// Running in JDK 6
return SourceVersion.latest();
}
}
}