mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-15 02:17:12 +00:00
Removed the ability of lombok to run as ecj annotation processor, because
it won't actually work right; method-level generics would break. The new way is to use -javaagent:lombok.jar=ECJ in addition to -cp lombok.jar
This commit is contained in:
1 parent
21cfb45696
commit
2d9195a229
4 files changed
+14
-199
No files matched your search
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
* Copyright © 2009-2011 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -129,30 +129,10 @@ public class AnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
@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);
|
||||
// Lombok used to work as annotation processor to ecj but that never actually worked properly, so we disabled the feature in 0.10.0.
|
||||
// Because loading lombok as an agent in any ECJ-based non-interactive tool works just fine, we're not going to generate any warnings, as we'll
|
||||
// likely generate more false positives than be helpful.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.eclipse.apt;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
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.TypeElement;
|
||||
|
||||
import lombok.Lombok;
|
||||
import lombok.eclipse.TransformEclipseAST;
|
||||
import lombok.eclipse.agent.PatchFixes;
|
||||
import lombok.patcher.inject.LiveInjector;
|
||||
|
||||
import org.eclipse.jdt.core.compiler.CharOperation;
|
||||
import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
|
||||
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
|
||||
import org.eclipse.jdt.internal.compiler.parser.Parser;
|
||||
import org.eclipse.jdt.internal.compiler.util.HashtableOfType;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class Processor extends AbstractProcessor {
|
||||
private BaseProcessingEnvImpl processingEnv;
|
||||
|
||||
@Override public synchronized void init(ProcessingEnvironment procEnv) {
|
||||
super.init(procEnv);
|
||||
|
||||
this.processingEnv = (BaseProcessingEnvImpl)procEnv;
|
||||
|
||||
if (eclipseNeedsPatching()) {
|
||||
new LiveInjector().injectSelf();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean eclipseNeedsPatching() {
|
||||
try {
|
||||
return Class.forName("org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration").getDeclaredField("$lombokAST") == null;
|
||||
} catch (Exception ignore) {
|
||||
//I guess it isn't there, then.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
CompilationUnitDeclaration[] roots = (CompilationUnitDeclaration[]) fieldAccess(roundEnv, "_units");
|
||||
|
||||
if (roots == null) return false;
|
||||
for (CompilationUnitDeclaration cud : roots) {
|
||||
//ECJ, like eclipse, first 'diet parses' - parsing only structure and not method bodies, and then later parses method bodies.
|
||||
//On eclipse, we instrument both runs, but on ECJ, instrumenting is rather limited, and unless you get major errors or use -proc:none,
|
||||
//full parsing is inevitable, so we just get it over with up front, so we can lombokize everything in one go instead of in 2 phases.
|
||||
fullParseType(processingEnv.getCompiler().parser, cud, cud.types);
|
||||
TransformEclipseAST.transform(null, cud);
|
||||
}
|
||||
|
||||
Map<PackageBinding, List<char[]>> packageToTypeNames = new HashMap<PackageBinding, List<char[]>>();
|
||||
|
||||
for (CompilationUnitDeclaration cud : roots) {
|
||||
addToClearTracker(packageToTypeNames, new char[0], cud.scope.fPackage, cud.types);
|
||||
}
|
||||
|
||||
for (Map.Entry<PackageBinding, List<char[]>> e : packageToTypeNames.entrySet()) {
|
||||
if (e.getValue().isEmpty()) continue;
|
||||
HashtableOfType knownTypes = (HashtableOfType) fieldAccess(e.getKey(), "knownTypes");
|
||||
for (int i = 0; i < knownTypes.keyTable.length; i++) {
|
||||
if (knownTypes.keyTable[i] == null) continue;
|
||||
for (char[] toClear : e.getValue()) {
|
||||
if (CharOperation.equals(knownTypes.keyTable[i], toClear)) knownTypes.keyTable[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
methodInvoke(knownTypes, "rehash");
|
||||
}
|
||||
|
||||
for (CompilationUnitDeclaration cud : roots) {
|
||||
cud.scope = null;
|
||||
cud.types[0].binding = null;
|
||||
cud.types[0].scope = null;
|
||||
processingEnv.getLookupEnvironment().buildTypeBindings(cud, null);
|
||||
}
|
||||
|
||||
processingEnv.getLookupEnvironment().completeTypeBindings();
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void fullParseType(Parser parser, CompilationUnitDeclaration cud, TypeDeclaration[] typeDecls) {
|
||||
if (typeDecls == null) return;
|
||||
for (TypeDeclaration typeDecl : typeDecls) {
|
||||
for (AbstractMethodDeclaration methodDecl : typeDecl.methods) {
|
||||
methodDecl.parseStatements(parser, cud);
|
||||
methodDecl.bits |= PatchFixes.ALREADY_PROCESSED_FLAG;
|
||||
}
|
||||
fullParseType(parser, cud, typeDecl.memberTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToClearTracker(Map<PackageBinding, List<char[]>> packageToTypeNames, char[] prefix, PackageBinding packageBinding, TypeDeclaration[] typeDecls) {
|
||||
if (typeDecls == null) return;
|
||||
List<char[]> names = packageToTypeNames.get(packageBinding);
|
||||
if (names == null) {
|
||||
names = new ArrayList<char[]>();
|
||||
packageToTypeNames.put(packageBinding, names);
|
||||
}
|
||||
for (TypeDeclaration typeDecl : typeDecls) {
|
||||
char[] name;
|
||||
if (prefix.length == 0) name = typeDecl.name;
|
||||
else {
|
||||
name = Arrays.copyOf(prefix, prefix.length + typeDecl.name.length);
|
||||
System.arraycopy(typeDecl.name, 0, name, prefix.length, typeDecl.name.length);
|
||||
}
|
||||
names.add(name);
|
||||
if (typeDecl.memberTypes != null && typeDecl.memberTypes.length > 0) {
|
||||
char[] newPrefix = Arrays.copyOf(name, name.length +1);
|
||||
newPrefix[newPrefix.length-1] = '$';
|
||||
addToClearTracker(packageToTypeNames, newPrefix, packageBinding, typeDecl.memberTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void methodInvoke(Object object, String methodName) {
|
||||
try {
|
||||
Method m = object.getClass().getDeclaredMethod(methodName);
|
||||
m.setAccessible(true);
|
||||
m.invoke(object);
|
||||
} catch (Exception e) {
|
||||
throw Lombok.sneakyThrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object fieldAccess(Object object, String fieldName) {
|
||||
try {
|
||||
Field f = object.getClass().getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
return f.get(object);
|
||||
} catch (Exception e) {
|
||||
throw Lombok.sneakyThrow(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,6 +518,10 @@ public class EclipseHandlerUtil {
|
||||
report = false;
|
||||
break;
|
||||
}
|
||||
if ("lombok.core.AnnotationProcessor".equals(elem.getClassName())) {
|
||||
report = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (report) {
|
||||
|
||||
@@ -28,7 +28,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.core.AST.Kind;
|
||||
@@ -159,6 +161,9 @@ public class PatchDelegate {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<ASTNode, Object> alreadyApplied = new IdentityHashMap<ASTNode, Object>();
|
||||
private static final Object MARKER = new Object();
|
||||
|
||||
private static void fillMethodBindings(CompilationUnitDeclaration cud, ClassScope scope, List<BindingTuple> methodsToDelegate) {
|
||||
TypeDeclaration decl = scope.referenceContext;
|
||||
if (decl == null) return;
|
||||
@@ -170,6 +175,7 @@ public class PatchDelegate {
|
||||
TypeBinding tb = ann.type.resolveType(decl.initializerScope);
|
||||
if (!charArrayEquals("lombok", tb.qualifiedPackageName())) continue;
|
||||
if (!charArrayEquals("Delegate", tb.qualifiedSourceName())) continue;
|
||||
if (alreadyApplied.put(ann, MARKER) == MARKER) continue;
|
||||
|
||||
List<ClassLiteralAccess> rawTypes = new ArrayList<ClassLiteralAccess>();
|
||||
List<ClassLiteralAccess> excludedRawTypes = new ArrayList<ClassLiteralAccess>();
|
||||
|
||||
Reference in new issue
Block a user