diff options
Diffstat (limited to 'src/core/lombok/javac/handlers')
15 files changed, 297 insertions, 186 deletions
diff --git a/src/core/lombok/javac/handlers/HandleAccessors.java b/src/core/lombok/javac/handlers/HandleAccessors.java index 7aeec6bb..e2489bda 100644 --- a/src/core/lombok/javac/handlers/HandleAccessors.java +++ b/src/core/lombok/javac/handlers/HandleAccessors.java @@ -28,11 +28,13 @@ import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.experimental.Accessors; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @ProviderFor(JavacAnnotationHandler.class) +@HandlerPriority(65536) public class HandleAccessors extends JavacAnnotationHandler<Accessors> { @Override public void handle(AnnotationValues<Accessors> annotation, JCAnnotation ast, JavacNode annotationNode) { // Accessors itself is handled by HandleGetter/Setter; this is just to ensure that the annotation is removed diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 6422f5ed..8a826087 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -41,7 +41,6 @@ import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; @@ -55,10 +54,12 @@ import lombok.experimental.Builder; import lombok.experimental.NonFinal; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.HandleConstructor.SkipIfConstructorExists; -import static lombok.javac.Javac.*; import static lombok.core.handlers.HandlerUtil.*; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.Javac.*; +import static lombok.javac.JavacTreeMaker.TypeTag.*; @ProviderFor(JavacAnnotationHandler.class) @HandlerPriority(-1024) //-2^10; to ensure we've picked up @FieldDefault's changes (-2048) but @Value hasn't removed itself yet (-512), so that we can error on presence of it on the builder classes. @@ -97,7 +98,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { if (parent.get() instanceof JCClassDecl) { tdParent = parent; JCClassDecl td = (JCClassDecl) tdParent.get(); - ListBuffer<JavacNode> allFields = ListBuffer.lb(); + ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>(); @SuppressWarnings("deprecation") boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation(lombok.experimental.Value.class, parent)); for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent)) { @@ -106,7 +107,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { // non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves. // Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that. if (fd.init != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue; - namesOfParameters.add(fd.name); + namesOfParameters.add(removePrefixFromField(fieldNode)); typesOfParameters.add(fd.vartype); allFields.append(fieldNode); } @@ -218,12 +219,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } private JCMethodDecl generateBuildMethod(String name, Name staticName, JCExpression returnType, java.util.List<Name> fieldNames, JavacNode type, List<JCExpression> thrownExceptions) { - TreeMaker maker = type.getTreeMaker(); + JavacTreeMaker maker = type.getTreeMaker(); JCExpression call; JCStatement statement; - ListBuffer<JCExpression> args = ListBuffer.lb(); + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); for (Name n : fieldNames) { args.append(maker.Ident(n)); } @@ -232,14 +233,14 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { call = maker.NewClass(null, List.<JCExpression>nil(), returnType, args.toList(), null); statement = maker.Return(call); } else { - ListBuffer<JCExpression> typeParams = ListBuffer.lb(); + ListBuffer<JCExpression> typeParams = new ListBuffer<JCExpression>(); for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) { typeParams.append(maker.Ident(tp.name)); } JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName); call = maker.Apply(typeParams.toList(), fn, args.toList()); - if (returnType instanceof JCPrimitiveTypeTree && ((JCPrimitiveTypeTree) returnType).typetag == CTC_VOID) { + if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) { statement = maker.Exec(call); } else { statement = maker.Return(call); @@ -252,9 +253,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } private JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) { - TreeMaker maker = type.getTreeMaker(); + JavacTreeMaker maker = type.getTreeMaker(); - ListBuffer<JCExpression> typeArgs = ListBuffer.lb(); + ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>(); for (JCTypeParameter typeParam : typeParams) { typeArgs.append(maker.Ident(typeParam.name)); } @@ -285,7 +286,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { continue top; } } - TreeMaker maker = builderType.getTreeMaker(); + JavacTreeMaker maker = builderType.getTreeMaker(); JCModifiers mods = maker.Modifiers(Flags.PRIVATE); JCVariableDecl newField = maker.VarDef(mods, name, cloneType(maker, typesOfParameters.get(i), source), null); out.add(injectField(builderType, newField)); @@ -308,7 +309,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { boolean isBoolean = isBoolean(fieldNode); String setterName = fluent ? fieldNode.getName() : TransformationsUtil.toSetterName(null, fieldNode.getName(), isBoolean); - TreeMaker maker = builderType.getTreeMaker(); + JavacTreeMaker maker = builderType.getTreeMaker(); return HandleSetter.createSetter(Flags.PUBLIC, fieldNode, maker, setterName, chain, source, List.<JCAnnotation>nil(), List.<JCAnnotation>nil()); } @@ -322,9 +323,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } private JavacNode makeBuilderClass(JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) { - TreeMaker maker = tdParent.getTreeMaker(); + JavacTreeMaker maker = tdParent.getTreeMaker(); JCModifiers mods = maker.Modifiers(Flags.PUBLIC | Flags.STATIC); - JCClassDecl builder = ClassDef(maker, mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil()); + JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil()); return injectType(tdParent, builder); } } diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 09b4faee..e7786ffe 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -28,10 +28,10 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; -import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; @@ -49,7 +49,6 @@ import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeCast; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; @@ -97,8 +96,8 @@ public class HandleCleanup extends JavacAnnotationHandler<Cleanup> { } boolean seenDeclaration = false; - ListBuffer<JCStatement> newStatements = ListBuffer.lb(); - ListBuffer<JCStatement> tryBlock = ListBuffer.lb(); + ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>(); + ListBuffer<JCStatement> tryBlock = new ListBuffer<JCStatement>(); for (JCStatement statement : statements) { if (!seenDeclaration) { if (statement == decl) seenDeclaration = true; @@ -114,7 +113,7 @@ public class HandleCleanup extends JavacAnnotationHandler<Cleanup> { } doAssignmentCheck(annotationNode, tryBlock.toList(), decl.name); - TreeMaker maker = annotationNode.getTreeMaker(); + JavacTreeMaker maker = annotationNode.getTreeMaker(); JCFieldAccess cleanupMethod = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName)); List<JCStatement> cleanupCall = List.<JCStatement>of(maker.Exec( maker.Apply(List.<JCExpression>nil(), cleanupMethod, List.<JCExpression>nil()))); @@ -139,9 +138,9 @@ public class HandleCleanup extends JavacAnnotationHandler<Cleanup> { ancestor.rebuild(); } - private JCMethodInvocation preventNullAnalysis(TreeMaker maker, JavacNode node, JCExpression expression) { + private JCMethodInvocation preventNullAnalysis(JavacTreeMaker maker, JavacNode node, JCExpression expression) { JCMethodInvocation singletonList = maker.Apply(List.<JCExpression>nil(), chainDotsString(node, "java.util.Collections.singletonList"), List.of(expression)); - JCMethodInvocation cleanedExpr = maker.Apply(List.<JCExpression>nil(), maker.Select(singletonList, node.toName("get")) , List.<JCExpression>of(maker.Literal(TypeTags.INT, 0))); + JCMethodInvocation cleanedExpr = maker.Apply(List.<JCExpression>nil(), maker.Select(singletonList, node.toName("get")) , List.<JCExpression>of(maker.Literal(CTC_INT, 0))); return cleanedExpr; } diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index ecd982e9..b77a5367 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -32,12 +32,12 @@ import lombok.core.AST.Kind; import lombok.experimental.Builder; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -52,6 +52,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Name; public class HandleConstructor { @ProviderFor(JavacAnnotationHandler.class) @@ -90,7 +91,7 @@ public class HandleConstructor { } private static List<JavacNode> findRequiredFields(JavacNode typeNode) { - ListBuffer<JavacNode> fields = ListBuffer.lb(); + ListBuffer<JavacNode> fields = new ListBuffer<JavacNode>(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); @@ -125,7 +126,7 @@ public class HandleConstructor { } static List<JavacNode> findAllFields(JavacNode typeNode) { - ListBuffer<JavacNode> fields = ListBuffer.lb(); + ListBuffer<JavacNode> fields = new ListBuffer<JavacNode>(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); @@ -206,11 +207,12 @@ public class HandleConstructor { private static void addConstructorProperties(JCModifiers mods, JavacNode node, List<JavacNode> fields) { if (fields.isEmpty()) return; - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties"); - ListBuffer<JCExpression> fieldNames = ListBuffer.lb(); + ListBuffer<JCExpression> fieldNames = new ListBuffer<JCExpression>(); for (JavacNode field : fields) { - fieldNames.append(maker.Literal(field.getName())); + Name fieldName = removePrefixFromField(field); + fieldNames.append(maker.Literal(fieldName.toString())); } JCExpression fieldNamesArray = maker.NewArray(null, List.<JCExpression>nil(), fieldNames.toList()); JCAnnotation annotation = maker.Annotation(constructorPropertiesType, List.of(fieldNamesArray)); @@ -218,23 +220,25 @@ public class HandleConstructor { } static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean suppressConstructorProperties, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0; if (isEnum) level = AccessLevel.PRIVATE; - ListBuffer<JCStatement> nullChecks = ListBuffer.lb(); - ListBuffer<JCStatement> assigns = ListBuffer.lb(); - ListBuffer<JCVariableDecl> params = ListBuffer.lb(); + ListBuffer<JCStatement> nullChecks = new ListBuffer<JCStatement>(); + ListBuffer<JCStatement> assigns = new ListBuffer<JCStatement>(); + ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); for (JavacNode fieldNode : fields) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); + Name fieldName = removePrefixFromField(fieldNode); + Name rawName = field.name; List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN); - JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), field.name, field.vartype, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, field.vartype, null); params.append(param); - JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name); - JCAssign assign = maker.Assign(thisX, maker.Ident(field.name)); + JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName); + JCAssign assign = maker.Assign(thisX, maker.Ident(fieldName)); assigns.append(maker.Exec(assign)); if (!nonNulls.isEmpty()) { @@ -261,18 +265,18 @@ public class HandleConstructor { } private JCMethodDecl createStaticConstructor(String name, AccessLevel level, JavacNode typeNode, List<JavacNode> fields, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); JCModifiers mods = maker.Modifiers(Flags.STATIC | toJavacModifier(level)); JCExpression returnType, constructorType; - ListBuffer<JCTypeParameter> typeParams = ListBuffer.lb(); - ListBuffer<JCVariableDecl> params = ListBuffer.lb(); - ListBuffer<JCExpression> typeArgs1 = ListBuffer.lb(); - ListBuffer<JCExpression> typeArgs2 = ListBuffer.lb(); - ListBuffer<JCExpression> args = ListBuffer.lb(); + ListBuffer<JCTypeParameter> typeParams = new ListBuffer<JCTypeParameter>(); + ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); + ListBuffer<JCExpression> typeArgs1 = new ListBuffer<JCExpression>(); + ListBuffer<JCExpression> typeArgs2 = new ListBuffer<JCExpression>(); + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); if (!type.typarams.isEmpty()) { for (JCTypeParameter param : type.typarams) { @@ -289,12 +293,13 @@ public class HandleConstructor { for (JavacNode fieldNode : fields) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); + Name fieldName = removePrefixFromField(fieldNode); JCExpression pType = cloneType(maker, field.vartype, source); List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN); - JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), field.name, pType, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, pType, null); params.append(param); - args.append(maker.Ident(field.name)); + args.append(maker.Ident(fieldName)); } JCReturn returnStatement = maker.Return(maker.NewClass(null, List.<JCExpression>nil(), constructorType, args.toList(), null)); JCBlock body = maker.Block(0, List.<JCStatement>of(returnStatement)); diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index 644b03fb..6af34f20 100644 --- a/src/core/lombok/javac/handlers/HandleDelegate.java +++ b/src/core/lombok/javac/handlers/HandleDelegate.java @@ -48,6 +48,7 @@ import lombok.javac.FindTypeVarScanner; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacResolution; +import lombok.javac.JavacTreeMaker; import lombok.javac.ResolutionResetNeeded; import lombok.javac.JavacResolution.TypeNotConvertibleException; @@ -71,7 +72,6 @@ import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; @@ -266,7 +266,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { checkConflictOfTypeVarNames(sig, annotation); - TreeMaker maker = annotation.getTreeMaker(); + JavacTreeMaker maker = annotation.getTreeMaker(); com.sun.tools.javac.util.List<JCAnnotation> annotations; if (sig.isDeprecated) { @@ -305,7 +305,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { int idx = 0; for (TypeMirror param : sig.type.getParameterTypes()) { - JCModifiers paramMods = maker.Modifiers(Flags.FINAL); + JCModifiers paramMods = maker.Modifiers(Flags.FINAL | Flags.PARAMETER); String[] paramNames = sig.getParameterNames(); Name name = annotation.toName(paramNames[idx++]); params.append(maker.VarDef(paramMods, name, JavacResolution.typeToJCTree((Type) param, annotation.getAst(), true), null)); @@ -394,13 +394,13 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { METHOD { public JCExpression get(final JavacNode node, final Name name) { com.sun.tools.javac.util.List<JCExpression> nilExprs = com.sun.tools.javac.util.List.nil(); - final TreeMaker maker = node.getTreeMaker(); + final JavacTreeMaker maker = node.getTreeMaker(); return maker.Apply(nilExprs, maker.Select(maker.Ident(node.toName("this")), name), nilExprs); } }, FIELD { public JCExpression get(final JavacNode node, final Name name) { - final TreeMaker maker = node.getTreeMaker(); + final JavacTreeMaker maker = node.getTreeMaker(); return maker.Select(maker.Ident(node.toName("this")), name); } }; diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 3b1e226f..0f8161e1 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -31,8 +31,10 @@ import java.util.Collections; import lombok.EqualsAndHashCode; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; @@ -40,7 +42,6 @@ import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; @@ -57,7 +58,6 @@ import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCUnary; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; @@ -139,7 +139,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } } - JCTree extending = ((JCClassDecl)typeNode.get()).getExtendsClause(); + JCTree extending = Javac.getExtendsClause((JCClassDecl)typeNode.get()); if (extending != null) { String p = extending.toString(); isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object"); @@ -154,7 +154,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas source.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type."); } - ListBuffer<JavacNode> nodesForEquality = ListBuffer.lb(); + ListBuffer<JavacNode> nodesForEquality = new ListBuffer<JavacNode>(); if (includes != null) { for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -195,7 +195,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas // The user code couldn't possibly (barring really weird subclassing shenanigans) be in a shippable state anyway; the implementations of these 3 methods are // all inter-related and should be written by the same entity. String msg = String.format("Not generating %s: One of equals, hashCode, and canEqual exists. " + - "You should either write all of these are none of these (in the latter case, lombok generates them).", + "You should either write all of these or none of these (in the latter case, lombok generates them).", equalsExists == MemberExistsResult.NOT_EXISTS && hashCodeExists == MemberExistsResult.NOT_EXISTS ? "equals and hashCode" : equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode"); source.addWarning(msg); @@ -219,12 +219,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); JCExpression returnType = maker.TypeIdent(CTC_INT); - ListBuffer<JCStatement> statements = ListBuffer.lb(); + ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>(); Name primeName = typeNode.toName(PRIME_NAME); Name resultName = typeNode.toName(RESULT_NAME); @@ -258,7 +258,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas break; case LONG: { Name dollarFieldName = dollar.append(((JCVariableDecl)fieldNode.get()).name); - statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(TypeTags.LONG), fieldAccessor)); + statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor)); statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName)))); } break; @@ -276,7 +276,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas List.<JCExpression>nil(), chainDots(typeNode, "java", "lang", "Double", "doubleToLongBits"), List.of(fieldAccessor)); - statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(TypeTags.LONG), init)); + statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, maker.TypeIdent(CTC_LONG), init)); statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName)))); } break; @@ -322,7 +322,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas private JCExpressionStatement createResultCalculation(JavacNode typeNode, JCExpression expr) { /* result = result * PRIME + (expr); */ - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); Name resultName = typeNode.toName(RESULT_NAME); JCExpression mult = maker.Binary(CTC_MUL, maker.Ident(resultName), maker.Ident(typeNode.toName(PRIME_NAME))); JCExpression add = maker.Binary(CTC_PLUS, mult, expr); @@ -330,7 +330,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } /** The 2 references must be clones of each other. */ - private JCExpression longToIntForHashCode(TreeMaker maker, JCExpression ref1, JCExpression ref2) { + private JCExpression longToIntForHashCode(JavacTreeMaker maker, JCExpression ref1, JCExpression ref2) { /* (int)(ref >>> 32 ^ ref) */ JCExpression shift = maker.Binary(CTC_UNSIGNED_SHIFT_RIGHT, ref1, maker.Literal(32)); JCExpression xorBits = maker.Binary(CTC_BITXOR, shift, ref2); @@ -347,7 +347,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } Collections.reverse(list); - TreeMaker maker = type.getTreeMaker(); + JavacTreeMaker maker = type.getTreeMaker(); JCExpression chain = maker.Ident(type.toName(list.get(0))); for (int i = 1; i < list.size(); i++) { @@ -358,7 +358,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); Name oName = typeNode.toName("o"); @@ -370,8 +370,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); - ListBuffer<JCStatement> statements = ListBuffer.lb(); - final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null)); + ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>(); + final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), oName, objectType, null)); /* if (o == this) return true; */ { statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), @@ -379,6 +379,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } /* if (!(o instanceof Outer.Inner.MyType) return false; */ { + JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } @@ -386,8 +387,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* MyType<?> other = (MyType<?>) o; */ { if (!fields.isEmpty() || needsCanEqual) { final JCExpression selfType1, selfType2; - ListBuffer<JCExpression> wildcards1 = ListBuffer.lb(); - ListBuffer<JCExpression> wildcards2 = ListBuffer.lb(); + 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)); @@ -493,14 +494,14 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas * return other instanceof Outer.Inner.MyType; * } */ - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.<JCAnnotation>nil()); JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); Name canEqualName = typeNode.toName("canEqual"); JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); Name otherName = typeNode.toName("other"); - List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), otherName, objectType, null)); + List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), otherName, objectType, null)); JCBlock body = maker.Block(0, List.<JCStatement>of( maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode))))); @@ -509,7 +510,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } private JCStatement generateCompareFloatOrDouble(JCExpression thisDotField, JCExpression otherDotField, - TreeMaker maker, JavacNode node, boolean isDouble) { + JavacTreeMaker maker, JavacNode node, boolean isDouble) { /* if (Float.compare(fieldName, other.fieldName) != 0) return false; */ JCExpression clazz = chainDots(node, "java", "lang", isDouble ? "Double" : "Float"); List<JCExpression> args = List.of(thisDotField, otherDotField); @@ -518,7 +519,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas return maker.If(compareCallEquals0, returnBool(maker, false), null); } - private JCStatement returnBool(TreeMaker maker, boolean bool) { + private JCStatement returnBool(JavacTreeMaker maker, boolean bool) { return maker.Return(maker.Literal(CTC_BOOLEAN, bool ? 1 : 0)); } } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 51642f86..4ef23170 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.Javac.*; +import static lombok.javac.JavacTreeMaker.TypeTag.*; import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.Collection; @@ -37,6 +38,8 @@ import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; +import lombok.javac.JavacTreeMaker.TypeTag; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -57,7 +60,6 @@ import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCSynchronized; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -213,7 +215,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source.get(), lazy, onMethod)); } - private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source, boolean lazy, List<JCAnnotation> onMethod) { + private JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, boolean lazy, List<JCAnnotation> onMethod) { JCVariableDecl fieldNode = (JCVariableDecl) field.get(); // Remember the type; lazy will change it @@ -268,7 +270,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { } if (!delegates.isEmpty()) { - ListBuffer<JCAnnotation> withoutDelegates = ListBuffer.lb(); + ListBuffer<JCAnnotation> withoutDelegates = new ListBuffer<JCAnnotation>(); for (JCAnnotation annotation : fieldNode.mods.annotations) { if (!delegates.contains(annotation)) { withoutDelegates.append(annotation); @@ -280,7 +282,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { return delegates; } - private List<JCStatement> createSimpleGetterBody(TreeMaker treeMaker, JavacNode field) { + private List<JCStatement> createSimpleGetterBody(JavacTreeMaker treeMaker, JavacNode field) { return List.<JCStatement>of(treeMaker.Return(createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD))); } @@ -288,9 +290,9 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { private static final String JLO = "java.lang.Object"; private static final List<JCExpression> NIL_EXPRESSION = List.nil(); - private static final java.util.Map<Integer, String> TYPE_MAP; + private static final java.util.Map<TypeTag, String> TYPE_MAP; static { - Map<Integer, String> m = new HashMap<Integer, String>(); + Map<TypeTag, String> m = new HashMap<TypeTag, String>(); m.put(CTC_INT, "java.lang.Integer"); m.put(CTC_DOUBLE, "java.lang.Double"); m.put(CTC_FLOAT, "java.lang.Float"); @@ -302,7 +304,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { TYPE_MAP = Collections.unmodifiableMap(m); } - private List<JCStatement> createLazyGetterBody(TreeMaker maker, JavacNode fieldNode, JCTree source) { + private List<JCStatement> createLazyGetterBody(JavacTreeMaker maker, JavacNode fieldNode, JCTree source) { /* java.lang.Object value = this.fieldName.get(); if (value == null) { @@ -326,7 +328,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { [END IF] */ - ListBuffer<JCStatement> statements = ListBuffer.lb(); + ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>(); JCVariableDecl field = (JCVariableDecl) fieldNode.get(); JCExpression copyOfRawFieldType = copyType(maker, field); @@ -334,7 +336,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { field.type = null; boolean isPrimitive = false; if (field.vartype instanceof JCPrimitiveTypeTree) { - String boxed = TYPE_MAP.get(((JCPrimitiveTypeTree)field.vartype).typetag); + String boxed = TYPE_MAP.get(typeTag(field.vartype)); if (boxed != null) { isPrimitive = true; field.vartype = chainDotsString(fieldNode, boxed); @@ -354,14 +356,14 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { /* if (value == null) { */ { JCSynchronized synchronizedStatement; /* synchronized (this.fieldName) { */ { - ListBuffer<JCStatement> synchronizedStatements = ListBuffer.lb(); + ListBuffer<JCStatement> synchronizedStatements = new ListBuffer<JCStatement>(); /* value = this.fieldName.get(); */ { JCExpressionStatement newAssign = maker.Exec(maker.Assign(maker.Ident(valueName), callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)))); synchronizedStatements.append(newAssign); } /* if (value == null) { */ { - ListBuffer<JCStatement> innerIfStatements = ListBuffer.lb(); + ListBuffer<JCStatement> innerIfStatements = new ListBuffer<JCStatement>(); /* final RawValueType actualValue = INITIALIZER_EXPRESSION; */ { innerIfStatements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), actualValueName, copyOfRawFieldType, field.init)); } @@ -423,16 +425,16 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { } private JCMethodInvocation callGet(JavacNode source, JCExpression receiver) { - TreeMaker maker = source.getTreeMaker(); + JavacTreeMaker maker = source.getTreeMaker(); return maker.Apply(NIL_EXPRESSION, maker.Select(receiver, source.toName("get")), NIL_EXPRESSION); } private JCStatement callSet(JavacNode source, JCExpression receiver, JCExpression value) { - TreeMaker maker = source.getTreeMaker(); + JavacTreeMaker maker = source.getTreeMaker(); return maker.Exec(maker.Apply(NIL_EXPRESSION, maker.Select(receiver, source.toName("set")), List.<JCExpression>of(value))); } - private JCExpression copyType(TreeMaker treeMaker, JCVariableDecl fieldNode) { + private JCExpression copyType(JavacTreeMaker treeMaker, JCVariableDecl fieldNode) { return fieldNode.type != null ? treeMaker.Type(fieldNode.type) : fieldNode.vartype; } } diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 35a32be5..31478b66 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -28,12 +28,12 @@ import java.lang.annotation.Annotation; import lombok.core.AnnotationValues; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; @@ -74,13 +74,13 @@ public class HandleLog { } private static JCFieldAccess selfType(JavacNode typeNode) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); Name name = ((JCClassDecl) typeNode.get()).name; return maker.Select(maker.Ident(name), typeNode.toName("class")); } private static boolean createField(LoggingFramework framework, JavacNode typeNode, JCFieldAccess loggingType, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); // private static final <loggerType> log = <factoryMethod>(<parameter>); JCExpression loggerType = chainDotsString(typeNode, framework.getLoggerTypeName()); @@ -164,7 +164,7 @@ public class HandleLog { // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(TargetType.class.getName()); JUL(lombok.extern.java.Log.class, "java.util.logging.Logger", "java.util.logging.Logger.getLogger") { @Override public JCExpression createFactoryParameter(JavacNode typeNode, JCFieldAccess loggingType) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCExpression method = maker.Select(loggingType, typeNode.toName("getName")); return maker.Apply(List.<JCExpression>nil(), method, List.<JCExpression>nil()); } diff --git a/src/core/lombok/javac/handlers/NonNullHandler.java b/src/core/lombok/javac/handlers/HandleNonNull.java index 415d6032..21611a39 100644 --- a/src/core/lombok/javac/handlers/NonNullHandler.java +++ b/src/core/lombok/javac/handlers/HandleNonNull.java @@ -36,18 +36,24 @@ import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCParens; import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSynchronized; import com.sun.tools.javac.tree.JCTree.JCThrow; +import com.sun.tools.javac.tree.JCTree.JCTry; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; import lombok.NonNull; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.core.AST.Kind; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import static lombok.javac.JavacTreeMaker.TypeTag.*; +import static lombok.javac.JavacTreeMaker.TreeTag.*; @ProviderFor(JavacAnnotationHandler.class) -public class NonNullHandler extends JavacAnnotationHandler<NonNull> { +@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. +public class HandleNonNull extends JavacAnnotationHandler<NonNull> { @Override public void handle(AnnotationValues<NonNull> annotation, JCAnnotation ast, JavacNode annotationNode) { if (annotationNode.up().getKind() == Kind.FIELD) { // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), @@ -74,7 +80,12 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> { return; } - if (JavacHandlerUtil.isGenerated(declaration)) return; +// if (JavacHandlerUtil.isGenerated(declaration)) return; + + if (declaration.body == null) { + annotationNode.addWarning("@NonNull is meaningless on a parameter of an abstract method."); + return; + } // Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter, // and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and @@ -91,17 +102,33 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> { List<JCStatement> statements = declaration.body.stats; String expectedName = annotationNode.up().getName(); - for (JCStatement stat : statements) { - if (JavacHandlerUtil.isConstructorCall(stat)) continue; - String varNameOfNullCheck = returnVarNameIfNullCheck(stat); - if (varNameOfNullCheck == null) break; - if (varNameOfNullCheck.equals(expectedName)) return; + + /* Abort if the null check is already there, delving into try and synchronized statements */ { + List<JCStatement> stats = statements; + int idx = 0; + while (stats.size() > idx) { + JCStatement stat = stats.get(idx++); + if (JavacHandlerUtil.isConstructorCall(stat)) continue; + if (stat instanceof JCTry) { + stats = ((JCTry) stat).body.stats; + idx = 0; + continue; + } + if (stat instanceof JCSynchronized) { + stats = ((JCSynchronized) stat).body.stats; + idx = 0; + continue; + } + String varNameOfNullCheck = returnVarNameIfNullCheck(stat); + if (varNameOfNullCheck == null) break; + if (varNameOfNullCheck.equals(expectedName)) return; + } } List<JCStatement> tail = statements; List<JCStatement> head = List.nil(); for (JCStatement stat : statements) { - if (JavacHandlerUtil.isConstructorCall(stat) || JavacHandlerUtil.isGenerated(stat)) { + if (JavacHandlerUtil.isConstructorCall(stat) || (JavacHandlerUtil.isGenerated(stat) && isNullCheck(stat))) { tail = tail.tail; head = head.prepend(stat); continue; @@ -114,6 +141,10 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> { declaration.body.stats = newList; } + private boolean isNullCheck(JCStatement stat) { + return returnVarNameIfNullCheck(stat) != null; + } + /** * Checks if the statement is of the form 'if (x == null) {throw WHATEVER;}, * where the block braces are optional. If it is of this form, returns "x". @@ -138,10 +169,10 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> { while (cond instanceof JCParens) cond = ((JCParens) cond).expr; if (!(cond instanceof JCBinary)) return null; JCBinary bin = (JCBinary) cond; - if (getTag(bin) != CTC_EQUAL) return null; + if (!CTC_EQUAL.equals(treeTag(bin))) return null; if (!(bin.lhs instanceof JCIdent)) return null; if (!(bin.rhs instanceof JCLiteral)) return null; - if (((JCLiteral) bin.rhs).typetag != CTC_BOT) return null; + if (!CTC_BOT.equals(typeTag(bin.rhs))) return null; return ((JCIdent) bin.lhs).name.toString(); } } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 282e6c2f..c4977b2b 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -26,23 +26,20 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.Collection; -import javax.lang.model.type.NoType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeVisitor; - import lombok.AccessLevel; import lombok.Setter; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; @@ -54,7 +51,6 @@ import com.sun.tools.javac.tree.JCTree.JCReturn; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -194,13 +190,13 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { injectMethod(fieldNode.up(), createdSetter); } - static JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { + static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { String setterName = toSetterName(field); boolean returnThis = shouldReturnThis(field); return createSetter(access, field, treeMaker, setterName, returnThis, source, onMethod, onParam); } - static JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, String setterName, boolean shouldReturnThis, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { + static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { if (setterName == null) return null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); @@ -208,14 +204,14 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD); JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name)); - ListBuffer<JCStatement> statements = ListBuffer.lb(); + ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>(); List<JCAnnotation> nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); Name methodName = field.toName(setterName); List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL | Flags.PARAMETER, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); if (nonNulls.isEmpty()) { statements.append(treeMaker.Exec(assign)); @@ -232,7 +228,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { if (methodType == null) { //WARNING: Do not use field.getSymbolTable().voidType - that field has gone through non-backwards compatible API changes within javac1.6. - methodType = treeMaker.Type(new JCNoType(CTC_VOID)); + methodType = treeMaker.Type(Javac.createVoidType(treeMaker, CTC_VOID)); shouldReturnThis = false; } @@ -257,22 +253,4 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { copyJavadoc(field, decl, CopyJavadoc.SETTER); return decl; } - - private static class JCNoType extends Type implements NoType { - public JCNoType(int tag) { - super(tag, null); - } - - @Override - public TypeKind getKind() { - if (tag == CTC_VOID) return TypeKind.VOID; - if (tag == CTC_NONE) return TypeKind.NONE; - throw new AssertionError("Unexpected tag: " + tag); - } - - @Override - public <R, P> R accept(TypeVisitor<R, P> v, P p) { - return v.visitNoType(this, p); - } - } } diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index c818f630..b41277c3 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -29,14 +29,15 @@ import java.util.Collections; import lombok.SneakyThrows; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCExpression; @@ -49,6 +50,7 @@ import com.sun.tools.javac.util.List; * Handles the {@code lombok.SneakyThrows} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSneakyThrows extends JavacAnnotationHandler<SneakyThrows> { @Override public void handle(AnnotationValues<SneakyThrows> annotation, JCAnnotation ast, JavacNode annotationNode) { deleteAnnotationIfNeccessary(annotationNode, SneakyThrows.class); @@ -113,7 +115,7 @@ public class HandleSneakyThrows extends JavacAnnotationHandler<SneakyThrows> { } private JCStatement buildTryCatchBlock(JavacNode node, List<JCStatement> contents, String exception, JCTree source) { - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); JCBlock tryBlock = setGeneratedBy(maker.Block(0, contents), source); diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index 2bca49e9..661a7c2a 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 The Project Lombok Authors. + * Copyright (C) 2009-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +26,10 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import lombok.Synchronized; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; import org.mangosdk.spi.ProviderFor; @@ -39,13 +41,13 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCNewArray; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; /** * Handles the {@code lombok.Synchronized} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { private static final String INSTANCE_LOCK_NAME = "$lock"; private static final String STATIC_LOCK_NAME = "$LOCK"; @@ -77,7 +79,7 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME; } - TreeMaker maker = methodNode.getTreeMaker().at(ast.pos); + JavacTreeMaker maker = methodNode.getTreeMaker().at(ast.pos); if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) { if (!autoMake) { diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 333393da..9bd5b920 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 The Project Lombok Authors. + * Copyright (C) 2009-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,12 +31,12 @@ import lombok.core.AnnotationValues; import lombok.core.AST.Kind; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -129,7 +129,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { return; } - ListBuffer<JavacNode> nodesForToString = ListBuffer.lb(); + ListBuffer<JavacNode> nodesForToString = new ListBuffer<JavacNode>(); if (includes != null) { for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -167,7 +167,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { } static JCMethodDecl createToString(JavacNode typeNode, Collection<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index b3f218b8..9cfa4531 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -33,6 +33,7 @@ import lombok.core.TransformationsUtil; import lombok.experimental.Wither; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; @@ -51,7 +52,6 @@ import com.sun.tools.javac.tree.JCTree.JCReturn; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -201,27 +201,25 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { injectMethod(fieldNode.up(), createdWither); } - private JCMethodDecl createWither(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { + private JCMethodDecl createWither(long access, JavacNode field, JavacTreeMaker maker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { String witherName = toWitherName(field); if (witherName == null) return null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); - ListBuffer<JCStatement> statements = ListBuffer.lb(); + ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>(); List<JCAnnotation> nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); Name methodName = field.toName(witherName); List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); JCExpression selfType = cloneSelfType(field); if (selfType == null) return null; - TreeMaker maker = field.getTreeMaker(); - - ListBuffer<JCExpression> args = ListBuffer.lb(); + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); for (JavacNode child : field.up().down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl childDecl = (JCVariableDecl) child.get(); @@ -247,14 +245,14 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { if (nonNulls.isEmpty()) { statements.append(returnStatement); } else { - JCStatement nullCheck = generateNullCheck(treeMaker, field); + JCStatement nullCheck = generateNullCheck(maker, field); if (nullCheck != null) statements.append(nullCheck); statements.append(returnStatement); } JCExpression returnType = cloneSelfType(field); - JCBlock methodBody = treeMaker.Block(0, statements.toList()); + JCBlock methodBody = maker.Block(0, statements.toList()); List<JCTypeParameter> methodGenericParams = List.nil(); List<JCVariableDecl> parameters = List.of(param); List<JCExpression> throwsClauses = List.nil(); @@ -263,9 +261,9 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod); if (isFieldDeprecated(field)) { - annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil())); + annsOnMethod = annsOnMethod.prepend(maker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil())); } - JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, returnType, + JCMethodDecl decl = recursiveSetGeneratedBy(maker.MethodDef(maker.Modifiers(access, annsOnMethod), methodName, returnType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); copyJavadoc(field, decl, CopyJavadoc.WITHER); return decl; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index d7d29da2..50e80169 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -44,10 +44,14 @@ import lombok.core.AnnotationValues.AnnotationValue; import lombok.core.TransformationsUtil; import lombok.core.TypeResolver; import lombok.experimental.Accessors; +import lombok.javac.Javac; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.parser.Tokens.Comment; +import com.sun.tools.javac.tree.DocCommentTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; @@ -72,7 +76,6 @@ 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.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; @@ -96,6 +99,7 @@ public class JavacHandlerUtil { } @Override public void scan(JCTree tree) { + if (tree == null) return; setGeneratedBy(tree, source); super.scan(tree); } @@ -133,10 +137,12 @@ public class JavacHandlerUtil { } public static <T extends JCTree> T setGeneratedBy(T node, JCTree source) { + if (node == null) return null; synchronized (generatedNodes) { if (source == null) generatedNodes.remove(node); else generatedNodes.put(node, new WeakReference<JCTree>(source)); } + if (source != null) node.pos = source.pos; return node; } @@ -213,6 +219,17 @@ public class JavacHandlerUtil { } /** + * Returns if a node is marked deprecated (as picked up on by the parser). + * @param node the node to check (type, method, or field decl). + */ + public static boolean nodeHasDeprecatedFlag(JCTree node) { + if (node instanceof JCVariableDecl) return (((JCVariableDecl) node).mods.flags & Flags.DEPRECATED) != 0; + if (node instanceof JCMethodDecl) return (((JCMethodDecl) node).mods.flags & Flags.DEPRECATED) != 0; + if (node instanceof JCClassDecl) return (((JCClassDecl) node).mods.flags & Flags.DEPRECATED) != 0; + return false; + } + + /** * Creates an instance of {@code AnnotationValues} for the provided AST Node. * * @param type An annotation class type, such as {@code lombok.Getter.class}. @@ -334,7 +351,7 @@ public class JavacHandlerUtil { public static void deleteImportFromCompilationUnit(JavacNode node, String name) { if (inNetbeansEditor(node)) return; if (!node.shouldDeleteLombokAnnotations()) return; - ListBuffer<JCTree> newDefs = ListBuffer.lb(); + ListBuffer<JCTree> newDefs = new ListBuffer<JCTree>(); JCCompilationUnit unit = (JCCompilationUnit) node.top().get(); @@ -350,7 +367,7 @@ public class JavacHandlerUtil { } private static List<JCAnnotation> filterList(List<JCAnnotation> annotations, JCTree jcTree) { - ListBuffer<JCAnnotation> newAnnotations = ListBuffer.lb(); + ListBuffer<JCAnnotation> newAnnotations = new ListBuffer<JCAnnotation>(); for (JCAnnotation ann : annotations) { if (jcTree != ann) newAnnotations.append(ann); } @@ -429,11 +446,11 @@ public class JavacHandlerUtil { public static JCExpression cloneSelfType(JavacNode field) { JavacNode typeNode = field; - TreeMaker maker = field.getTreeMaker(); + JavacTreeMaker maker = field.getTreeMaker(); while (typeNode != null && typeNode.getKind() != Kind.TYPE) typeNode = typeNode.up(); if (typeNode != null && typeNode.get() instanceof JCClassDecl) { JCClassDecl type = (JCClassDecl) typeNode.get(); - ListBuffer<JCExpression> typeArgs = ListBuffer.lb(); + ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>(); if (!type.typarams.isEmpty()) { for (JCTypeParameter tp : type.typarams) { typeArgs.append(maker.Ident(tp.name)); @@ -456,6 +473,37 @@ public class JavacHandlerUtil { return varType != null && varType.toString().equals("boolean"); } + public static Name removePrefixFromField(JavacNode field) { + String[] prefixes = null; + for (JavacNode node : field.down()) { + if (annotationTypeMatches(Accessors.class, node)) { + prefixes = createAnnotation(Accessors.class, node).getInstance().prefix(); + break; + } + } + + if (prefixes == null) { + JavacNode current = field.up(); + outer: + while (current != null) { + for (JavacNode node : current.down()) { + if (annotationTypeMatches(Accessors.class, node)) { + prefixes = createAnnotation(Accessors.class, node).getInstance().prefix(); + break outer; + } + } + current = current.up(); + } + } + + if (prefixes != null && prefixes.length > 0) { + CharSequence newName = TransformationsUtil.removePrefix(field.getName(), prefixes); + if (newName != null) return field.toName(newName.toString()); + } + + return ((JCVariableDecl) field.get()).name; + } + public static AnnotationValues<Accessors> getAccessorsForField(JavacNode field) { for (JavacNode node : field.down()) { if (annotationTypeMatches(Accessors.class, node)) { @@ -707,11 +755,11 @@ public class JavacHandlerUtil { /** * Creates an expression that reads the field. Will either be {@code this.field} or {@code this.getField()} depending on whether or not there's a getter. */ - static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, FieldAccess fieldAccess) { + static JCExpression createFieldAccessor(JavacTreeMaker maker, JavacNode field, FieldAccess fieldAccess) { return createFieldAccessor(maker, field, fieldAccess, null); } - static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) { + static JCExpression createFieldAccessor(JavacTreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) { boolean lookForGetter = lookForGetter(field, fieldAccess); GetterMethod getter = lookForGetter ? findGetter(field) : null; @@ -839,7 +887,7 @@ public class JavacHandlerUtil { } private static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos, JCTree source) { - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); JCExpression suppressWarningsType = chainDots(node, "java", "lang", "SuppressWarnings"); JCLiteral allLiteral = maker.Literal("all"); suppressWarningsType.pos = pos; @@ -850,7 +898,7 @@ public class JavacHandlerUtil { } private static List<JCTree> addAllButOne(List<JCTree> defs, int idx) { - ListBuffer<JCTree> out = ListBuffer.lb(); + ListBuffer<JCTree> out = new ListBuffer<JCTree>(); int i = 0; for (JCTree def : defs) { if (i++ != idx) out.append(def); @@ -890,7 +938,7 @@ public class JavacHandlerUtil { assert elems != null; assert elems.length > 0; - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); if (pos != -1) maker = maker.at(pos); JCExpression e = maker.Ident(node.toName(elems[0])); for (int i = 1 ; i < elems.length ; i++) { @@ -921,7 +969,7 @@ public class JavacHandlerUtil { * Only the simple name is checked - the package and any containing class are ignored. */ public static List<JCAnnotation> findAnnotations(JavacNode fieldNode, Pattern namePattern) { - ListBuffer<JCAnnotation> result = ListBuffer.lb(); + ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); @@ -940,15 +988,15 @@ public class JavacHandlerUtil { * Generates a new statement that checks if the given variable is null, and if so, throws a {@code NullPointerException} with the * variable name as message. */ - public static JCStatement generateNullCheck(TreeMaker treeMaker, JavacNode variable) { + public static JCStatement generateNullCheck(JavacTreeMaker maker, JavacNode variable) { JCVariableDecl varDecl = (JCVariableDecl) variable.get(); if (isPrimitive(varDecl.vartype)) return null; Name fieldName = varDecl.name; JCExpression npe = chainDots(variable, "java", "lang", "NullPointerException"); - JCTree exception = treeMaker.NewClass(null, List.<JCExpression>nil(), npe, List.<JCExpression>of(treeMaker.Literal(fieldName.toString())), null); - JCStatement throwStatement = treeMaker.Throw(exception); - JCBlock throwBlock = treeMaker.Block(0, List.of(throwStatement)); - return treeMaker.If(treeMaker.Binary(CTC_EQUAL, treeMaker.Ident(fieldName), treeMaker.Literal(CTC_BOT, null)), throwBlock, null); + JCExpression exception = maker.NewClass(null, List.<JCExpression>nil(), npe, List.<JCExpression>of(maker.Literal(fieldName.toString())), null); + JCStatement throwStatement = maker.Throw(exception); + JCBlock throwBlock = maker.Block(0, List.of(throwStatement)); + return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), throwBlock, null); } /** @@ -971,7 +1019,7 @@ public class JavacHandlerUtil { if (idx > -1) matched[idx] = true; } - ListBuffer<Integer> problematic = ListBuffer.lb(); + ListBuffer<Integer> problematic = new ListBuffer<Integer>(); for (int i = 0 ; i < list.size() ; i++) { if (!matched[i]) problematic.append(i); } @@ -980,8 +1028,8 @@ public class JavacHandlerUtil { } static List<JCAnnotation> unboxAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName, String errorName, JavacNode errorNode) { - ListBuffer<JCExpression> params = ListBuffer.lb(); - ListBuffer<JCAnnotation> result = ListBuffer.lb(); + ListBuffer<JCExpression> params = new ListBuffer<JCExpression>(); + ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); errorNode.removeDeferredErrors(); @@ -1005,9 +1053,9 @@ public class JavacHandlerUtil { if (valueOfParam instanceof JCAnnotation) { String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString(); - dummyAnnotationName = dummyAnnotationName.replace("_", ""); + dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", ""); if (dummyAnnotationName.length() > 0) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); continue outer; } for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { @@ -1016,7 +1064,7 @@ public class JavacHandlerUtil { if ("value".equals(id.name.toString())) { expr = ((JCAssign) expr).rhs; } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); continue outer; } } @@ -1028,12 +1076,12 @@ public class JavacHandlerUtil { if (expr2 instanceof JCAnnotation) { result.append((JCAnnotation) expr2); } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); continue outer; } } } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); continue outer; } } @@ -1041,7 +1089,7 @@ public class JavacHandlerUtil { if (valueOfParam instanceof JCNewArray && ((JCNewArray) valueOfParam).elems.isEmpty()) { // Then we just remove it and move on (it's onMethod={} for example). } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); } } } @@ -1049,15 +1097,15 @@ public class JavacHandlerUtil { return result.toList(); } - public static List<JCTypeParameter> copyTypeParams(TreeMaker maker, List<JCTypeParameter> params) { + public static List<JCTypeParameter> copyTypeParams(JavacTreeMaker maker, List<JCTypeParameter> params) { if (params == null || params.isEmpty()) return params; - ListBuffer<JCTypeParameter> out = ListBuffer.lb(); + ListBuffer<JCTypeParameter> out = new ListBuffer<JCTypeParameter>(); for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); return out.toList(); } - public static JCExpression namePlusTypeParamsToTypeReference(TreeMaker maker, Name typeName, List<JCTypeParameter> params) { - ListBuffer<JCExpression> typeArgs = ListBuffer.lb(); + public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List<JCTypeParameter> params) { + ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>(); if (!params.isEmpty()) { for (JCTypeParameter param : params) { @@ -1093,7 +1141,7 @@ public class JavacHandlerUtil { } static List<JCAnnotation> copyAnnotations(List<? extends JCExpression> in) { - ListBuffer<JCAnnotation> out = ListBuffer.lb(); + ListBuffer<JCAnnotation> out = new ListBuffer<JCAnnotation>(); for (JCExpression expr : in) { if (!(expr instanceof JCAnnotation)) continue; out.append((JCAnnotation) expr.clone()); @@ -1135,13 +1183,13 @@ public class JavacHandlerUtil { * the class's own parameter, but as its a static method, the static method's notion of {@code T} is different from the class notion of {@code T}. If you're duplicating * a type used in the class context, you need to use this method. */ - public static JCExpression cloneType(TreeMaker maker, JCExpression in, JCTree source) { + public static JCExpression cloneType(JavacTreeMaker maker, JCExpression in, JCTree source) { JCExpression out = cloneType0(maker, in); if (out != null) recursiveSetGeneratedBy(out, source); return out; } - private static JCExpression cloneType0(TreeMaker maker, JCTree in) { + private static JCExpression cloneType0(JavacTreeMaker maker, JCTree in) { if (in == null) return null; if (in instanceof JCPrimitiveTypeTree) return (JCExpression) in; @@ -1162,7 +1210,7 @@ public class JavacHandlerUtil { if (in instanceof JCTypeApply) { JCTypeApply ta = (JCTypeApply) in; - ListBuffer<JCExpression> lb = ListBuffer.lb(); + ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>(); for (JCExpression typeArg : ta.arguments) { lb.append(cloneType0(maker, typeArg)); } @@ -1279,15 +1327,57 @@ public class JavacHandlerUtil { if (copyMode == null) copyMode = CopyJavadoc.VERBATIM; try { JCCompilationUnit cu = ((JCCompilationUnit) from.top().get()); - if (cu.docComments != null) { - String javadoc = cu.docComments.get(from.get()); - - if (javadoc != null) { - String[] filtered = copyMode.split(javadoc); - cu.docComments.put(to, filtered[0]); - cu.docComments.put(from.get(), filtered[1]); - } + Object dc = Javac.getDocComments(cu); + if (dc instanceof Map) { + copyJavadoc_jdk6_7(from, to, copyMode, dc); + } else if (Javac.instanceOfDocCommentTable(dc)) { + CopyJavadoc_8.copyJavadoc(from, to, copyMode, dc); } } catch (Exception ignore) {} } + + private static class CopyJavadoc_8 { + static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode, Object dc) { + DocCommentTable dct = (DocCommentTable) dc; + Comment javadoc = dct.getComment(from.get()); + + if (javadoc != null) { + String[] filtered = copyMode.split(javadoc.getText()); + dct.putComment(to, createJavadocComment(filtered[0], from)); + dct.putComment(from.get(), createJavadocComment(filtered[1], from)); + } + } + + private static Comment createJavadocComment(final String text, final JavacNode field) { + return new Comment() { + @Override public String getText() { + return text; + } + + @Override public int getSourcePos(int index) { + return -1; + } + + @Override public CommentStyle getStyle() { + return CommentStyle.JAVADOC; + } + + @Override public boolean isDeprecated() { + return text.contains("@deprecated") && field.getKind() == Kind.FIELD && isFieldDeprecated(field); + } + }; + } + } + + @SuppressWarnings({"unchecked", "all"}) + private static void copyJavadoc_jdk6_7(JavacNode from, JCTree to, CopyJavadoc copyMode, Object dc) { + Map<JCTree, String> docComments = (Map<JCTree, String>) dc; + String javadoc = docComments.get(from.get()); + + if (javadoc != null) { + String[] filtered = copyMode.split(javadoc); + docComments.put(to, filtered[0]); + docComments.put(from.get(), filtered[1]); + } + } } |