diff options
author | Kevin Chirls <kchirls@users.noreply.github.com> | 2017-03-15 09:26:36 -0700 |
---|---|---|
committer | Kevin Chirls <kchirls@users.noreply.github.com> | 2017-03-15 09:26:36 -0700 |
commit | d146f362682654afd1a01c477836e72eadbd9e42 (patch) | |
tree | 5491f9510b0539fdfc2e8f188d6f1ef89c77242a /src/core/lombok/javac/handlers | |
parent | f765730526e061d39c3ecd44f37de6a7f7887cf0 (diff) | |
parent | a2c10c70fa8e2c8736464a5c3d445e2ca6e8a296 (diff) | |
download | lombok-d146f362682654afd1a01c477836e72eadbd9e42.tar.gz lombok-d146f362682654afd1a01c477836e72eadbd9e42.tar.bz2 lombok-d146f362682654afd1a01c477836e72eadbd9e42.zip |
Merge remote-tracking branch 'rzwitserloot/master'
Diffstat (limited to 'src/core/lombok/javac/handlers')
8 files changed, 144 insertions, 111 deletions
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 8588fc16..4c670433 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -155,7 +155,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { allFields.append(fieldNode); } - new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, null, annotationNode); + new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode); returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams); typeParams = td.typarams; @@ -270,8 +270,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } if (pos == -1 || tpOnType.size() <= pos) { - annotationNode.addError("**" + returnType.getClass().toString()); -// annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type."); + annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type."); return; } typeArgsForToBuilder.add(tpOnType.get(pos).name); @@ -298,7 +297,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { JavacNode builderType = findInnerClass(tdParent, builderClassName); if (builderType == null) { - builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast); + builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast); } else { JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get(); if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) { @@ -320,7 +319,6 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } } } - } for (BuilderFieldData bfd : builderFields) { @@ -350,7 +348,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) { - JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, null, annotationNode); + JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, annotationNode); if (cd != null) injectMethod(builderType, cd); } @@ -375,7 +373,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast)); if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) { - JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams); + JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams); recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); if (md != null) injectMethod(tdParent, md); } @@ -550,7 +548,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null); } - public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) { + public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) { JavacTreeMaker maker = type.getTreeMaker(); ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>(); @@ -564,7 +562,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { JCBlock body = maker.Block(0, List.<JCStatement>of(statement)); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; - return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); + return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); } public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) { @@ -629,12 +627,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { return null; } - public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) { + public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) { JavacTreeMaker maker = tdParent.getTreeMaker(); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; JCModifiers mods = maker.Modifiers(modifiers); - JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil()); + JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil()); return injectType(tdParent, builder); } diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 5f523ce6..25e96d75 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -71,14 +71,14 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return; - List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode); + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); boolean force = ann.force(); List<JavacNode> fields = force ? findFinalFields(typeNode) : List.<JavacNode>nil(); - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, null, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -91,19 +91,16 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return; - List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode); + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode); RequiredArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -141,18 +138,15 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return; - List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode); + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode); AllArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -188,7 +182,7 @@ public class HandleConstructor { } public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, null, source); + generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, source); } public enum SkipIfConstructorExists { @@ -196,10 +190,10 @@ public class HandleConstructor { } public void generateAllArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, null, source); + generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, source); } - public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, Boolean suppressConstructorProperties, JavacNode source) { + public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { boolean staticConstrRequired = staticName != null && !staticName.equals(""); if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; @@ -228,7 +222,7 @@ public class HandleConstructor { } } - JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, suppressConstructorProperties, source); + JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source); ListBuffer<Type> argTypes = new ListBuffer<Type>(); for (JavacNode fieldNode : fields) { Type mirror = getMirrorForFieldType(fieldNode); @@ -262,18 +256,18 @@ public class HandleConstructor { mods.annotations = mods.annotations.append(annotation); } - public static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean allToDefault, Boolean suppressConstructorProperties, JavacNode source) { + public static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean allToDefault, JavacNode source) { JavacTreeMaker maker = typeNode.getTreeMaker(); boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0; if (isEnum) level = AccessLevel.PRIVATE; - if (suppressConstructorProperties == null) { - if (fields.isEmpty()) { - suppressConstructorProperties = false; - } else { - suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); - } + boolean suppressConstructorProperties; + + if (fields.isEmpty()) { + suppressConstructorProperties = false; + } else { + suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); } ListBuffer<JCStatement> nullChecks = new ListBuffer<JCStatement>(); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index f34b4f6b..6df56ed6 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -95,7 +95,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas List<String> excludes = List.from(ann.exclude()); List<String> includes = List.from(ann.of()); JavacNode typeNode = annotationNode.up(); - List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam=", annotationNode); + List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode); checkForBogusFieldNames(typeNode, annotation); Boolean callSuper = ann.callSuper(); @@ -363,7 +363,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas return maker.TypeCast(maker.TypeIdent(CTC_INT), maker.Parens(xorBits)); } - public JCExpression createTypeReference(JavacNode type) { + public JCExpression createTypeReference(JavacNode type, boolean addWildcards) { java.util.List<String> list = new ArrayList<String>(); list.add(type.getName()); JavacNode tNode = type.up(); @@ -372,20 +372,28 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas tNode = tNode.up(); } Collections.reverse(list); + JCClassDecl typeDecl = (JCClassDecl) type.get(); JavacTreeMaker maker = type.getTreeMaker(); + JCExpression chain = maker.Ident(type.toName(list.get(0))); for (int i = 1; i < list.size(); i++) { chain = maker.Select(chain, type.toName(list.get(i))); } - return chain; + if (!addWildcards || typeDecl.typarams.length() == 0) return chain; + + ListBuffer<JCExpression> wildcards = new ListBuffer<JCExpression>(); + for (int i = 0 ; i < typeDecl.typarams.length() ; i++) { + wildcards.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); + } + + return maker.TypeApply(chain, wildcards.toList()); } public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) { JavacTreeMaker maker = typeNode.getTreeMaker(); - JCClassDecl type = (JCClassDecl) typeNode.get(); Name oName = typeNode.toName("o"); Name otherName = typeNode.toName("other"); @@ -408,27 +416,13 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* if (!(o instanceof Outer.Inner.MyType)) return false; */ { - JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode)))); + JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false)))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } - /* MyType<?> other = (MyType<?>) o; */ { + /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */ { if (!fields.isEmpty() || needsCanEqual) { - final JCExpression selfType1, selfType2; - ListBuffer<JCExpression> wildcards1 = new ListBuffer<JCExpression>(); - ListBuffer<JCExpression> wildcards2 = new ListBuffer<JCExpression>(); - for (int i = 0 ; i < type.typarams.length() ; i++) { - wildcards1.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); - wildcards2.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); - } - - if (type.typarams.isEmpty()) { - selfType1 = maker.Ident(type.name); - selfType2 = maker.Ident(type.name); - } else { - selfType1 = maker.TypeApply(maker.Ident(type.name), wildcards1.toList()); - selfType2 = maker.TypeApply(maker.Ident(type.name), wildcards2.toList()); - } + final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true); statements.append( maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName)))); @@ -533,7 +527,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null)); JCBlock body = maker.Block(0, List.<JCStatement>of( - maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode))))); + maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false))))); return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext()); } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 60dbe8ee..5a2e1993 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -147,7 +147,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { if (node == null) return; - List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode); + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 02cc3775..e766127a 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -129,8 +129,8 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { if (level == AccessLevel.NONE || node == null) return; - List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode); - List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode); + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod", annotationNode); + List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java index 6d3ec63b..ee8081d6 100644 --- a/src/core/lombok/javac/handlers/HandleUtilityClass.java +++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java @@ -44,6 +44,7 @@ import com.sun.tools.javac.util.Name; import lombok.ConfigurationKeys; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.experimental.UtilityClass; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; @@ -53,6 +54,7 @@ import lombok.javac.JavacTreeMaker; /** * Handles the {@code @UtilityClass} annotation for javac. */ +@HandlerPriority(-4096) //-2^12; to ensure @FieldDefaults picks up on the 'static' we set here. @ProviderFor(JavacAnnotationHandler.class) public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> { @Override public void handle(AnnotationValues<UtilityClass> annotation, JCAnnotation ast, JavacNode annotationNode) { diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 8aec0240..987a3d34 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -131,8 +131,8 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { if (level == AccessLevel.NONE || node == null) return; - List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod=", annotationNode); - List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam=", annotationNode); + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode); + List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 949c9f5c..68d8061c 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -92,6 +92,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -894,16 +895,20 @@ public class JavacHandlerUtil { static class ClassSymbolMembersField { private static final Field membersField; private static final Method removeMethod; + private static final Method enterMethod; static { Field f = null; - Method m = null; + Method r = null; + Method e = null; try { f = ClassSymbol.class.getField("members_field"); - m = f.getType().getMethod("remove", Symbol.class); - } catch (Exception e) {} + r = f.getType().getMethod("remove", Symbol.class); + e = f.getType().getMethod("enter", Symbol.class); + } catch (Exception ex) {} membersField = f; - removeMethod = m; + removeMethod = r; + enterMethod = e; } static void remove(ClassSymbol from, Symbol toRemove) { @@ -914,6 +919,15 @@ public class JavacHandlerUtil { removeMethod.invoke(scope, toRemove); } catch (Exception e) {} } + + static void enter(ClassSymbol from, Symbol toEnter) { + if (from == null) return; + try { + Scope scope = (Scope) membersField.get(from); + if (scope == null) return; + enterMethod.invoke(scope, toEnter); + } catch (Exception e) {} + } } public static void injectMethod(JavacNode typeNode, JCMethodDecl method) { @@ -959,7 +973,7 @@ public class JavacHandlerUtil { 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); - cs.members_field.enter(methodSymbol); + ClassSymbolMembersField.enter(cs, methodSymbol); } /** @@ -1025,10 +1039,10 @@ public class JavacHandlerUtil { public static void addGenerated(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) { if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateGenerated()) return; - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) { + if (HandlerUtil.shouldAddGenerated(node)) { addAnnotation(mods, node, pos, source, context, "javax.annotation.Generated", node.getTreeMaker().Literal("lombok")); } - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) { + if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS))) { addAnnotation(mods, node, pos, source, context, "lombok.Generated", null); } } @@ -1233,19 +1247,9 @@ public class JavacHandlerUtil { ListBuffer<JCExpression> params = new ListBuffer<JCExpression>(); ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); - try { - for (JCExpression arg : ast.args) { - String argName = "value"; - if (arg instanceof JCAssign) { - JCAssign as = (JCAssign) arg; - argName = as.lhs.toString(); - } - if (!argName.equals(parameterName)) continue; - } - } catch (Exception ignore) {} - outer: for (JCExpression param : ast.args) { + boolean allowRaw; String nameOfParam = "value"; JCExpression valueOfParam = null; if (param instanceof JCAssign) { @@ -1257,6 +1261,15 @@ public class JavacHandlerUtil { valueOfParam = assign.rhs; } + /* strip trailing underscores */ { + int lastIdx; + for (lastIdx = nameOfParam.length() ; lastIdx > 0; lastIdx--) { + if (nameOfParam.charAt(lastIdx - 1) != '_') break; + } + allowRaw = lastIdx < nameOfParam.length(); + nameOfParam = nameOfParam.substring(0, lastIdx); + } + if (!parameterName.equals(nameOfParam)) { params.append(param); continue outer; @@ -1269,52 +1282,84 @@ public class JavacHandlerUtil { String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString(); dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", ""); if (dummyAnnotationName.length() > 0) { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; - } - for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { - if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) { - JCIdent id = (JCIdent) ((JCAssign) expr).lhs; - if ("value".equals(id.name.toString())) { - expr = ((JCAssign) expr).rhs; - } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; - } + if (allowRaw) { + result.append((JCAnnotation) valueOfParam); + } else { + addError(errorName, annotationNode); + continue outer; } - - if (expr instanceof JCAnnotation) { - result.append((JCAnnotation) expr); - } else if (expr instanceof JCNewArray) { - for (JCExpression expr2 : ((JCNewArray) expr).elems) { - if (expr2 instanceof JCAnnotation) { - result.append((JCAnnotation) expr2); + } else { + for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { + if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) { + JCIdent id = (JCIdent) ((JCAssign) expr).lhs; + if ("value".equals(id.name.toString())) { + expr = ((JCAssign) expr).rhs; } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; + addError(errorName, annotationNode); } } - } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; + + if (expr instanceof JCAnnotation) { + result.append((JCAnnotation) expr); + } else if (expr instanceof JCNewArray) { + for (JCExpression expr2 : ((JCNewArray) expr).elems) { + if (expr2 instanceof JCAnnotation) { + result.append((JCAnnotation) expr2); + } else { + addError(errorName, annotationNode); + continue outer; + } + } + } else { + addError(errorName, annotationNode); + continue outer; + } } } - } else { - if (valueOfParam instanceof JCNewArray && ((JCNewArray) valueOfParam).elems.isEmpty()) { - // Then we just remove it and move on (it's onMethod={} for example). + } else if (valueOfParam instanceof JCNewArray) { + JCNewArray arr = (JCNewArray) valueOfParam; + if (arr.elems.isEmpty()) { + // Just remove it, this is always fine. + } else if (allowRaw) { + for (JCExpression jce : arr.elems) { + if (jce instanceof JCAnnotation) result.append((JCAnnotation) jce); + else addError(errorName, annotationNode); + } } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + addError(errorName, annotationNode); } + } else { + addError(errorName, annotationNode); } } ast.args = params.toList(); return result.toList(); } - public static List<JCTypeParameter> copyTypeParams(JavacTreeMaker maker, List<JCTypeParameter> params) { + private static void addError(String errorName, JavacNode node) { + if (node.getLatestJavaSpecSupported() < 8) { + node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + } else { + node.addError("The correct format for JDK8+ is " + errorName + "_={@SomeAnnotation, @SomeOtherAnnotation})"); + } + } + + public static List<JCTypeParameter> copyTypeParams(JavacNode source, List<JCTypeParameter> params) { if (params == null || params.isEmpty()) return params; ListBuffer<JCTypeParameter> out = new ListBuffer<JCTypeParameter>(); - for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); + JavacTreeMaker maker = source.getTreeMaker(); + Context context = source.getContext(); + for (JCTypeParameter tp : params) { + List<JCExpression> bounds = tp.bounds; + if (bounds != null && !bounds.isEmpty()) { + ListBuffer<JCExpression> boundsCopy = new ListBuffer<JCExpression>(); + for (JCExpression expr : tp.bounds) { + boundsCopy.append(cloneType(maker, expr, source.get(), context)); + } + bounds = boundsCopy.toList(); + } + out.append(maker.TypeParameter(tp.name, bounds)); + } return out.toList(); } |