mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 22:17:41 +00:00
generalized the annotation processor that lombok.jar represents into a main class that farms out the work to a specific implementation depending on environment; previously lombok.jar's annotation processor was javac specific.
This commit is contained in:
1 parent
f57e23bebb
commit
55bed99c90
2 files changed
+147
-31
No files matched your search
@@ -0,0 +1,144 @@
|
||||
package lombok.core;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class AnnotationProcessor extends AbstractProcessor {
|
||||
private static String trace(Throwable t) {
|
||||
StringWriter w = new StringWriter();
|
||||
t.printStackTrace(new PrintWriter(w, true));
|
||||
return w.toString();
|
||||
}
|
||||
|
||||
static abstract class ProcessorDescriptor {
|
||||
abstract boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings);
|
||||
abstract String getName();
|
||||
abstract boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv);
|
||||
}
|
||||
|
||||
private final List<ProcessorDescriptor> registered = Arrays.asList(new JavacDescriptor(), new EcjDescriptor());
|
||||
private final List<ProcessorDescriptor> active = new ArrayList<ProcessorDescriptor>();
|
||||
private final List<String> delayedWarnings = new ArrayList<String>();
|
||||
|
||||
static class JavacDescriptor extends ProcessorDescriptor {
|
||||
private Processor processor;
|
||||
|
||||
@Override String getName() {
|
||||
return "sun/apple javac 1.6";
|
||||
}
|
||||
|
||||
@Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
|
||||
if (!procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) return false;
|
||||
|
||||
try {
|
||||
processor = (Processor)Class.forName("lombok.javac.apt.Processor").newInstance();
|
||||
} catch (Exception e) {
|
||||
delayedWarnings.add("You found a bug in lombok; lombok.javac.apt.Processor is not available. Lombok will not run during this compilation: " + trace(e));
|
||||
return false;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
delayedWarnings.add("Can't load javac processor due to (most likely) a class loader problem: " + trace(e));
|
||||
return false;
|
||||
}
|
||||
|
||||
processor.init(procEnv);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
return processor.process(annotations, roundEnv);
|
||||
}
|
||||
}
|
||||
|
||||
static class EcjDescriptor extends ProcessorDescriptor {
|
||||
private Processor processor;
|
||||
|
||||
@Override String getName() {
|
||||
return "ECJ";
|
||||
}
|
||||
|
||||
@Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
|
||||
if (!procEnv.getClass().getName().startsWith("org.eclipse.jdt.")) return false;
|
||||
boolean inEclipse;
|
||||
try {
|
||||
Class.forName("org.eclipse.core.runtime.Platform"); //if this works, we're in eclipse.
|
||||
inEclipse = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
inEclipse = false; //We're in ecj.
|
||||
}
|
||||
|
||||
if (inEclipse) {
|
||||
delayedWarnings.add("You should not install lombok.jar as an annotation processor in eclipse. Instead, run lombok.jar as a java application and follow the instructions.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
processor = (Processor)Class.forName("lombok.eclipse.apt.Processor").newInstance();
|
||||
} catch (Exception e) {
|
||||
delayedWarnings.add("You found a bug in lombok; lombok.eclipse.apt.Processor is not available. Lombok will not run during this compilation: " + trace(e));
|
||||
return false;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
delayedWarnings.add("Can't load eclipse processor due to (most likely) a class loader problem: " + trace(e));
|
||||
return false;
|
||||
}
|
||||
|
||||
processor.init(procEnv);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
return processor.process(annotations, roundEnv);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void init(ProcessingEnvironment procEnv) {
|
||||
super.init(procEnv);
|
||||
for (ProcessorDescriptor proc : registered) {
|
||||
if (proc.want(procEnv, delayedWarnings)) active.add(proc);
|
||||
}
|
||||
|
||||
if (active.isEmpty() && delayedWarnings.isEmpty()) {
|
||||
StringBuilder supported = new StringBuilder();
|
||||
for (ProcessorDescriptor proc : registered) {
|
||||
if (supported.length() > 0) supported.append(", ");
|
||||
supported.append(proc.getName());
|
||||
}
|
||||
procEnv.getMessager().printMessage(Kind.WARNING, String.format("You aren't using a compiler supported by lombok, so lombok will not work and has been disabled.\n" +
|
||||
"Your processor is: %s\nLombok supports: %s", procEnv.getClass().getName(), supported));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (!delayedWarnings.isEmpty()) {
|
||||
Set<? extends Element> rootElements = roundEnv.getRootElements();
|
||||
if (!rootElements.isEmpty()) {
|
||||
Element firstRoot = rootElements.iterator().next();
|
||||
for (String warning : delayedWarnings) processingEnv.getMessager().printMessage(Kind.WARNING, warning, firstRoot);
|
||||
delayedWarnings.clear();
|
||||
}
|
||||
}
|
||||
|
||||
boolean handled = false;
|
||||
for (ProcessorDescriptor proc : active) {
|
||||
handled |= proc.process(annotations, roundEnv);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
import lombok.javac.JavacTransformer;
|
||||
|
||||
@@ -55,47 +54,20 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class Processor extends AbstractProcessor {
|
||||
private ProcessingEnvironment rawProcessingEnv;
|
||||
private JavacProcessingEnvironment processingEnv;
|
||||
private JavacTransformer transformer;
|
||||
private Trees trees;
|
||||
private String errorToShow;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void init(ProcessingEnvironment procEnv) {
|
||||
super.init(procEnv);
|
||||
this.rawProcessingEnv = procEnv;
|
||||
String className = procEnv.getClass().getName();
|
||||
if (className.startsWith("org.eclipse.jdt.")) {
|
||||
errorToShow = "You should not install lombok.jar as an annotation processor in eclipse. Instead, run lombok.jar as a java application and follow the instructions.";
|
||||
procEnv.getMessager().printMessage(Kind.WARNING, errorToShow);
|
||||
this.processingEnv = null;
|
||||
} else if (!procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) {
|
||||
procEnv.getMessager().printMessage(Kind.WARNING, "You aren't using a compiler based around javac v1.6, so lombok will not work properly.\n" +
|
||||
"Your processor class is: " + className);
|
||||
this.processingEnv = null;
|
||||
this.errorToShow = null;
|
||||
} else {
|
||||
this.processingEnv = (JavacProcessingEnvironment) procEnv;
|
||||
transformer = new JavacTransformer(procEnv.getMessager());
|
||||
trees = Trees.instance(procEnv);
|
||||
this.errorToShow = null;
|
||||
}
|
||||
this.processingEnv = (JavacProcessingEnvironment) procEnv;
|
||||
transformer = new JavacTransformer(procEnv.getMessager());
|
||||
trees = Trees.instance(procEnv);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (processingEnv == null) {
|
||||
if (errorToShow != null) {
|
||||
Set<? extends Element> rootElements = roundEnv.getRootElements();
|
||||
if (!rootElements.isEmpty()) {
|
||||
rawProcessingEnv.getMessager().printMessage(Kind.WARNING, errorToShow, rootElements.iterator().next());
|
||||
errorToShow = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IdentityHashMap<JCCompilationUnit, Void> units = new IdentityHashMap<JCCompilationUnit, Void>();
|
||||
for (Element element : roundEnv.getRootElements()) {
|
||||
JCCompilationUnit unit = toUnit(element);
|
||||
|
||||
Reference in new issue
Block a user