aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/handlers/JavacHandlerUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac/handlers/JavacHandlerUtil.java')
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java190
1 files changed, 119 insertions, 71 deletions
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 32eae4e9..fba13133 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -37,19 +37,19 @@ import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
-import javax.lang.model.element.Element;
-
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
-import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Enter;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.MemberEnter;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
@@ -1010,12 +1010,6 @@ public class JavacHandlerUtil {
return call;
}
- public static Type getMirrorForFieldType(JavacNode fieldNode) {
- Element fieldElement = fieldNode.getElement();
- if (fieldElement instanceof VarSymbol) return ((VarSymbol) fieldElement).type;
- return null;
- }
-
/**
* Adds the given new field declaration to the provided type AST Node.
* The field carries the @{@link SuppressWarnings}("all") annotation.
@@ -1071,6 +1065,8 @@ public class JavacHandlerUtil {
insertAfter.tail = fieldEntry;
}
+ EnterReflect.memberEnter(field, typeNode);
+
return typeNode.add(field, Kind.FIELD);
}
@@ -1148,19 +1144,30 @@ public class JavacHandlerUtil {
}
static class JCAnnotationReflect {
- private static Field ATTRIBUTE;
-
+ private static final Field ATTRIBUTE;
+
static {
- try {
- ATTRIBUTE = Permit.getField(JCAnnotation.class, "attribute");
- } catch (Exception ignore) {}
+ ATTRIBUTE = Permit.permissiveGetField(JCAnnotation.class, "attribute");
}
static Attribute.Compound getAttribute(JCAnnotation jcAnnotation) {
- try {
- return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation);
- } catch (Exception e) {
- return null;
+ if (ATTRIBUTE != null) {
+ try {
+ return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation);
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+
+ static void setAttribute(JCAnnotation jcAnnotation, Attribute.Compound attribute) {
+ if (ATTRIBUTE != null) {
+ try {
+ Permit.set(ATTRIBUTE, jcAnnotation, attribute);
+ } catch (Exception e) {
+ // Ignore
+ }
}
}
}
@@ -1204,8 +1211,10 @@ public class JavacHandlerUtil {
}
}
- public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
- injectMethod(typeNode, method, null, null);
+
+ @Deprecated
+ public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List<Type> paramTypes, Type returnType) {
+ injectMethod(typeNode, method);
}
/**
@@ -1214,9 +1223,7 @@ public class JavacHandlerUtil {
*
* Also takes care of updating the JavacAST.
*/
- public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List<Type> paramTypes, Type returnType) {
- Context context = typeNode.getContext();
- Symtab symtab = Symtab.instance(context);
+ public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
JCClassDecl type = (JCClassDecl) typeNode.get();
if (method.getName().contentEquals("<init>")) {
@@ -1240,55 +1247,11 @@ public class JavacHandlerUtil {
addGenerated(method.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(method)), typeNode.getContext());
type.defs = type.defs.append(method);
- List<Symbol.VarSymbol> params = null;
- if (method.getParameters() != null && !method.getParameters().isEmpty()) {
- ListBuffer<Symbol.VarSymbol> newParams = new ListBuffer<Symbol.VarSymbol>();
- for (int i = 0; i < method.getParameters().size(); i++) {
- JCTree.JCVariableDecl param = method.getParameters().get(i);
- if (param.sym == null) {
- Type paramType = paramTypes == null ? param.getType().type : paramTypes.get(i);
- VarSymbol varSymbol = new VarSymbol(param.mods.flags, param.name, paramType, symtab.noSymbol);
- varSymbol.adr = 1 << i;
- List<JCAnnotation> annotations = param.getModifiers().getAnnotations();
- if (annotations != null && !annotations.isEmpty()) {
- ListBuffer<Attribute.Compound> newAnnotations = new ListBuffer<Attribute.Compound>();
- for (JCAnnotation jcAnnotation : annotations) {
- Attribute.Compound attribute = JCAnnotationReflect.getAttribute(jcAnnotation);
- if (attribute != null) {
- newAnnotations.append(attribute);
- }
- }
- if (annotations.length() == newAnnotations.length()) {
- varSymbol.appendAttributes(newAnnotations.toList());
- }
- }
- newParams.append(varSymbol);
- } else {
- newParams.append(param.sym);
- }
- }
- params = newParams.toList();
- if (params.length() != method.getParameters().length()) params = null;
- }
-
- fixMethodMirror(typeNode.getContext(), typeNode.getElement(), method.getModifiers().flags, method.getName(), paramTypes, params, returnType);
+ EnterReflect.memberEnter(method, typeNode);
typeNode.add(method, Kind.METHOD);
}
- private static void fixMethodMirror(Context context, Element typeMirror, long access, Name methodName, List<Type> paramTypes, List<Symbol.VarSymbol> params, Type returnType) {
- if (typeMirror == null || paramTypes == null || returnType == null) return;
- ClassSymbol cs = (ClassSymbol) typeMirror;
- MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.<Type>nil(), Symtab.instance(context).methodClass), cs);
- if (params != null && !params.isEmpty()) {
- methodSymbol.params = params;
- for (VarSymbol varSymbol : params) {
- varSymbol.owner = methodSymbol;
- }
- }
- ClassSymbolMembersField.enter(cs, methodSymbol);
- }
-
/**
* Adds an inner type (class, interface, enum) to the given type. Cannot inject top-level types.
*
@@ -1301,9 +1264,55 @@ public class JavacHandlerUtil {
addSuppressWarningsAll(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext());
addGenerated(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext());
typeDecl.defs = typeDecl.defs.append(type);
+
+ EnterReflect.classEnter(type, typeNode);
+
return typeNode.add(type, Kind.TYPE);
}
+ static class EnterReflect {
+ private static final Method classEnter;
+ private static final Method memberEnter;
+ private static final Method blockAnnotations;
+ private static final Method unblockAnnotations;
+
+ static {
+ classEnter = Permit.permissiveGetMethod(Enter.class, "classEnter", JCTree.class, Env.class);
+ memberEnter = Permit.permissiveGetMethod(MemberEnter.class, "memberEnter", JCTree.class, Env.class);
+
+ Method block = Permit.permissiveGetMethod(Annotate.class, "blockAnnotations");
+ if (block == null) block = Permit.permissiveGetMethod(Annotate.class, "enterStart");
+ blockAnnotations = block;
+
+ Method unblock = Permit.permissiveGetMethod(Annotate.class, "unblockAnnotations");
+ if (unblock == null) unblock = Permit.permissiveGetMethod(Annotate.class, "enterDone");
+ unblockAnnotations = unblock;
+ }
+
+ static Type classEnter(JCTree tree, JavacNode parent) {
+ Enter enter = Enter.instance(parent.getContext());
+ Env<AttrContext> classEnv = enter.getEnv((TypeSymbol) parent.getElement());
+ Type type = (Type) Permit.invokeSneaky(classEnter, enter, tree, classEnv);
+ if (type == null) return null;
+ type.complete();
+ return type;
+ }
+
+ static void memberEnter(JCTree tree, JavacNode parent) {
+ Context context = parent.getContext();
+ MemberEnter me = MemberEnter.instance(context);
+ Annotate annotate = Annotate.instance(context);
+ Enter enter = Enter.instance(context);
+
+ Env<AttrContext> classEnv = enter.getEnv((TypeSymbol) parent.getElement());
+ if (classEnv == null) return;
+
+ Permit.invokeSneaky(blockAnnotations, annotate);
+ Permit.invokeSneaky(memberEnter, me, tree, classEnv);
+ Permit.invokeSneaky(unblockAnnotations, annotate);
+ }
+ }
+
public static long addFinalIfNeeded(long flags, Context context) {
boolean addFinal = LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateFinalParams();
@@ -1802,10 +1811,49 @@ public class JavacHandlerUtil {
addError(errorName, annotationNode);
}
}
+ for (JCAnnotation annotation : result) {
+ clearTypes(annotation);
+ }
ast.args = params.toList();
return result.toList();
}
+ /**
+ * Removes all type information from the provided tree.
+ */
+ private static void clearTypes(JCTree tree) {
+ tree.accept(new TreeScanner() {
+ @Override public void scan(JCTree tree) {
+ tree.type = null;
+ super.scan(tree);
+ }
+ @Override public void visitClassDef(JCClassDecl tree) {
+ tree.sym = null;
+ super.visitClassDef(tree);
+ }
+ @Override public void visitMethodDef(JCMethodDecl tree) {
+ tree.sym = null;
+ super.visitMethodDef(tree);
+ }
+ @Override public void visitVarDef(JCVariableDecl tree) {
+ tree.sym = null;
+ super.visitVarDef(tree);
+ }
+ @Override public void visitSelect(JCFieldAccess tree) {
+ tree.sym = null;
+ super.visitSelect(tree);
+ }
+ @Override public void visitIdent(JCIdent tree) {
+ tree.sym = null;
+ super.visitIdent(tree);
+ }
+ @Override public void visitAnnotation(JCAnnotation tree) {
+ JCAnnotationReflect.setAttribute(tree, null);
+ super.visitAnnotation(tree);
+ }
+ });
+ }
+
private static void addError(String errorName, JavacNode node) {
if (node.getLatestJavaSpecSupported() < 8) {
node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))");