diff options
Diffstat (limited to 'src/core/lombok/javac/handlers/JavacHandlerUtil.java')
-rw-r--r-- | src/core/lombok/javac/handlers/JavacHandlerUtil.java | 190 |
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}))"); |