From 4be46113e81292a88cd5fdb3a5ce18fbcffd570d Mon Sep 17 00:00:00 2001 From: Robbert Jan Grootjans Date: Fri, 8 Mar 2013 16:54:02 +0100 Subject: Compiler options can now be specified for JDK 8 or JDK 6/7 or lower. After this was finalized I realize that we might consider moving entirely to String based options, instead of inferring the options from the provided enum. This setup does have the benefit of throwing exceptions when options are not present. --- .../lombok/javac/Javac6BasedLombokOptions.java | 45 ++++++++++++++++++++++ .../lombok/javac/Javac8BasedLombokOptions.java | 45 ++++++++++++++++++++++ src/core/lombok/javac/LombokOptions.java | 14 ++----- 3 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 src/core/lombok/javac/Javac6BasedLombokOptions.java create mode 100644 src/core/lombok/javac/Javac8BasedLombokOptions.java (limited to 'src/core') diff --git a/src/core/lombok/javac/Javac6BasedLombokOptions.java b/src/core/lombok/javac/Javac6BasedLombokOptions.java new file mode 100644 index 00000000..4bb2bdc3 --- /dev/null +++ b/src/core/lombok/javac/Javac6BasedLombokOptions.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac; + +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; + +public class Javac6BasedLombokOptions extends LombokOptions { + + public static Javac6BasedLombokOptions replaceWithDelombokOptions(Context context) { + Options options = Options.instance(context); + context.put(optionsKey, (Options)null); + Javac6BasedLombokOptions result = new Javac6BasedLombokOptions(context); + result.putAll(options); + return result; + } + + private Javac6BasedLombokOptions(Context context) { + super(context); + } + + @Override public void putJavacOption(String optionName, String value) { + put(OptionName.valueOf(optionName), value); + } +} diff --git a/src/core/lombok/javac/Javac8BasedLombokOptions.java b/src/core/lombok/javac/Javac8BasedLombokOptions.java new file mode 100644 index 00000000..3fdea890 --- /dev/null +++ b/src/core/lombok/javac/Javac8BasedLombokOptions.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac; + +import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; + +public class Javac8BasedLombokOptions extends LombokOptions { + public static Javac8BasedLombokOptions replaceWithDelombokOptions(Context context) { + Options options = Options.instance(context); + context.put(optionsKey, (Options)null); + Javac8BasedLombokOptions result = new Javac8BasedLombokOptions(context); + result.putAll(options); + return result; + } + + private Javac8BasedLombokOptions(Context context) { + super(context); + } + + @Override public void putJavacOption(String optionName, String value) { + String optionText = Option.valueOf(optionName).text; + put(optionText, value); + } +} diff --git a/src/core/lombok/javac/LombokOptions.java b/src/core/lombok/javac/LombokOptions.java index 1a73a8cc..66e42fe7 100644 --- a/src/core/lombok/javac/LombokOptions.java +++ b/src/core/lombok/javac/LombokOptions.java @@ -28,18 +28,10 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Options; -public class LombokOptions extends Options { +public abstract class LombokOptions extends Options { private boolean deleteLombokAnnotations = true; private final Set changed = new HashSet(); - public static LombokOptions replaceWithDelombokOptions(Context context) { - Options options = Options.instance(context); - context.put(optionsKey, (Options)null); - LombokOptions result = new LombokOptions(context); - result.putAll(options); - return result; - } - public boolean isChanged(JCCompilationUnit ast) { return changed.contains(ast); } @@ -54,7 +46,9 @@ public class LombokOptions extends Options { return (options instanceof LombokOptions) && ((LombokOptions) options).deleteLombokAnnotations; } - private LombokOptions(Context context) { + protected LombokOptions(Context context) { super(context); } + + public abstract void putJavacOption(String optionName, String value); } -- cgit From 0b100f22071236907142e4c0fb85ffa50102818d Mon Sep 17 00:00:00 2001 From: Robbert Jan Grootjans Date: Fri, 22 Mar 2013 18:23:44 +0100 Subject: Refactored out references to TypeTags. Instead they are retrieved dynamically, with a pinch of caching during runtime. We already had some fixes to make sure that compile time constanst were not inlined, but we need to take into account that a lot of the Integer-based enums have been replaced with actual enums. Also, certain TreeMaker methods needed to be invoked dynamically with reflection. This needs to be reviewed, and if it turns out that these changes are too dramatic, we should fork out a larger part of our code for specific JVM versions. --- src/core/lombok/javac/JavacResolution.java | 27 ++- src/core/lombok/javac/handlers/HandleCleanup.java | 5 +- .../javac/handlers/HandleEqualsAndHashCode.java | 51 ++--- src/core/lombok/javac/handlers/HandleGetter.java | 9 +- src/core/lombok/javac/handlers/HandleSetter.java | 10 +- .../lombok/javac/handlers/HandleSynchronized.java | 3 +- src/core/lombok/javac/handlers/HandleToString.java | 13 +- src/core/lombok/javac/handlers/HandleWither.java | 3 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 9 +- .../lombok/delombok/PrettyCommentsPrinter.java | 234 ++++++++++---------- src/utils/lombok/javac/Javac.java | 237 ++++++++++++++++++--- 11 files changed, 397 insertions(+), 204 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 0a21aa58..e5d8ed38 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -43,7 +43,6 @@ import com.sun.tools.javac.code.Type.ArrayType; import com.sun.tools.javac.code.Type.CapturedType; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type.WildcardType; -import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; @@ -419,8 +418,8 @@ public class JavacResolution { TreeMaker maker = ast.getTreeMaker(); - if (type.tag == CTC_BOT) return createJavaLangObject(ast); - if (type.tag == CTC_VOID) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast); + if (Javac.compareCTC(type.tag, CTC_BOT)) return createJavaLangObject(ast); + if (Javac.compareCTC(type.tag, CTC_VOID)) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast); if (type.isPrimitive()) return primitiveToJCTree(type.getKind(), maker); if (type.isErroneous()) throw new TypeNotConvertibleException("Type cannot be resolved"); @@ -454,7 +453,7 @@ public class JavacResolution { upper = type.getUpperBound(); } if (allowCompound) { - if (lower == null || lower.tag == CTC_BOT) { + if (lower == null || Javac.compareCTC(lower.tag, CTC_BOT)) { if (upper == null || upper.toString().equals("java.lang.Object")) { return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null); } @@ -479,7 +478,7 @@ public class JavacResolution { String qName; if (symbol.isLocal()) { qName = symbol.getSimpleName().toString(); - } else if (symbol.type != null && symbol.type.getEnclosingType() != null && symbol.type.getEnclosingType().tag == TypeTags.CLASS) { + } else if (symbol.type != null && symbol.type.getEnclosingType() != null && Javac.compareCTC(symbol.type.getEnclosingType().tag, Javac.getTypeTag("CLASS"))) { replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false); qName = symbol.getSimpleName().toString(); } else { @@ -515,23 +514,23 @@ public class JavacResolution { private static JCExpression primitiveToJCTree(TypeKind kind, TreeMaker maker) throws TypeNotConvertibleException { switch (kind) { case BYTE: - return maker.TypeIdent(CTC_BYTE); + return Javac.makeTypeIdent(maker, CTC_BYTE); case CHAR: - return maker.TypeIdent(CTC_CHAR); + return Javac.makeTypeIdent(maker, CTC_CHAR); case SHORT: - return maker.TypeIdent(CTC_SHORT); + return Javac.makeTypeIdent(maker, CTC_SHORT); case INT: - return maker.TypeIdent(CTC_INT); + return Javac.makeTypeIdent(maker, CTC_INT); case LONG: - return maker.TypeIdent(CTC_LONG); + return Javac.makeTypeIdent(maker, CTC_LONG); case FLOAT: - return maker.TypeIdent(CTC_FLOAT); + return Javac.makeTypeIdent(maker, CTC_FLOAT); case DOUBLE: - return maker.TypeIdent(CTC_DOUBLE); + return Javac.makeTypeIdent(maker, CTC_DOUBLE); case BOOLEAN: - return maker.TypeIdent(CTC_BOOLEAN); + return Javac.makeTypeIdent(maker, CTC_BOOLEAN); case VOID: - return maker.TypeIdent(CTC_VOID); + return Javac.makeTypeIdent(maker, CTC_VOID); case NULL: case NONE: case OTHER: diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 09b4faee..c75256a5 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -26,6 +26,7 @@ import static lombok.javac.Javac.*; import lombok.Cleanup; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @@ -120,7 +121,7 @@ public class HandleCleanup extends JavacAnnotationHandler { maker.Apply(List.nil(), cleanupMethod, List.nil()))); JCMethodInvocation preventNullAnalysis = preventNullAnalysis(maker, annotationNode, maker.Ident(decl.name)); - JCBinary isNull = maker.Binary(CTC_NOT_EQUAL, preventNullAnalysis, maker.Literal(CTC_BOT, null)); + JCBinary isNull = Javac.makeBinary(maker, CTC_NOT_EQUAL, preventNullAnalysis, Javac.makeLiteral(maker, CTC_BOT, null)); JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null); @@ -141,7 +142,7 @@ public class HandleCleanup extends JavacAnnotationHandler { private JCMethodInvocation preventNullAnalysis(TreeMaker maker, JavacNode node, JCExpression expression) { JCMethodInvocation singletonList = maker.Apply(List.nil(), chainDotsString(node, "java.util.Collections.singletonList"), List.of(expression)); - JCMethodInvocation cleanedExpr = maker.Apply(List.nil(), maker.Select(singletonList, node.toName("get")) , List.of(maker.Literal(TypeTags.INT, 0))); + JCMethodInvocation cleanedExpr = maker.Apply(List.nil(), maker.Select(singletonList, node.toName("get")) , List.of(Javac.makeLiteral(maker, CTC_INT, 0))); return cleanedExpr; } diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 5f69be9d..39edb143 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -30,6 +30,7 @@ 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.handlers.JavacHandlerUtil.FieldAccess; @@ -39,7 +40,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; @@ -213,7 +213,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); - JCExpression returnType = maker.TypeIdent(CTC_INT); + JCExpression returnType = Javac.makeTypeIdent(maker, CTC_INT); ListBuffer statements = ListBuffer.lb(); Name primeName = typeNode.toName(PRIME_NAME); @@ -221,12 +221,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), 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, Javac.makeTypeIdent(maker, CTC_LONG), init)); statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName)))); } break; @@ -296,7 +296,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")), List.nil()); - JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(dollarFieldName), maker.Literal(CTC_BOT, null)); + JCExpression thisEqualsNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(dollarFieldName), Javac.makeLiteral(maker, CTC_BOT, null)); statements.append(createResultCalculation(typeNode, maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall))); } } @@ -314,17 +314,17 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler>> 32 ^ ref) */ - JCExpression shift = maker.Binary(CTC_UNSIGNED_SHIFT_RIGHT, ref1, maker.Literal(32)); - JCExpression xorBits = maker.Binary(CTC_BITXOR, shift, ref2); - return maker.TypeCast(maker.TypeIdent(CTC_INT), xorBits); + JCExpression shift = Javac.makeBinary(maker, CTC_UNSIGNED_SHIFT_RIGHT, ref1, maker.Literal(32)); + JCExpression xorBits = Javac.makeBinary(maker, CTC_BITXOR, shift, ref2); + return maker.TypeCast(Javac.makeTypeIdent(maker, CTC_INT), xorBits); } private JCExpression createTypeReference(JavacNode type) { @@ -358,18 +358,19 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); - JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); + JCExpression returnType = Javac.makeTypeIdent(maker, CTC_BOOLEAN); ListBuffer statements = ListBuffer.lb(); final List params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null)); /* if (o == this) return true; */ { - statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), + statements.append(maker.If(Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null)); } /* if (!(o instanceof Outer.Inner.MyType) return false; */ { - JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); + + JCUnary notInstanceOf = Javac.makeUnary(maker, CTC_NOT, maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } @@ -404,7 +405,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.of(maker.Ident(oName))); - JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper); + JCUnary superNotEqual = Javac.makeUnary(maker, CTC_NOT, callToSuper); statements.append(maker.If(superNotEqual, returnBool(maker, false), null)); } @@ -436,7 +437,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler args = List.of(thisFieldAccessor, otherFieldAccessor); - statements.append(maker.If(maker.Unary(CTC_NOT, + statements.append(maker.If(Javac.makeUnary(maker, CTC_NOT, maker.Apply(List.nil(), eqMethod, args)), returnBool(maker, false), null)); } else /* objects */ { /* final java.lang.Object this$fieldName = this.fieldName; */ @@ -460,12 +461,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.of(maker.Ident(otherDollarFieldName))); - JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat)); + JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, Javac.makeUnary(maker, CTC_NOT, thisEqualsThat)); statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null)); } } @@ -486,7 +487,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); - JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); + JCExpression returnType = Javac.makeTypeIdent(maker, CTC_BOOLEAN); Name canEqualName = typeNode.toName("canEqual"); JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); Name otherName = typeNode.toName("other"); @@ -503,12 +504,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler args = List.of(thisDotField, otherDotField); - JCBinary compareCallEquals0 = maker.Binary(CTC_NOT_EQUAL, maker.Apply( + JCBinary compareCallEquals0 = Javac.makeBinary(maker, CTC_NOT_EQUAL, maker.Apply( List.nil(), maker.Select(clazz, node.toName("compare")), args), maker.Literal(0)); return maker.If(compareCallEquals0, returnBool(maker, false), null); } private JCStatement returnBool(TreeMaker maker, boolean bool) { - return maker.Return(maker.Literal(CTC_BOOLEAN, bool ? 1 : 0)); + return maker.Return(Javac.makeLiteral(maker, CTC_BOOLEAN, bool ? 1 : 0)); } } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index bc68d5ad..2fa2a755 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -35,6 +35,7 @@ import lombok.Getter; 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.handlers.JavacHandlerUtil.FieldAccess; @@ -288,9 +289,9 @@ public class HandleGetter extends JavacAnnotationHandler { private static final String AR = "java.util.concurrent.atomic.AtomicReference"; private static final List NIL_EXPRESSION = List.nil(); - private static final java.util.Map TYPE_MAP; + private static final java.util.Map TYPE_MAP; static { - Map m = new HashMap(); + Map m = new HashMap(); m.put(CTC_INT, "java.lang.Integer"); m.put(CTC_DOUBLE, "java.lang.Double"); m.put(CTC_FLOAT, "java.lang.Float"); @@ -364,7 +365,7 @@ public class HandleGetter extends JavacAnnotationHandler { innerIfStatements.append(statement); } - JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null)); + JCBinary isNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(valueName), Javac.makeLiteral(maker, CTC_BOT, null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements.toList()), null); synchronizedStatements.append(ifStatement); } @@ -372,7 +373,7 @@ public class HandleGetter extends JavacAnnotationHandler { synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements.toList())); } - JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null)); + JCBinary isNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(valueName), Javac.makeLiteral(maker, CTC_BOT, null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, List.of(synchronizedStatement)), null); statements.append(ifStatement); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index c1e03c35..2136024e 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -35,6 +35,7 @@ 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.handlers.JavacHandlerUtil.FieldAccess; @@ -253,14 +254,15 @@ public class HandleSetter extends JavacAnnotationHandler { } private static class JCNoType extends Type implements NoType { - public JCNoType(int tag) { - super(tag, null); + public JCNoType(Object tag) { + //FIX + super(1, null); } @Override public TypeKind getKind() { - if (tag == CTC_VOID) return TypeKind.VOID; - if (tag == CTC_NONE) return TypeKind.NONE; + if (Javac.compareCTC(tag, CTC_VOID)) return TypeKind.VOID; + if (Javac.compareCTC(tag, CTC_NONE)) return TypeKind.NONE; throw new AssertionError("Unexpected tag: " + tag); } diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index 2bca49e9..2737eeb2 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -26,6 +26,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import lombok.Synchronized; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; @@ -87,7 +88,7 @@ public class HandleSynchronized extends JavacAnnotationHandler { JCExpression objectType = chainDots(methodNode, ast.pos, "java", "lang", "Object"); //We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable! JCNewArray newObjectArray = maker.NewArray(chainDots(methodNode, ast.pos, "java", "lang", "Object"), - List.of(maker.Literal(CTC_INT, 0)), null); + List.of(Javac.makeLiteral(maker, CTC_INT, 0)), null); JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray), ast); diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 520acf62..c37fe149 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -27,6 +27,7 @@ import static lombok.javac.Javac.*; import lombok.ToString; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @@ -193,7 +194,7 @@ public class HandleToString extends JavacAnnotationHandler { JCMethodInvocation callToSuper = maker.Apply(List.nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.nil()); - current = maker.Binary(CTC_PLUS, current, callToSuper); + current = Javac.makeBinary(maker, CTC_PLUS, current, callToSuper); first = false; } @@ -213,21 +214,21 @@ public class HandleToString extends JavacAnnotationHandler { } else expr = fieldAccessor; if (first) { - current = maker.Binary(CTC_PLUS, current, expr); + current = Javac.makeBinary(maker, CTC_PLUS, current, expr); first = false; continue; } if (includeFieldNames) { - current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "=")); + current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "=")); } else { - current = maker.Binary(CTC_PLUS, current, maker.Literal(infix)); + current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(infix)); } - current = maker.Binary(CTC_PLUS, current, expr); + current = Javac.makeBinary(maker, CTC_PLUS, current, expr); } - if (!first) current = maker.Binary(CTC_PLUS, current, maker.Literal(suffix)); + if (!first) current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(suffix)); JCStatement returnStatement = maker.Return(current); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index ba5aa72d..62ed63f1 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -31,6 +31,7 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.experimental.Wither; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; @@ -239,7 +240,7 @@ public class HandleWither extends JavacAnnotationHandler { } JCNewClass newClass = maker.NewClass(null, List.nil(), selfType, args.toList(), null); - JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name)); + JCExpression identityCheck = Javac.makeBinary(maker, CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name)); JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass); JCReturn returnStatement = maker.Return(conditional); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index c2de5b05..178b82a2 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -42,6 +42,7 @@ 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 com.sun.tools.javac.code.BoundKind; @@ -882,14 +883,14 @@ 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(TreeMaker 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.nil(), npe, List.of(treeMaker.Literal(fieldName.toString())), null); - JCStatement throwStatement = treeMaker.Throw(exception); - return treeMaker.If(treeMaker.Binary(CTC_EQUAL, treeMaker.Ident(fieldName), treeMaker.Literal(CTC_BOT, null)), throwStatement, null); + JCTree exception = maker.NewClass(null, List.nil(), npe, List.of(maker.Literal(fieldName.toString())), null); + JCStatement throwStatement = maker.Throw(exception); + return maker.If(Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(fieldName), Javac.makeLiteral(maker, CTC_BOT, null)), throwStatement, null); } /** diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 6e9a1c94..d0f38a62 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -48,7 +48,8 @@ import com.sun.source.tree.Tree; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.code.TypeTags; +//import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; @@ -121,12 +122,12 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { private static final Method GET_TAG_METHOD; private static final Field TAG_FIELD; - private static final int PARENS = Javac.getCtcInt(JCTree.class, "PARENS"); - private static final int IMPORT = Javac.getCtcInt(JCTree.class, "IMPORT"); - private static final int VARDEF = Javac.getCtcInt(JCTree.class, "VARDEF"); - private static final int SELECT = Javac.getCtcInt(JCTree.class, "SELECT"); + private static final Object PARENS = Javac.getTreeTag("PARENS"); + private static final Object IMPORT = Javac.getTreeTag("IMPORT"); + private static final Object VARDEF = Javac.getTreeTag("VARDEF"); + private static final Object SELECT = Javac.getTreeTag("SELECT"); - private static final Map OPERATORS; + private static final Map OPERATORS; static { Method m = null; @@ -145,44 +146,44 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { GET_TAG_METHOD = m; TAG_FIELD = f; - Map map = new HashMap(); + Map map = new HashMap(); - map.put(Javac.getCtcInt(JCTree.class, "POS"), "+"); - map.put(Javac.getCtcInt(JCTree.class, "NEG"), "-"); - map.put(Javac.getCtcInt(JCTree.class, "NOT"), "!"); - map.put(Javac.getCtcInt(JCTree.class, "COMPL"), "~"); - map.put(Javac.getCtcInt(JCTree.class, "PREINC"), "++"); - map.put(Javac.getCtcInt(JCTree.class, "PREDEC"), "--"); - map.put(Javac.getCtcInt(JCTree.class, "POSTINC"), "++"); - map.put(Javac.getCtcInt(JCTree.class, "POSTDEC"), "--"); - map.put(Javac.getCtcInt(JCTree.class, "NULLCHK"), "<*nullchk*>"); - map.put(Javac.getCtcInt(JCTree.class, "OR"), "||"); - map.put(Javac.getCtcInt(JCTree.class, "AND"), "&&"); - map.put(Javac.getCtcInt(JCTree.class, "EQ"), "=="); - map.put(Javac.getCtcInt(JCTree.class, "NE"), "!="); - map.put(Javac.getCtcInt(JCTree.class, "LT"), "<"); - map.put(Javac.getCtcInt(JCTree.class, "GT"), ">"); - map.put(Javac.getCtcInt(JCTree.class, "LE"), "<="); - map.put(Javac.getCtcInt(JCTree.class, "GE"), ">="); - map.put(Javac.getCtcInt(JCTree.class, "BITOR"), "|"); - map.put(Javac.getCtcInt(JCTree.class, "BITXOR"), "^"); - map.put(Javac.getCtcInt(JCTree.class, "BITAND"), "&"); - map.put(Javac.getCtcInt(JCTree.class, "SL"), "<<"); - map.put(Javac.getCtcInt(JCTree.class, "SR"), ">>"); - map.put(Javac.getCtcInt(JCTree.class, "USR"), ">>>"); - map.put(Javac.getCtcInt(JCTree.class, "PLUS"), "+"); - map.put(Javac.getCtcInt(JCTree.class, "MINUS"), "-"); - map.put(Javac.getCtcInt(JCTree.class, "MUL"), "*"); - map.put(Javac.getCtcInt(JCTree.class, "DIV"), "/"); - map.put(Javac.getCtcInt(JCTree.class, "MOD"), "%"); + map.put(Javac.getTreeTag("POS"), "+"); + map.put(Javac.getTreeTag("NEG"), "-"); + map.put(Javac.getTreeTag("NOT"), "!"); + map.put(Javac.getTreeTag("COMPL"), "~"); + map.put(Javac.getTreeTag("PREINC"), "++"); + map.put(Javac.getTreeTag("PREDEC"), "--"); + map.put(Javac.getTreeTag("POSTINC"), "++"); + map.put(Javac.getTreeTag("POSTDEC"), "--"); + map.put(Javac.getTreeTag("NULLCHK"), "<*nullchk*>"); + map.put(Javac.getTreeTag("OR"), "||"); + map.put(Javac.getTreeTag("AND"), "&&"); + map.put(Javac.getTreeTag("EQ"), "=="); + map.put(Javac.getTreeTag("NE"), "!="); + map.put(Javac.getTreeTag("LT"), "<"); + map.put(Javac.getTreeTag("GT"), ">"); + map.put(Javac.getTreeTag("LE"), "<="); + map.put(Javac.getTreeTag("GE"), ">="); + map.put(Javac.getTreeTag("BITOR"), "|"); + map.put(Javac.getTreeTag("BITXOR"), "^"); + map.put(Javac.getTreeTag("BITAND"), "&"); + map.put(Javac.getTreeTag("SL"), "<<"); + map.put(Javac.getTreeTag("SR"), ">>"); + map.put(Javac.getTreeTag("USR"), ">>>"); + map.put(Javac.getTreeTag("PLUS"), "+"); + map.put(Javac.getTreeTag("MINUS"), "-"); + map.put(Javac.getTreeTag("MUL"), "*"); + map.put(Javac.getTreeTag("DIV"), "/"); + map.put(Javac.getTreeTag("MOD"), "%"); OPERATORS = map; } - static int getTag(JCTree tree) { + static Object getTag(JCTree tree) { if (GET_TAG_METHOD != null) { try { - return (Integer)GET_TAG_METHOD.invoke(tree); + return GET_TAG_METHOD.invoke(tree); } catch (IllegalAccessException e) { throw new RuntimeException(e); @@ -192,7 +193,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } try { - return TAG_FIELD.getInt(tree); + return TAG_FIELD.get(tree); } catch (IllegalAccessException e) { throw new RuntimeException(e); @@ -1222,7 +1223,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - public String operatorName(int tag) { + public String operatorName(Object tag) { String result = OPERATORS.get(tag); if (result == null) throw new Error(); return result; @@ -1232,7 +1233,8 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { try { open(prec, TreeInfo.assignopPrec); printExpr(tree.lhs, TreeInfo.assignopPrec + 1); - print(" " + operatorName(getTag(tree) - JCTree.ASGOffset) + "= "); +// print(" " + operatorName(getTag(tree) - JCTree.ASGOffset) + "= "); + print(" = "); printExpr(tree.rhs, TreeInfo.assignopPrec); close(prec, TreeInfo.assignopPrec); } catch (IOException e) { @@ -1242,10 +1244,10 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitUnary(JCUnary tree) { try { - int ownprec = TreeInfo.opPrec(getTag(tree)); + int ownprec = isOwnPrec(tree); String opname = operatorName(getTag(tree)); open(prec, ownprec); - if (getTag(tree) <= Javac.getCtcInt(JCTree.class, "PREDEC")) { + if (isPostUnary(tree)) { print(opname); printExpr(tree.arg, ownprec); } else { @@ -1257,10 +1259,63 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { throw new UncheckedIOException(e); } } + + private String assignOpName(JCExpression tree) { + try { + Object tag = getTag(tree); + if (JavaCompiler.version().startsWith("1.8")) { + return operatorName(tag.getClass().getMethod("noAssignOp").invoke(tree)); + } else { + return operatorName((Integer)((Integer)tag - (Integer)JCTree.class.getField("ASGOffset").get(null))); + } + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + private int isOwnPrec(JCExpression tree) { + try { + if (JavaCompiler.version().startsWith("1.8")) { + return (Integer)TreeInfo.class.getMethod("opPrec", Class.forName("com.sun.tools.javac.code.TypeTag")).invoke(tree, getTag(tree)); + } else { + return (Integer)TreeInfo.class.getMethod("opPrec", Integer.TYPE).invoke(tree, getTag(tree)); + } + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + private boolean isPostUnary(JCUnary tree) { + try { + Object tag = getTag(tree); + if (JavaCompiler.version().startsWith("1.8")) { + return (Boolean) tag.getClass().getMethod("isPostUnaryOp").invoke(tree); + } else { + return ((Integer) tag) <= ((Integer) Javac.getTreeTag("PREDEC")); + } + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } public void visitBinary(JCBinary tree) { try { - int ownprec = TreeInfo.opPrec(getTag(tree)); + int ownprec = isOwnPrec(tree); String opname = operatorName(getTag(tree)); open(prec, ownprec); printExpr(tree.lhs, ownprec); @@ -1327,77 +1382,40 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitLiteral(JCLiteral tree) { try { - switch (tree.typetag) { - case TypeTags.INT: - print(tree.value.toString()); - break; - case TypeTags.LONG: - print(tree.value + "L"); - break; - case TypeTags.FLOAT: - print(tree.value + "F"); - break; - case TypeTags.DOUBLE: - print(tree.value.toString()); - break; - case TypeTags.CHAR: - print("\'" + - Convert.quote( - String.valueOf((char)((Number)tree.value).intValue())) + - "\'"); - break; - case TypeTags.BOOLEAN: - print(((Number)tree.value).intValue() == 1 ? "true" : "false"); - break; - case TypeTags.BOT: - print("null"); - break; - default: - print("\"" + Convert.quote(tree.value.toString()) + "\""); - break; + if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_INT)) print(tree.value.toString()); + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_LONG)) print(tree.value + "L"); + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_FLOAT)) print(tree.value + "F"); + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_DOUBLE)) print(tree.value.toString()); + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_CHAR)) { + print("\'" + + Convert.quote( + String.valueOf((char)((Number)tree.value).intValue()))+ + "\'"); } + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOOLEAN)) print(((Number)tree.value).intValue() == 1 ? "true" : "false"); + else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOT)) print("null"); + else print("\"" + Convert.quote(tree.value.toString()) + "\""); } catch (IOException e) { throw new UncheckedIOException(e); } } - public void visitTypeIdent(JCPrimitiveTypeTree tree) { - try { - switch(tree.typetag) { - case TypeTags.BYTE: - print("byte"); - break; - case TypeTags.CHAR: - print("char"); - break; - case TypeTags.SHORT: - print("short"); - break; - case TypeTags.INT: - print("int"); - break; - case TypeTags.LONG: - print("long"); - break; - case TypeTags.FLOAT: - print("float"); - break; - case TypeTags.DOUBLE: - print("double"); - break; - case TypeTags.BOOLEAN: - print("boolean"); - break; - case TypeTags.VOID: - print("void"); - break; - default: - print("error"); - break; - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } + public void visitTypeIdent(JCPrimitiveTypeTree tree) { + Object typetag = Javac.getTreeTypeTag(tree); + try { + if (Javac.compareCTC(typetag, Javac.CTC_BYTE)) print("byte"); + else if (Javac.compareCTC(typetag, Javac.CTC_CHAR)) print("char"); + else if (Javac.compareCTC(typetag, Javac.CTC_SHORT)) print("short"); + else if (Javac.compareCTC(typetag, Javac.CTC_INT)) print("int"); + else if (Javac.compareCTC(typetag, Javac.CTC_LONG)) print("long"); + else if (Javac.compareCTC(typetag, Javac.CTC_FLOAT)) print("float"); + else if (Javac.compareCTC(typetag, Javac.CTC_DOUBLE)) print("double"); + else if (Javac.compareCTC(typetag, Javac.CTC_BOOLEAN)) print("boolean"); + else if (Javac.compareCTC(typetag, Javac.CTC_VOID)) print("void"); + else print("error"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } public void visitTypeArray(JCArrayTypeTree tree) { diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 75bb2dbf..cbbd6730 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -21,29 +21,33 @@ */ package lombok.javac; +import java.lang.reflect.Method; import java.util.regex.Pattern; -import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCLiteral; +import com.sun.tools.javac.tree.JCTree.JCUnary; +import com.sun.tools.javac.tree.TreeMaker; /** * Container for static utility methods relevant to lombok's operation on javac. */ public class Javac { private Javac() { - //prevent instantiation + // prevent instantiation } /** Matches any of the 8 primitive names, such as {@code boolean}. */ - private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile( - "^(boolean|byte|short|int|long|float|double|char)$"); + private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile("^(boolean|byte|short|int|long|float|double|char)$"); /** - * Checks if the given expression (that really ought to refer to a type expression) represents a primitive type. + * Checks if the given expression (that really ought to refer to a type + * expression) represents a primitive type. */ public static boolean isPrimitive(JCExpression ref) { String typeName = ref.toString(); @@ -51,15 +55,16 @@ public class Javac { } /** - * Turns an expression into a guessed intended literal. Only works for literals, as you can imagine. + * Turns an expression into a guessed intended literal. Only works for + * literals, as you can imagine. * * Will for example turn a TrueLiteral into 'Boolean.valueOf(true)'. */ public static Object calculateGuess(JCExpression expr) { if (expr instanceof JCLiteral) { - JCLiteral lit = (JCLiteral)expr; + JCLiteral lit = (JCLiteral) expr; if (lit.getKind() == com.sun.source.tree.Tree.Kind.BOOLEAN_LITERAL) { - return ((Number)lit.value).intValue() == 0 ? false : true; + return ((Number) lit.value).intValue() == 0 ? false : true; } return lit.value; } else if (expr instanceof JCIdent || expr instanceof JCFieldAccess) { @@ -70,45 +75,207 @@ public class Javac { if (idx > -1) x = x.substring(idx + 1); } return x; - } else return null; + } else + return null; } - public static final int CTC_BOOLEAN = getCtcInt(TypeTags.class, "BOOLEAN"); - public static final int CTC_INT = getCtcInt(TypeTags.class, "INT"); - public static final int CTC_DOUBLE = getCtcInt(TypeTags.class, "DOUBLE"); - public static final int CTC_FLOAT = getCtcInt(TypeTags.class, "FLOAT"); - public static final int CTC_SHORT = getCtcInt(TypeTags.class, "SHORT"); - public static final int CTC_BYTE = getCtcInt(TypeTags.class, "BYTE"); - public static final int CTC_LONG = getCtcInt(TypeTags.class, "LONG"); - public static final int CTC_CHAR = getCtcInt(TypeTags.class, "CHAR"); - public static final int CTC_VOID = getCtcInt(TypeTags.class, "VOID"); - public static final int CTC_NONE = getCtcInt(TypeTags.class, "NONE"); - - public static final int CTC_NOT_EQUAL = getCtcInt(JCTree.class, "NE"); - public static final int CTC_NOT = getCtcInt(JCTree.class, "NOT"); - public static final int CTC_BITXOR = getCtcInt(JCTree.class, "BITXOR"); - public static final int CTC_UNSIGNED_SHIFT_RIGHT = getCtcInt(JCTree.class, "USR"); - public static final int CTC_MUL = getCtcInt(JCTree.class, "MUL"); - public static final int CTC_PLUS = getCtcInt(JCTree.class, "PLUS"); - public static final int CTC_BOT = getCtcInt(TypeTags.class, "BOT"); - public static final int CTC_EQUAL = getCtcInt(JCTree.class, "EQ"); + public static final Object CTC_BOOLEAN = getTypeTag("BOOLEAN"); + public static final Object CTC_INT = getTypeTag("INT"); + public static final Object CTC_DOUBLE = getTypeTag("DOUBLE"); + public static final Object CTC_FLOAT = getTypeTag("FLOAT"); + public static final Object CTC_SHORT = getTypeTag("SHORT"); + public static final Object CTC_BYTE = getTypeTag("BYTE"); + public static final Object CTC_LONG = getTypeTag("LONG"); + public static final Object CTC_CHAR = getTypeTag("CHAR"); + public static final Object CTC_VOID = getTypeTag("VOID"); + public static final Object CTC_NONE = getTypeTag("NONE"); + public static final Object CTC_BOT = getTypeTag("BOT"); + public static final Object CTC_CLASS = getTypeTag("CLASS"); + + public static final Object CTC_NOT_EQUAL = getTreeTag("NE"); + public static final Object CTC_NOT = getTreeTag("NOT"); + public static final Object CTC_BITXOR = getTreeTag("BITXOR"); + public static final Object CTC_UNSIGNED_SHIFT_RIGHT = getTreeTag("USR"); + public static final Object CTC_MUL = getTreeTag("MUL"); + public static final Object CTC_PLUS = getTreeTag("PLUS"); + public static final Object CTC_EQUAL = getTreeTag("EQ"); + +// /** +// * Retrieves the current ordinal position of a type tag. +// * +// * For JDK 8 this is the ordinal position within the +// * com.sun.tools.javac.code.TypeTag enum for JDK 7 and lower, +// * this is the value of the constant within +// * com.sun.tools.javac.code.TypeTags +// * +// * Solves the problem of compile time constant inlining, resulting in lombok +// * having the wrong value (javac compiler changes private api constants from +// * time to time). +// * +// * @param identifier +// * @return the ordinal value of the typetag constant +// */ +// public static int getTypeTag(String identifier) { +// try { +// if (JavaCompiler.version().startsWith("1.8")) { +// Object enumInstance = Class.forName("com.sun.tools.javac.code.TypeTag").getField(identifier).get(null); +// return (int) Class.forName("com.sun.tools.javac.code.TypeTag").getField("order").get(enumInstance); +// +// } else { +// return (int) Class.forName("com.sun.tools.javac.code.TypeTags").getField(identifier).get(null); +// } +// } catch (NoSuchFieldException e) { +// throw new RuntimeException(e); +// } catch (IllegalAccessException e) { +// throw new RuntimeException(e); +// } catch (Exception e) { +// if (e instanceof RuntimeException) throw (RuntimeException) e; +// throw new RuntimeException(e); +// } +// } + + + + public static boolean compareCTC(Object ctc1, Object ctc2) { + return ctc1.equals(ctc2); + } /** - * Retrieves a compile time constant of type int from the specified class location. + * Retrieves the current type tag. The actual type object differs depending on the Compiler version + * + * For JDK 8 this is an enum value of type com.sun.tools.javac.code.TypeTag + * for JDK 7 and lower, this is the value of the constant within com.sun.tools.javac.code.TypeTags * - * Solves the problem of compile time constant inlining, resulting in lombok having the wrong value - * (javac compiler changes private api constants from time to time) + * Solves the problem of compile time constant inlining, resulting in lombok + * having the wrong value (javac compiler changes private api constants from + * time to time). * - * @param ctcLocation location of the compile time constant - * @param identifier the name of the field of the compile time constant. + * @param identifier + * @return the ordinal value of the typetag constant */ - public static int getCtcInt(Class ctcLocation, String identifier) { + public static Object getTypeTag(String identifier) { try { - return (Integer)ctcLocation.getField(identifier).get(null); + if (JavaCompiler.version().startsWith("1.8")) { + return Class.forName("com.sun.tools.javac.code.TypeTag").getField(identifier).get(null); + } else { + return Class.forName("com.sun.tools.javac.code.TypeTags").getField(identifier).get(null); + } } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + public static Object getTreeTag(String identifier) { + try { + if (JavaCompiler.version().startsWith("1.8")) { + return Class.forName("com.sun.tools.javac.tree.JCTree$Tag").getField(identifier).get(null); + } else { + return Class.forName("com.sun.tools.javac.tree.JCTree").getField(identifier).get(null); + } + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); } } + + + public static Object getTreeTypeTag(JCTree tree) { + try { + return TreeMaker.class.getField("typetag").get(tree); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + public static JCExpression makeTypeIdent(TreeMaker maker, Object ctc) { + try { + Method createIdent; + if (JavaCompiler.version().startsWith("1.8")) { + createIdent = TreeMaker.class.getMethod("TypeIdent", Class.forName("com.sun.tools.javac.code.TypeTag")); + } else { + createIdent = TreeMaker.class.getMethod("TypeIdent", Integer.TYPE); + } + return (JCExpression) createIdent.invoke(maker, ctc); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + public static JCLiteral makeLiteral(TreeMaker maker, Object ctc, Object argument) { + try { + Method createLiteral; + if (JavaCompiler.version().startsWith("1.8")) { + createLiteral = TreeMaker.class.getMethod("Literal", Class.forName("com.sun.tools.javac.code.TypeTag"), Object.class); + } else { + createLiteral = TreeMaker.class.getMethod("Literal", Integer.TYPE, Object.class); + } + return (JCLiteral) createLiteral.invoke(maker, ctc, argument); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + public static JCUnary makeUnary(TreeMaker maker, Object ctc, JCExpression argument) { + try { + Method createUnary; + if (JavaCompiler.version().startsWith("1.8")) { + createUnary = TreeMaker.class.getMethod("Unary", Class.forName("com.sun.tools.javac.code.TypeTag"), JCExpression.class); + } else { + createUnary = TreeMaker.class.getMethod("Unary", Integer.TYPE, JCExpression.class); + } + return (JCUnary) createUnary.invoke(maker, ctc, argument); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + public static JCBinary makeBinary(TreeMaker maker, Object ctc, JCExpression rhsArgument, JCExpression lhsArgument) { + try { + Method createUnary; + if (JavaCompiler.version().startsWith("1.8")) { + createUnary = TreeMaker.class.getMethod("Binary", Class.forName("com.sun.tools.javac.code.TypeTag"), JCExpression.class, JCExpression.class); + } else { + createUnary = TreeMaker.class.getMethod("Binary", Integer.TYPE, JCExpression.class, JCExpression.class); + } + return (JCBinary) createUnary.invoke(maker, ctc, rhsArgument, lhsArgument); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new RuntimeException(e); + } + } + + } -- cgit From 1b4d8669c48af215c38a73f6dfd15741619a1c45 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 23 Jul 2013 00:54:59 +0200 Subject: A source file with just @Getter in it now compiles in javac8, but there is still a looooong way to go. --- src/core/lombok/javac/JavacAST.java | 2 +- .../javac/handlers/HandleEqualsAndHashCode.java | 2 +- .../lombok/javac/handlers/HandleSneakyThrows.java | 3 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 4 +- .../lombok/delombok/PrettyCommentsPrinter.java | 4 +- src/utils/lombok/javac/CommentCatcher.java | 10 +- src/utils/lombok/javac/Javac.java | 126 ++++++++++++++++----- 7 files changed, 109 insertions(+), 42 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 36c51210..04d7540f 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -360,7 +360,7 @@ public class JavacAST extends AST { void removeDeferredErrors(JavacNode node) { DiagnosticPosition pos = node.get().pos(); JCCompilationUnit top = (JCCompilationUnit) top().get(); - removeFromDeferredDiagnostics(pos.getStartPosition(), pos.getEndPosition(top.endPositions)); + removeFromDeferredDiagnostics(pos.getStartPosition(), Javac.getEndPosition(pos, top)); } /** Supply either a position or a node (in that case, position of the node is used) */ diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 741e7e21..f5f1bbd6 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -139,7 +139,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler { JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null); JCExpression lombokLombokSneakyThrowNameRef = chainDots(node, "lombok", "Lombok", "sneakyThrow"); - JCBlock catchBody = maker.Block(0, List.of(maker.Throw(maker.Apply( + JCBlock catchBody = maker.Block(0, List.of(Javac.makeThrow(maker, maker.Apply( List.nil(), lombokLombokSneakyThrowNameRef, List.of(maker.Ident(node.toName("$ex"))))))); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 211f5d36..a9c47e78 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -946,8 +946,8 @@ public class JavacHandlerUtil { if (isPrimitive(varDecl.vartype)) return null; Name fieldName = varDecl.name; JCExpression npe = chainDots(variable, "java", "lang", "NullPointerException"); - JCTree exception = maker.NewClass(null, List.nil(), npe, List.of(maker.Literal(fieldName.toString())), null); - JCStatement throwStatement = maker.Throw(exception); + JCExpression exception = maker.NewClass(null, List.nil(), npe, List.of(maker.Literal(fieldName.toString())), null); + JCStatement throwStatement = Javac.makeThrow(maker, exception); JCBlock throwBlock = maker.Block(0, List.of(throwStatement)); return maker.If(Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(fieldName), Javac.makeLiteral(maker, CTC_BOT, null)), throwBlock, null); } diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 075cc64f..481380f7 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -742,9 +742,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { else print("class " + tree.name); printTypeParameters(tree.typarams); - if (tree.getExtendsClause() != null) { + if (Javac.getExtendsClause(tree) != null) { print(" extends "); - printExpr(tree.getExtendsClause()); + printExpr(Javac.getExtendsClause(tree)); } if (tree.implementing.nonEmpty()) { print(" implements "); diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java index 8d1e71c0..eb747554 100644 --- a/src/utils/lombok/javac/CommentCatcher.java +++ b/src/utils/lombok/javac/CommentCatcher.java @@ -25,8 +25,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.WeakHashMap; -import lombok.Lombok; - import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; @@ -73,9 +71,9 @@ public class CommentCatcher { } scannerFactory.getMethod("preRegister", Context.class).invoke(null, context); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw Javac.sneakyThrow(e.getCause()); } catch (Exception e) { - throw Lombok.sneakyThrow(e); + throw Javac.sneakyThrow(e); } } @@ -89,9 +87,9 @@ public class CommentCatcher { } parserFactory.getMethod("setInCompiler", JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw Javac.sneakyThrow(e.getCause()); } catch (Exception e) { - throw Lombok.sneakyThrow(e); + throw Javac.sneakyThrow(e); } } } diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index dfa51e00..1f2a7031 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -35,22 +35,23 @@ import javax.lang.model.type.NoType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeVisitor; -import lombok.Lombok; - import com.sun.tools.javac.code.Type; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; +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.TreeMaker; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; @@ -62,6 +63,9 @@ public class Javac { // prevent instantiation } + private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); + private static final ConcurrentMap TREE_TAG_CACHE = new ConcurrentHashMap(); + /** Matches any of the 8 primitive names, such as {@code boolean}. */ private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile("^(boolean|byte|short|int|long|float|double|char)$"); @@ -148,10 +152,6 @@ public class Javac { return ctc1 == null ? ctc2 == null : ctc1.equals(ctc2); } - private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); - private static final ConcurrentMap TREE_TAG_CACHE = new ConcurrentHashMap(); - - /** * Retrieves the provided TypeTag value, in a compiler version independent manner. * @@ -168,7 +168,7 @@ public class Javac { * @return the value of the typetag constant (either enum instance or an Integer object). */ public static Object getTypeTag(String identifier) { - return getFieldCached(TYPE_TAG_CACHE, getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.code.TypeTag" : "com.sun.tools.javac.code.TypeTags", identifier); + return getFieldCached(TYPE_TAG_CACHE, getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.code.TypeTags" : "com.sun.tools.javac.code.TypeTag", identifier); } public static Object getTreeTag(String identifier) { @@ -181,11 +181,11 @@ public class Javac { try { value = Class.forName(className).getField(fieldName).get(null); } catch (NoSuchFieldException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (ClassNotFoundException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } cache.putIfAbsent(fieldName, value); @@ -200,8 +200,8 @@ public class Javac { return tree.typetag; } - private static final Method createIdent, createLiteral, createUnary, createBinary; - + private static final Method createIdent, createLiteral, createUnary, createBinary, createThrow, getExtendsClause, getEndPosition; + static { if (getJavaCompilerVersion() < 8) { createIdent = getMethod(TreeMaker.class, "TypeIdent", int.class); @@ -220,23 +220,40 @@ public class Javac { if (getJavaCompilerVersion() < 8) { createUnary = getMethod(TreeMaker.class, "Unary", int.class, JCExpression.class); } else { - createUnary = getMethod(TreeMaker.class, "Unary", "com.sun.tools.javac.code.TypeTag", JCExpression.class.getName()); + createUnary = getMethod(TreeMaker.class, "Unary", "com.sun.tools.javac.tree.JCTree$Tag", JCExpression.class.getName()); } createUnary.setAccessible(true); if (getJavaCompilerVersion() < 8) { createBinary = getMethod(TreeMaker.class, "Binary", Integer.TYPE, JCExpression.class, JCExpression.class); } else { - createBinary = getMethod(TreeMaker.class, "Binary", "com.sun.tools.javac.code.TypeTag", JCExpression.class.getName(), JCExpression.class.getName()); + createBinary = getMethod(TreeMaker.class, "Binary", "com.sun.tools.javac.tree.JCTree$Tag", JCExpression.class.getName(), JCExpression.class.getName()); + } + createBinary.setAccessible(true); + + if (getJavaCompilerVersion() < 8) { + createThrow = getMethod(TreeMaker.class, "Throw", JCTree.class); + } else { + createThrow = getMethod(TreeMaker.class, "Throw", JCExpression.class); } createBinary.setAccessible(true); + + getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class[0]); + getExtendsClause.setAccessible(true); + + if (getJavaCompilerVersion() < 8) { + getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", java.util.Map.class); + } else { + getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", "com.sun.tools.javac.tree.EndPosTable"); + } + getEndPosition.setAccessible(true); } private static Method getMethod(Class clazz, String name, Class... paramTypes) { try { return clazz.getMethod(name, paramTypes); } catch (NoSuchMethodException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } } @@ -246,9 +263,9 @@ public class Javac { for (int i = 0; i < paramTypes.length; i++) c[i] = Class.forName(paramTypes[i]); return clazz.getMethod(name, c); } catch (NoSuchMethodException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (ClassNotFoundException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } } @@ -256,9 +273,9 @@ public class Javac { try { return (JCExpression) createIdent.invoke(maker, ctc); } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); } } @@ -266,9 +283,9 @@ public class Javac { try { return (JCLiteral) createLiteral.invoke(maker, ctc, argument); } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); } } @@ -276,9 +293,9 @@ public class Javac { try { return (JCUnary) createUnary.invoke(maker, ctc, argument); } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); } } @@ -286,9 +303,48 @@ public class Javac { try { return (JCBinary) createBinary.invoke(maker, ctc, lhsArgument, rhsArgument); } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); + } catch (InvocationTargetException e) { + throw sneakyThrow(e.getCause()); + } + } + + public static JCStatement makeThrow(TreeMaker maker, JCExpression expression) { + try { + return (JCStatement) createThrow.invoke(maker, expression); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); + } + } + + public static JCTree getExtendsClause(JCClassDecl decl) { + try { + return (JCTree) getExtendsClause.invoke(decl); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } catch (InvocationTargetException e) { + throw sneakyThrow(e.getCause()); + } + } + + public static Object getDocComments(JCCompilationUnit cu) { + try { + return JCCOMPILATIONUNIT_DOCCOMMENTS.get(cu); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } + } + + public static int getEndPosition(DiagnosticPosition pos, JCCompilationUnit top) { + try { + Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top); + return (Integer) getEndPosition.invoke(pos, endPositions); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } catch (InvocationTargetException e) { + throw sneakyThrow(e.getCause()); } } @@ -318,9 +374,9 @@ public class Javac { return (Type) JC_NO_TYPE.newInstance(); } } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InstantiationException e) { - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } } } @@ -343,7 +399,7 @@ public class Javac { } } - private static final Field JCTREE_TAG, JCLITERAL_TYPETAG, JCPRIMITIVETYPETREE_TYPETAG; + private static final Field JCTREE_TAG, JCLITERAL_TYPETAG, JCPRIMITIVETYPETREE_TYPETAG, JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS; private static final Method JCTREE_GETTAG; static { Field f = null; @@ -364,6 +420,18 @@ public class Javac { } catch (NoSuchFieldException e) {} JCPRIMITIVETYPETREE_TYPETAG = f; + f = null; + try { + f = JCCompilationUnit.class.getDeclaredField("endPositions"); + } catch (NoSuchFieldException e) {} + JCCOMPILATIONUNIT_ENDPOSITIONS = f; + + f = null; + try { + f = JCCompilationUnit.class.getDeclaredField("docComments"); + } catch (NoSuchFieldException e) {} + JCCOMPILATIONUNIT_DOCCOMMENTS = f; + Method m = null; try { m = JCTree.class.getDeclaredMethod("getTag"); @@ -424,7 +492,7 @@ public class Javac { } } - private static RuntimeException sneakyThrow(Throwable t) { + static RuntimeException sneakyThrow(Throwable t) { if (t == null) throw new NullPointerException("t"); Javac.sneakyThrow0(t); return null; -- cgit From e2af5ed0c7786e01bec861f21f2e5ec3bc5ea33f Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 26 Jul 2013 07:15:07 +0200 Subject: experiment: Can we wrap TreeMaker and remove a heck of a lot of opportunity to program handlers that are not cross javac6-8 compatible? --- src/core/lombok/javac/JavacAST.java | 6 +- src/core/lombok/javac/JavacNode.java | 3 +- src/core/lombok/javac/JavacResolution.java | 2 +- src/core/lombok/javac/handlers/HandleBuilder.java | 17 +- src/core/lombok/javac/handlers/HandleCleanup.java | 11 +- .../lombok/javac/handlers/HandleConstructor.java | 8 +- src/core/lombok/javac/handlers/HandleDelegate.java | 8 +- .../javac/handlers/HandleEqualsAndHashCode.java | 66 +- src/core/lombok/javac/handlers/HandleGetter.java | 24 +- src/core/lombok/javac/handlers/HandleLog.java | 8 +- src/core/lombok/javac/handlers/HandleSetter.java | 6 +- .../lombok/javac/handlers/HandleSneakyThrows.java | 7 +- .../lombok/javac/handlers/HandleSynchronized.java | 9 +- src/core/lombok/javac/handlers/HandleToString.java | 19 +- src/core/lombok/javac/handlers/HandleWither.java | 19 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 51 +- src/utils/lombok/javac/Javac.java | 231 ++----- src/utils/lombok/javac/JavacTreeMaker.java | 662 +++++++++++++++++++++ 18 files changed, 832 insertions(+), 325 deletions(-) create mode 100644 src/utils/lombok/javac/JavacTreeMaker.java (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 04d7540f..1f3b04a4 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -66,7 +66,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; public class JavacAST extends AST { private final Messager messager; private final JavacElements elements; - private final TreeMaker treeMaker; + private final JavacTreeMaker treeMaker; private final Symtab symtab; private final JavacTypes javacTypes; private final Log log; @@ -86,7 +86,7 @@ public class JavacAST extends AST { this.messager = messager; this.log = Log.instance(context); this.elements = JavacElements.instance(context); - this.treeMaker = TreeMaker.instance(context); + this.treeMaker = new JavacTreeMaker(TreeMaker.instance(context)); this.symtab = Symtab.instance(context); this.javacTypes = JavacTypes.instance(context); clearChanged(); @@ -135,7 +135,7 @@ public class JavacAST extends AST { } /** @return A TreeMaker instance that you can use to create new AST nodes. */ - public TreeMaker getTreeMaker() { + public JavacTreeMaker getTreeMaker() { treeMaker.at(-1); return treeMaker; } diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java index 16c06430..30a470a9 100644 --- a/src/core/lombok/javac/JavacNode.java +++ b/src/core/lombok/javac/JavacNode.java @@ -30,7 +30,6 @@ import lombok.core.AST.Kind; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.model.JavacTypes; 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.JCClassDecl; @@ -165,7 +164,7 @@ public class JavacNode extends lombok.core.LombokNode { } private JCMethodDecl generateBuildMethod(String name, Name staticName, JCExpression returnType, java.util.List fieldNames, JavacNode type, List thrownExceptions) { - TreeMaker maker = type.getTreeMaker(); + JavacTreeMaker maker = type.getTreeMaker(); JCExpression call; JCStatement statement; @@ -239,7 +240,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName); call = maker.Apply(typeParams.toList(), fn, args.toList()); - if (returnType instanceof JCPrimitiveTypeTree && compareCTC(getTypeTag((JCPrimitiveTypeTree) returnType), CTC_VOID)) { + if (returnType instanceof JCPrimitiveTypeTree && compareCTC(Javac.getTypeTag((JCPrimitiveTypeTree) returnType), CTC_VOID)) { statement = maker.Exec(call); } else { statement = maker.Return(call); @@ -252,7 +253,7 @@ public class HandleBuilder extends JavacAnnotationHandler { } private JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, JavacNode type, List typeParams) { - TreeMaker maker = type.getTreeMaker(); + JavacTreeMaker maker = type.getTreeMaker(); ListBuffer typeArgs = ListBuffer.lb(); for (JCTypeParameter typeParam : typeParams) { @@ -285,7 +286,7 @@ public class HandleBuilder extends JavacAnnotationHandler { 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 { 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.nil(), List.nil()); } @@ -322,9 +323,9 @@ public class HandleBuilder extends JavacAnnotationHandler { } private JavacNode makeBuilderClass(JavacNode tdParent, String builderClassName, List 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.nil(), List.nil()); + JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.nil(), List.nil()); return injectType(tdParent, builder); } } diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 790d8964..417d2815 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -26,9 +26,9 @@ import static lombok.javac.Javac.*; import lombok.Cleanup; 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 org.mangosdk.spi.ProviderFor; @@ -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; @@ -114,13 +113,13 @@ public class HandleCleanup extends JavacAnnotationHandler { } 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 cleanupCall = List.of(maker.Exec( maker.Apply(List.nil(), cleanupMethod, List.nil()))); JCMethodInvocation preventNullAnalysis = preventNullAnalysis(maker, annotationNode, maker.Ident(decl.name)); - JCBinary isNull = Javac.makeBinary(maker, CTC_NOT_EQUAL, preventNullAnalysis, Javac.makeLiteral(maker, CTC_BOT, null)); + JCBinary isNull = maker.Binary(CTC_NOT_EQUAL, preventNullAnalysis, maker.Literal(CTC_BOT, null)); JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null); @@ -139,9 +138,9 @@ public class HandleCleanup extends JavacAnnotationHandler { 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.nil(), chainDotsString(node, "java.util.Collections.singletonList"), List.of(expression)); - JCMethodInvocation cleanedExpr = maker.Apply(List.nil(), maker.Select(singletonList, node.toName("get")) , List.of(Javac.makeLiteral(maker, CTC_INT, 0))); + JCMethodInvocation cleanedExpr = maker.Apply(List.nil(), maker.Select(singletonList, node.toName("get")) , List.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..1134c45c 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; @@ -206,7 +206,7 @@ public class HandleConstructor { private static void addConstructorProperties(JCModifiers mods, JavacNode node, List fields) { if (fields.isEmpty()) return; - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties"); ListBuffer fieldNames = ListBuffer.lb(); for (JavacNode field : fields) { @@ -218,7 +218,7 @@ public class HandleConstructor { } static JCMethodDecl createConstructor(AccessLevel level, List onConstructor, JavacNode typeNode, List 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; @@ -261,7 +261,7 @@ public class HandleConstructor { } private JCMethodDecl createStaticConstructor(String name, AccessLevel level, JavacNode typeNode, List fields, JCTree source) { - TreeMaker maker = typeNode.getTreeMaker(); + JavacTreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); JCModifiers mods = maker.Modifiers(Flags.STATIC | toJavacModifier(level)); diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index 644b03fb..33627072 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 { checkConflictOfTypeVarNames(sig, annotation); - TreeMaker maker = annotation.getTreeMaker(); + JavacTreeMaker maker = annotation.getTreeMaker(); com.sun.tools.javac.util.List annotations; if (sig.isDeprecated) { @@ -394,13 +394,13 @@ public class HandleDelegate extends JavacAnnotationHandler { METHOD { public JCExpression get(final JavacNode node, final Name name) { com.sun.tools.javac.util.List 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 f5f1bbd6..88ab3871 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -34,6 +34,7 @@ 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; @@ -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; @@ -219,11 +219,11 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler 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.nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); - JCExpression returnType = Javac.makeTypeIdent(maker, CTC_INT); + JCExpression returnType = maker.TypeIdent(CTC_INT); ListBuffer statements = ListBuffer.lb(); Name primeName = typeNode.toName(PRIME_NAME); @@ -231,12 +231,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), chainDots(typeNode, "java", "lang", "Double", "doubleToLongBits"), List.of(fieldAccessor)); - statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), dollarFieldName, Javac.makeTypeIdent(maker, CTC_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; @@ -306,7 +306,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")), List.nil()); - JCExpression thisEqualsNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(dollarFieldName), Javac.makeLiteral(maker, CTC_BOT, null)); + JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(dollarFieldName), maker.Literal(CTC_BOT, null)); statements.append(createResultCalculation(typeNode, maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall))); } } @@ -322,19 +322,19 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler>> 32 ^ ref) */ - JCExpression shift = Javac.makeBinary(maker, CTC_UNSIGNED_SHIFT_RIGHT, ref1, maker.Literal(32)); - JCExpression xorBits = Javac.makeBinary(maker, CTC_BITXOR, shift, ref2); - return maker.TypeCast(Javac.makeTypeIdent(maker, CTC_INT), xorBits); + JCExpression shift = maker.Binary(CTC_UNSIGNED_SHIFT_RIGHT, ref1, maker.Literal(32)); + JCExpression xorBits = maker.Binary(CTC_BITXOR, shift, ref2); + return maker.TypeCast(maker.TypeIdent(CTC_INT), xorBits); } private JCExpression createTypeReference(JavacNode type) { @@ -347,7 +347,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler 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"); @@ -368,19 +368,19 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); - JCExpression returnType = Javac.makeTypeIdent(maker, CTC_BOOLEAN); + JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); ListBuffer statements = ListBuffer.lb(); final List params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null)); /* if (o == this) return true; */ { - statements.append(maker.If(Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(oName), + statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null)); } /* if (!(o instanceof Outer.Inner.MyType) return false; */ { - JCUnary notInstanceOf = Javac.makeUnary(maker, CTC_NOT, maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); + JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } @@ -415,7 +415,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.of(maker.Ident(oName))); - JCUnary superNotEqual = Javac.makeUnary(maker, CTC_NOT, callToSuper); + JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper); statements.append(maker.If(superNotEqual, returnBool(maker, false), null)); } @@ -447,7 +447,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler args = List.of(thisFieldAccessor, otherFieldAccessor); - statements.append(maker.If(Javac.makeUnary(maker, CTC_NOT, + statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.nil(), eqMethod, args)), returnBool(maker, false), null)); } else /* objects */ { /* final java.lang.Object this$fieldName = this.fieldName; */ @@ -471,12 +471,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.of(maker.Ident(otherDollarFieldName))); - JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, Javac.makeUnary(maker, CTC_NOT, thisEqualsThat)); + JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat)); statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null)); } } @@ -494,10 +494,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); - JCExpression returnType = Javac.makeTypeIdent(maker, CTC_BOOLEAN); + JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN); Name canEqualName = typeNode.toName("canEqual"); JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); Name otherName = typeNode.toName("other"); @@ -510,16 +510,16 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler args = List.of(thisDotField, otherDotField); - JCBinary compareCallEquals0 = Javac.makeBinary(maker, CTC_NOT_EQUAL, maker.Apply( + JCBinary compareCallEquals0 = maker.Binary(CTC_NOT_EQUAL, maker.Apply( List.nil(), maker.Select(clazz, node.toName("compare")), args), maker.Literal(0)); return maker.If(compareCallEquals0, returnBool(maker, false), null); } - private JCStatement returnBool(TreeMaker maker, boolean bool) { - return maker.Return(Javac.makeLiteral(maker, CTC_BOOLEAN, bool ? 1 : 0)); + 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 c5ec6f60..f5bf2b6c 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -38,6 +38,7 @@ 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; @@ -58,7 +59,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; @@ -214,7 +214,7 @@ public class HandleGetter extends JavacAnnotationHandler { 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 onMethod) { + private JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, boolean lazy, List onMethod) { JCVariableDecl fieldNode = (JCVariableDecl) field.get(); // Remember the type; lazy will change it @@ -281,7 +281,7 @@ public class HandleGetter extends JavacAnnotationHandler { return delegates; } - private List createSimpleGetterBody(TreeMaker treeMaker, JavacNode field) { + private List createSimpleGetterBody(JavacTreeMaker treeMaker, JavacNode field) { return List.of(treeMaker.Return(createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD))); } @@ -303,7 +303,7 @@ public class HandleGetter extends JavacAnnotationHandler { TYPE_MAP = Collections.unmodifiableMap(m); } - private List createLazyGetterBody(TreeMaker maker, JavacNode fieldNode, JCTree source) { + private List createLazyGetterBody(JavacTreeMaker maker, JavacNode fieldNode, JCTree source) { /* java.lang.Object value = this.fieldName.get(); if (value == null) { @@ -374,7 +374,7 @@ public class HandleGetter extends JavacAnnotationHandler { } /* [ELSE] value = actualValue == null ? this.fieldName : actualValue; */ { if (!isPrimitive) { - JCExpression actualValueIsNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(actualValueName), Javac.makeLiteral(maker, CTC_BOT, null)); + JCExpression actualValueIsNull = maker.Binary(CTC_EQUAL, maker.Ident(actualValueName), maker.Literal(CTC_BOT, null)); JCExpression thisDotFieldName = createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD); JCExpression ternary = maker.Conditional(actualValueIsNull, thisDotFieldName, maker.Ident(actualValueName)); JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), ternary)); @@ -386,7 +386,7 @@ public class HandleGetter extends JavacAnnotationHandler { innerIfStatements.append(statement); } - JCBinary isNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(valueName), Javac.makeLiteral(maker, CTC_BOT, null)); + JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements.toList()), null); synchronizedStatements.append(ifStatement); } @@ -394,7 +394,7 @@ public class HandleGetter extends JavacAnnotationHandler { synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements.toList())); } - JCBinary isNull = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(valueName), Javac.makeLiteral(maker, CTC_BOT, null)); + JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, List.of(synchronizedStatement)), null); statements.append(ifStatement); } @@ -405,8 +405,8 @@ public class HandleGetter extends JavacAnnotationHandler { } /* [ELSE] return (BoxedValueType) (value == this.fieldName ? null : value); */ { if (!isPrimitive) { - JCExpression valueEqualsSelf = Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(valueName), createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)); - JCExpression ternary = maker.Conditional(valueEqualsSelf, Javac.makeLiteral(maker, CTC_BOT, null), maker.Ident(valueName)); + JCExpression valueEqualsSelf = maker.Binary(CTC_EQUAL, maker.Ident(valueName), createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)); + JCExpression ternary = maker.Conditional(valueEqualsSelf, maker.Literal(CTC_BOT, null), maker.Ident(valueName)); JCExpression typeCast = maker.TypeCast(copyOfBoxedFieldType, maker.Parens(ternary)); statements.append(maker.Return(typeCast)); } @@ -424,16 +424,16 @@ public class HandleGetter extends JavacAnnotationHandler { } 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.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 log = (); 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.nil(), method, List.nil()); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index c3ee10a3..1f8caa9b 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -34,6 +34,7 @@ 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; @@ -50,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; @@ -190,13 +190,13 @@ public class HandleSetter extends JavacAnnotationHandler { injectMethod(fieldNode.up(), createdSetter); } - static JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List onMethod, List onParam) { + static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, List onMethod, List 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 onMethod, List onParam) { + static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JCTree source, List onMethod, List onParam) { if (setterName == null) return null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index 8172cf35..69d2b45d 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -29,15 +29,14 @@ import java.util.Collections; import lombok.SneakyThrows; import lombok.core.AnnotationValues; -import lombok.javac.Javac; 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; @@ -114,7 +113,7 @@ public class HandleSneakyThrows extends JavacAnnotationHandler { } private JCStatement buildTryCatchBlock(JavacNode node, List contents, String exception, JCTree source) { - TreeMaker maker = node.getTreeMaker(); + JavacTreeMaker maker = node.getTreeMaker(); JCBlock tryBlock = setGeneratedBy(maker.Block(0, contents), source); @@ -122,7 +121,7 @@ public class HandleSneakyThrows extends JavacAnnotationHandler { JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null); JCExpression lombokLombokSneakyThrowNameRef = chainDots(node, "lombok", "Lombok", "sneakyThrow"); - JCBlock catchBody = maker.Block(0, List.of(Javac.makeThrow(maker, maker.Apply( + JCBlock catchBody = maker.Block(0, List.of(maker.Throw(maker.Apply( List.nil(), lombokLombokSneakyThrowNameRef, List.of(maker.Ident(node.toName("$ex"))))))); diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index 2737eeb2..b173f8fb 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,9 +26,9 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import lombok.Synchronized; 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.MemberExistsResult; import org.mangosdk.spi.ProviderFor; @@ -40,7 +40,6 @@ 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; /** @@ -78,7 +77,7 @@ public class HandleSynchronized extends JavacAnnotationHandler { 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) { @@ -88,7 +87,7 @@ public class HandleSynchronized extends JavacAnnotationHandler { JCExpression objectType = chainDots(methodNode, ast.pos, "java", "lang", "Object"); //We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable! JCNewArray newObjectArray = maker.NewArray(chainDots(methodNode, ast.pos, "java", "lang", "Object"), - List.of(Javac.makeLiteral(maker, CTC_INT, 0)), null); + List.of(maker.Literal(CTC_INT, 0)), null); JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray), ast); diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 8297a4db..ea526009 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 @@ -29,15 +29,14 @@ import java.util.Collection; import lombok.ToString; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; -import lombok.javac.Javac; 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; @@ -168,7 +167,7 @@ public class HandleToString extends JavacAnnotationHandler { } static JCMethodDecl createToString(JavacNode typeNode, Collection 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.nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); @@ -196,7 +195,7 @@ public class HandleToString extends JavacAnnotationHandler { JCMethodInvocation callToSuper = maker.Apply(List.nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.nil()); - current = Javac.makeBinary(maker, CTC_PLUS, current, callToSuper); + current = maker.Binary(CTC_PLUS, current, callToSuper); first = false; } @@ -220,21 +219,21 @@ public class HandleToString extends JavacAnnotationHandler { } else expr = fieldAccessor; if (first) { - current = Javac.makeBinary(maker, CTC_PLUS, current, expr); + current = maker.Binary(CTC_PLUS, current, expr); first = false; continue; } if (includeFieldNames) { - current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "=")); + current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "=")); } else { - current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(infix)); + current = maker.Binary(CTC_PLUS, current, maker.Literal(infix)); } - current = Javac.makeBinary(maker, CTC_PLUS, current, expr); + current = maker.Binary(CTC_PLUS, current, expr); } - if (!first) current = Javac.makeBinary(maker, CTC_PLUS, current, maker.Literal(suffix)); + if (!first) current = maker.Binary(CTC_PLUS, current, maker.Literal(suffix)); JCStatement returnStatement = maker.Return(current); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 514e27dd..9397caa0 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -31,9 +31,9 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.experimental.Wither; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; @@ -52,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; @@ -202,7 +201,7 @@ public class HandleWither extends JavacAnnotationHandler { injectMethod(fieldNode.up(), createdWither); } - private JCMethodDecl createWither(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List onMethod, List onParam) { + private JCMethodDecl createWither(long access, JavacNode field, JavacTreeMaker maker, JCTree source, List onMethod, List onParam) { String witherName = toWitherName(field); if (witherName == null) return null; @@ -215,13 +214,11 @@ public class HandleWither extends JavacAnnotationHandler { Name methodName = field.toName(witherName); List 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, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); JCExpression selfType = cloneSelfType(field); if (selfType == null) return null; - TreeMaker maker = field.getTreeMaker(); - ListBuffer args = ListBuffer.lb(); for (JavacNode child : field.up().down()) { if (child.getKind() != Kind.FIELD) continue; @@ -241,21 +238,21 @@ public class HandleWither extends JavacAnnotationHandler { } JCNewClass newClass = maker.NewClass(null, List.nil(), selfType, args.toList(), null); - JCExpression identityCheck = Javac.makeBinary(maker, CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name)); + JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name)); JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass); JCReturn returnStatement = maker.Return(conditional); 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 methodGenericParams = List.nil(); List parameters = List.of(param); List throwsClauses = List.nil(); @@ -264,9 +261,9 @@ public class HandleWither extends JavacAnnotationHandler { List annsOnMethod = copyAnnotations(onMethod); if (isFieldDeprecated(field)) { - annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.nil())); + annsOnMethod = annsOnMethod.prepend(maker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.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 a9c47e78..630cc31a 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -44,8 +44,8 @@ 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; @@ -73,7 +73,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; @@ -430,7 +429,7 @@ 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(); @@ -708,11 +707,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; @@ -840,7 +839,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; @@ -891,7 +890,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++) { @@ -941,15 +940,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 maker, 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"); JCExpression exception = maker.NewClass(null, List.nil(), npe, List.of(maker.Literal(fieldName.toString())), null); - JCStatement throwStatement = Javac.makeThrow(maker, exception); + JCStatement throwStatement = maker.Throw(exception); JCBlock throwBlock = maker.Block(0, List.of(throwStatement)); - return maker.If(Javac.makeBinary(maker, CTC_EQUAL, maker.Ident(fieldName), Javac.makeLiteral(maker, CTC_BOT, null)), throwBlock, null); + return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), throwBlock, null); } /** @@ -1050,14 +1049,14 @@ public class JavacHandlerUtil { return result.toList(); } - public static List copyTypeParams(TreeMaker maker, List params) { + public static List copyTypeParams(JavacTreeMaker maker, List params) { if (params == null || params.isEmpty()) return params; ListBuffer out = ListBuffer.lb(); for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); return out.toList(); } - public static JCExpression namePlusTypeParamsToTypeReference(TreeMaker maker, Name typeName, List params) { + public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List params) { ListBuffer typeArgs = ListBuffer.lb(); if (!params.isEmpty()) { @@ -1136,13 +1135,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; @@ -1278,17 +1277,17 @@ public class JavacHandlerUtil { */ public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) { 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]); - } - } - } catch (Exception ignore) {} +// 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]); +// } +// } +// } catch (Exception ignore) {} } } diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 1f2a7031..b0540997 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -21,12 +21,12 @@ */ package lombok.javac; +import static lombok.javac.JavacTreeMaker.TreeTag.treeTag; +import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; + import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -35,25 +35,20 @@ import javax.lang.model.type.NoType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeVisitor; +import lombok.javac.JavacTreeMaker.TreeTag; +import lombok.javac.JavacTreeMaker.TypeTag; + import com.sun.tools.javac.code.Type; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCLiteral; -import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; -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.TreeMaker; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; -import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Name; /** * Container for static utility methods relevant to lombok's operation on javac. @@ -63,9 +58,6 @@ public class Javac { // prevent instantiation } - private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); - private static final ConcurrentMap TREE_TAG_CACHE = new ConcurrentHashMap(); - /** Matches any of the 8 primitive names, such as {@code boolean}. */ private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile("^(boolean|byte|short|int|long|float|double|char)$"); @@ -127,69 +119,39 @@ public class Javac { return null; } - public static final Object CTC_BOOLEAN = getTypeTag("BOOLEAN"); - public static final Object CTC_INT = getTypeTag("INT"); - public static final Object CTC_DOUBLE = getTypeTag("DOUBLE"); - public static final Object CTC_FLOAT = getTypeTag("FLOAT"); - public static final Object CTC_SHORT = getTypeTag("SHORT"); - public static final Object CTC_BYTE = getTypeTag("BYTE"); - public static final Object CTC_LONG = getTypeTag("LONG"); - public static final Object CTC_CHAR = getTypeTag("CHAR"); - public static final Object CTC_VOID = getTypeTag("VOID"); - public static final Object CTC_NONE = getTypeTag("NONE"); - public static final Object CTC_BOT = getTypeTag("BOT"); - public static final Object CTC_CLASS = getTypeTag("CLASS"); - - public static final Object CTC_NOT_EQUAL = getTreeTag("NE"); - public static final Object CTC_NOT = getTreeTag("NOT"); - public static final Object CTC_BITXOR = getTreeTag("BITXOR"); - public static final Object CTC_UNSIGNED_SHIFT_RIGHT = getTreeTag("USR"); - public static final Object CTC_MUL = getTreeTag("MUL"); - public static final Object CTC_PLUS = getTreeTag("PLUS"); - public static final Object CTC_EQUAL = getTreeTag("EQ"); - - public static boolean compareCTC(Object ctc1, Object ctc2) { - return ctc1 == null ? ctc2 == null : ctc1.equals(ctc2); - } - - /** - * Retrieves the provided TypeTag value, in a compiler version independent manner. - * - * The actual type object differs depending on the Compiler version: - *
    - *
  • For JDK 8 this is an enum value of type com.sun.tools.javac.code.TypeTag - *
  • for JDK 7 and lower, this is the value of the constant within com.sun.tools.javac.code.TypeTags - *
- * Solves the problem of compile time constant inlining, resulting in lombok - * having the wrong value (javac compiler changes private api constants from - * time to time). - * - * @param identifier Identifier to turn into a TypeTag. - * @return the value of the typetag constant (either enum instance or an Integer object). - */ - public static Object getTypeTag(String identifier) { - return getFieldCached(TYPE_TAG_CACHE, getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.code.TypeTags" : "com.sun.tools.javac.code.TypeTag", identifier); - } - - public static Object getTreeTag(String identifier) { - return getFieldCached(TREE_TAG_CACHE, getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.tree.JCTree" : "com.sun.tools.javac.tree.JCTree$Tag", identifier); + public static final TypeTag CTC_BOOLEAN = typeTag("BOOLEAN"); + public static final TypeTag CTC_INT = typeTag("INT"); + public static final TypeTag CTC_DOUBLE = typeTag("DOUBLE"); + public static final TypeTag CTC_FLOAT = typeTag("FLOAT"); + public static final TypeTag CTC_SHORT = typeTag("SHORT"); + public static final TypeTag CTC_BYTE = typeTag("BYTE"); + public static final TypeTag CTC_LONG = typeTag("LONG"); + public static final TypeTag CTC_CHAR = typeTag("CHAR"); + public static final TypeTag CTC_VOID = typeTag("VOID"); + public static final TypeTag CTC_NONE = typeTag("NONE"); + public static final TypeTag CTC_BOT = typeTag("BOT"); + public static final TypeTag CTC_CLASS = typeTag("CLASS"); + + public static final TreeTag CTC_NOT_EQUAL = treeTag("NE"); + public static final TreeTag CTC_NOT = treeTag("NOT"); + public static final TreeTag CTC_BITXOR = treeTag("BITXOR"); + public static final TreeTag CTC_UNSIGNED_SHIFT_RIGHT = treeTag("USR"); + public static final TreeTag CTC_MUL = treeTag("MUL"); + public static final TreeTag CTC_PLUS = treeTag("PLUS"); + public static final TreeTag CTC_EQUAL = treeTag("EQ"); + + public static boolean compareCTC(TreeTag ctc1, TreeTag ctc2) { + boolean ctc1IsNull = ctc1 == null || ctc1.value == null; + boolean ctc2IsNull = ctc2 == null || ctc2.value == null; + if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull; + return ctc1.value.equals(ctc2.value); } - private static Object getFieldCached(ConcurrentMap cache, String className, String fieldName) { - Object value = cache.get(fieldName); - if (value != null) return value; - try { - value = Class.forName(className).getField(fieldName).get(null); - } catch (NoSuchFieldException e) { - throw sneakyThrow(e); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (ClassNotFoundException e) { - throw sneakyThrow(e); - } - - cache.putIfAbsent(fieldName, value); - return value; + public static boolean compareCTC(TypeTag ctc1, TypeTag ctc2) { + boolean ctc1IsNull = ctc1 == null || ctc1.value == null; + boolean ctc2IsNull = ctc2 == null || ctc2.value == null; + if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull; + return ctc1.value.equals(ctc2.value); } public static Object getTreeTypeTag(JCPrimitiveTypeTree tree) { @@ -200,44 +162,9 @@ public class Javac { return tree.typetag; } - private static final Method createIdent, createLiteral, createUnary, createBinary, createThrow, getExtendsClause, getEndPosition; + private static final Method getExtendsClause, getEndPosition; static { - if (getJavaCompilerVersion() < 8) { - createIdent = getMethod(TreeMaker.class, "TypeIdent", int.class); - } else { - createIdent = getMethod(TreeMaker.class, "TypeIdent", "com.sun.tools.javac.code.TypeTag"); - } - createIdent.setAccessible(true); - - if (getJavaCompilerVersion() < 8) { - createLiteral = getMethod(TreeMaker.class, "Literal", int.class, Object.class); - } else { - createLiteral = getMethod(TreeMaker.class, "Literal", "com.sun.tools.javac.code.TypeTag", "java.lang.Object"); - } - createLiteral.setAccessible(true); - - if (getJavaCompilerVersion() < 8) { - createUnary = getMethod(TreeMaker.class, "Unary", int.class, JCExpression.class); - } else { - createUnary = getMethod(TreeMaker.class, "Unary", "com.sun.tools.javac.tree.JCTree$Tag", JCExpression.class.getName()); - } - createUnary.setAccessible(true); - - if (getJavaCompilerVersion() < 8) { - createBinary = getMethod(TreeMaker.class, "Binary", Integer.TYPE, JCExpression.class, JCExpression.class); - } else { - createBinary = getMethod(TreeMaker.class, "Binary", "com.sun.tools.javac.tree.JCTree$Tag", JCExpression.class.getName(), JCExpression.class.getName()); - } - createBinary.setAccessible(true); - - if (getJavaCompilerVersion() < 8) { - createThrow = getMethod(TreeMaker.class, "Throw", JCTree.class); - } else { - createThrow = getMethod(TreeMaker.class, "Throw", JCExpression.class); - } - createBinary.setAccessible(true); - getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class[0]); getExtendsClause.setAccessible(true); @@ -269,56 +196,6 @@ public class Javac { } } - public static JCExpression makeTypeIdent(TreeMaker maker, Object ctc) { - try { - return (JCExpression) createIdent.invoke(maker, ctc); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } - } - - public static JCLiteral makeLiteral(TreeMaker maker, Object ctc, Object argument) { - try { - return (JCLiteral) createLiteral.invoke(maker, ctc, argument); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } - } - - public static JCUnary makeUnary(TreeMaker maker, Object ctc, JCExpression argument) { - try { - return (JCUnary) createUnary.invoke(maker, ctc, argument); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } - } - - public static JCBinary makeBinary(TreeMaker maker, Object ctc, JCExpression lhsArgument, JCExpression rhsArgument) { - try { - return (JCBinary) createBinary.invoke(maker, ctc, lhsArgument, rhsArgument); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } - } - - public static JCStatement makeThrow(TreeMaker maker, JCExpression expression) { - try { - return (JCStatement) createThrow.invoke(maker, expression); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } - } - public static JCTree getExtendsClause(JCClassDecl decl) { try { return (JCTree) getExtendsClause.invoke(decl); @@ -363,9 +240,9 @@ public class Javac { JC_NO_TYPE = c; } - public static Type createVoidType(TreeMaker maker, Object tag) { + public static Type createVoidType(JavacTreeMaker maker, TypeTag tag) { if (Javac.getJavaCompilerVersion() < 8) { - return new JCNoType(((Integer) tag).intValue()); + return new JCNoType(((Integer) tag.value).intValue()); } else { try { if (compareCTC(tag, CTC_VOID)) { @@ -388,8 +265,8 @@ public class Javac { @Override public TypeKind getKind() { - if (Javac.compareCTC(tag, CTC_VOID)) return TypeKind.VOID; - if (Javac.compareCTC(tag, CTC_NONE)) return TypeKind.NONE; + if (tag == ((Integer) CTC_VOID.value).intValue()) return TypeKind.VOID; + if (tag == ((Integer) CTC_NONE.value).intValue()) return TypeKind.NONE; throw new AssertionError("Unexpected tag: " + tag); } @@ -468,30 +345,6 @@ public class Javac { } } - private static Method classDef; - - public static JCClassDecl ClassDef(TreeMaker maker, JCModifiers mods, Name name, List typarams, JCExpression extending, List implementing, List defs) { - if (classDef == null) try { - classDef = TreeMaker.class.getDeclaredMethod("ClassDef", JCModifiers.class, Name.class, List.class, JCExpression.class, List.class, List.class); - } catch (NoSuchMethodException ignore) {} - if (classDef == null) try { - classDef = TreeMaker.class.getDeclaredMethod("ClassDef", JCModifiers.class, Name.class, List.class, JCTree.class, List.class, List.class); - } catch (NoSuchMethodException ignore) {} - - if (classDef == null) throw new IllegalStateException("Lombok bug #20130617-1310: ClassDef doesn't look like anything we thought it would look like."); - if (!Modifier.isPublic(classDef.getModifiers()) && !classDef.isAccessible()) { - classDef.setAccessible(true); - } - - try { - return (JCClassDecl) classDef.invoke(maker, mods, name, typarams, extending, implementing, defs); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } catch (IllegalAccessException e) { - throw sneakyThrow(e.getCause()); - } - } - static RuntimeException sneakyThrow(Throwable t) { if (t == null) throw new NullPointerException("t"); Javac.sneakyThrow0(t); diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java new file mode 100644 index 00000000..916c8735 --- /dev/null +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -0,0 +1,662 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.BoundKind; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCArrayAccess; +import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; +import com.sun.tools.javac.tree.JCTree.JCAssert; +import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCAssignOp; +import com.sun.tools.javac.tree.JCTree.JCBinary; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCBreak; +import com.sun.tools.javac.tree.JCTree.JCCase; +import com.sun.tools.javac.tree.JCTree.JCCatch; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCConditional; +import com.sun.tools.javac.tree.JCTree.JCContinue; +import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; +import com.sun.tools.javac.tree.JCTree.JCErroneous; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCForLoop; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCIf; +import com.sun.tools.javac.tree.JCTree.JCImport; +import com.sun.tools.javac.tree.JCTree.JCInstanceOf; +import com.sun.tools.javac.tree.JCTree.JCLabeledStatement; +import com.sun.tools.javac.tree.JCTree.JCLiteral; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCModifiers; +import com.sun.tools.javac.tree.JCTree.JCNewArray; +import com.sun.tools.javac.tree.JCTree.JCNewClass; +import com.sun.tools.javac.tree.JCTree.JCParens; +import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; +import com.sun.tools.javac.tree.JCTree.JCReturn; +import com.sun.tools.javac.tree.JCTree.JCSkip; +import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSwitch; +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.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCTypeCast; +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.JCTree.JCWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCWildcard; +import com.sun.tools.javac.tree.JCTree.LetExpr; +import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Name; + +public class JavacTreeMaker { + private final TreeMaker tm; + + public JavacTreeMaker(TreeMaker tm) { + this.tm = tm; + } + + public JavacTreeMaker at(int pos) { + tm.at(pos); + return this; + } + + private static class MethodId { + private final String name; + private final Class returnType; + private final Class[] paramTypes; + + MethodId(String name, Class returnType, Class... types) { + this.name = name; + this.paramTypes = types; + this.returnType = returnType; + } + + } + + private static Object getFieldCached(ConcurrentMap cache, String className, String fieldName) { + Object value = cache.get(fieldName); + if (value != null) return value; + try { + value = Class.forName(className).getField(fieldName).get(null); + } catch (NoSuchFieldException e) { + throw Javac.sneakyThrow(e); + } catch (IllegalAccessException e) { + throw Javac.sneakyThrow(e); + } catch (ClassNotFoundException e) { + throw Javac.sneakyThrow(e); + } + + cache.putIfAbsent(fieldName, value); + return value; + } + + private static interface SchroedingerType {} + + public static class TypeTag implements SchroedingerType { + private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); + public final Object value; + + private TypeTag(Object value) { + this.value = value; + } + + public static TypeTag typeTag(String identifier) { + return new TypeTag(getFieldCached(TYPE_TAG_CACHE, Javac.getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.code.TypeTags" : "com.sun.tools.javac.code.TypeTag", identifier)); + } + } + + public static class TreeTag implements SchroedingerType { + private static final ConcurrentMap TREE_TAG_CACHE = new ConcurrentHashMap(); + public final Object value; + + private TreeTag(Object value) { + this.value = value; + } + + public static TreeTag treeTag(String identifier) { + return new TreeTag(getFieldCached(TREE_TAG_CACHE, Javac.getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.tree.JCTree" : "com.sun.tools.javac.tree.JCTree$Tag", identifier)); + } + } + + /** + * Creates a new method ID based on the name of the method to invoke, the return type of that method, and the types of the parameters. + * + * A method matches if the return type matches, and for each parameter the following holds: + * + * Either (A) the type listed here is the same as, or a subtype of, the type of the method in javac's TreeMaker, or + * (B) the type listed here is a subtype of SchroedingerType. + */ + static MethodId MethodId(String name, Class returnType, Class... types) { + return new MethodId(name, returnType, types); + } + + /** + * Creates a new method ID based on the name of a method in this class, assuming the name of the method to invoke in TreeMaker has the same name, + * the same return type, and the same parameters (under the same rules as the other MethodId method). + */ + static MethodId MethodId(String name) { + for (Method m : JavacTreeMaker.class.getDeclaredMethods()) { + if (m.getName().equals(name)) { + @SuppressWarnings("unchecked") Class r = (Class) m.getReturnType(); + Class[] p = m.getParameterTypes(); + return new MethodId(name, r, p); + } + } + + throw new InternalError("Not found: " + name); + } + + private static final ConcurrentHashMap, Method> METHOD_CACHE = new ConcurrentHashMap, Method>(); + private J invoke(MethodId m, Object... args) { + Method method = METHOD_CACHE.get(m); + if (method == null) method = addToCache(m); + try { + return m.returnType.cast(method.invoke(tm, args)); + } catch (InvocationTargetException e) { + throw Javac.sneakyThrow(e.getCause()); + } catch (IllegalAccessException e) { + throw Javac.sneakyThrow(e); + } + } + + private static Method addToCache(MethodId m) { + Method found = null; + + outer: + for (Method method : TreeMaker.class.getDeclaredMethods()) { + if (!m.name.equals(method.getName())) continue; + Class[] t = method.getParameterTypes(); + if (t.length != m.paramTypes.length) continue; + for (int i = 0; i < t.length; i++) { + if (Symbol.class.isAssignableFrom(t[i])) continue outer; + if (!SchroedingerType.class.isAssignableFrom(m.paramTypes[i])) { + if (t[i].isPrimitive()) { + if (t[i] != m.paramTypes[i]) continue outer; + } else { + if (t[i].isAssignableFrom(m.paramTypes[i])) continue outer; + } + } + } + if (found == null) found = method; + else throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m); + } + if (found == null) throw new IllegalStateException("Lombok TreeMaker frontedn issue: no match when looking for method: " + m); + found.setAccessible(true); + Object marker = METHOD_CACHE.putIfAbsent(m, found); + if (marker == null) return found; + return METHOD_CACHE.get(m); + } + + //javac versions: 6-8 + private static final MethodId TopLevel = MethodId("TopLevel"); + public JCCompilationUnit TopLevel(List packageAnnotations, JCExpression pid, List defs) { + return invoke(TopLevel, packageAnnotations, pid, defs); + } + + //javac versions: 6-8 + private static final MethodId Import = MethodId("Import"); + public JCImport Import(JCTree qualid, boolean staticImport) { + return invoke(Import, qualid, staticImport); + } + + //javac versions: 6-8 + private static final MethodId ClassDef = MethodId("ClassDef"); + public JCClassDecl ClassDef(JCModifiers mods, Name name, List typarams, JCExpression extending, List implementing, List defs) { + return invoke(ClassDef, mods, name, typarams, extending, implementing, defs); + } + + //javac versions: 6-8 + private static final MethodId MethodDef = MethodId("MethodDef", JCMethodDecl.class, JCModifiers.class, Name.class, JCExpression.class, List.class, List.class, List.class, JCBlock.class, JCExpression.class); + public JCMethodDecl MethodDef(JCModifiers mods, Name name, JCExpression resType, List typarams, List params, List thrown, JCBlock body, JCExpression defaultValue) { + return invoke(MethodDef, mods, name, resType, typarams, params, thrown, body, defaultValue); + } + + //javac versions: 8 + private static final MethodId MethodDefWithRecvParam = MethodId("MethodDef", JCMethodDecl.class, JCModifiers.class, Name.class, JCExpression.class, List.class, JCVariableDecl.class, List.class, List.class, JCBlock.class, JCExpression.class); + public JCMethodDecl MethodDef(JCModifiers mods, Name name, JCExpression resType, List typarams, JCVariableDecl recvparam, List params, List thrown, JCBlock body, JCExpression defaultValue) { + return invoke(MethodDefWithRecvParam, mods, name, resType, recvparam, typarams, params, thrown, body, defaultValue); + } + + //javac versions: 6-8 + private static final MethodId VarDef = MethodId("VarDef"); + public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) { + return invoke(VarDef, mods, name, vartype, init); + } + + //javac versions: 8 + private static final MethodId ReceiverVarDef = MethodId("ReceiverVarDef"); + public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) { + return invoke(ReceiverVarDef, mods, name, vartype); + } + + //javac versions: 6-8 + private static final MethodId Skip = MethodId("Skip"); + public JCSkip Skip() { + return invoke(Skip); + } + + //javac versions: 6-8 + private static final MethodId Block = MethodId("Block"); + public JCBlock Block(long flags, List stats) { + return invoke(Block, flags, stats); + } + + //javac versions: 6-8 + private static final MethodId DoLoop = MethodId("DoLoop"); + public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) { + return invoke(DoLoop, body, cond); + } + + //javac versions: 6-8 + private static final MethodId WhileLoop = MethodId("WhileLoop"); + public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) { + return invoke(WhileLoop, cond, body); + } + + //javac versions: 6-8 + private static final MethodId ForLoop = MethodId("ForLoop"); + public JCForLoop ForLoop(List init, JCExpression cond, List step, JCStatement body) { + return invoke(ForLoop, init, cond, step, body); + } + + //javac versions: 6-8 + private static final MethodId ForeachLoop = MethodId("ForeachLoop"); + public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) { + return invoke(ForeachLoop, var, expr, body); + } + + //javac versions: 6-8 + private static final MethodId Labelled = MethodId("Labelled"); + public JCLabeledStatement Labelled(Name label, JCStatement body) { + return invoke(Labelled, label, body); + } + + //javac versions: 6-8 + private static final MethodId Switch = MethodId("Switch"); + public JCSwitch Switch(JCExpression selector, List cases) { + return invoke(Switch, selector, cases); + } + + //javac versions: 6-8 + private static final MethodId Case = MethodId("Case"); + public JCCase Case(JCExpression pat, List stats) { + return invoke(Case, pat, stats); + } + + //javac versions: 6-8 + private static final MethodId Synchronized = MethodId("Synchronized"); + public JCSynchronized Synchronized(JCExpression lock, JCBlock body) { + return invoke(Synchronized, lock, body); + } + + //javac versions: 6-8 + private static final MethodId Try = MethodId("Try", JCTry.class, JCBlock.class, List.class, JCBlock.class); + public JCTry Try(JCBlock body, List catchers, JCBlock finalizer) { + return invoke(Try, body, catchers, finalizer); + } + + //javac versions: 7-8 + private static final MethodId TryWithResources = MethodId("Try", JCTry.class, List.class, JCBlock.class, List.class, JCBlock.class); + public JCTry Try(List resources, JCBlock body, List catchers, JCBlock finalizer) { + return invoke(TryWithResources, resources, body, catchers, finalizer); + } + + //javac versions: 6-8 + private static final MethodId Catch = MethodId("Catch"); + public JCCatch Catch(JCVariableDecl param, JCBlock body) { + return invoke(Catch, param, body); + } + + //javac versions: 6-8 + private static final MethodId Conditional = MethodId("Conditional"); + public JCConditional Conditional(JCExpression cond, JCExpression thenpart, JCExpression elsepart) { + return invoke(Conditional, cond, thenpart, elsepart); + } + + //javac versions: 6-8 + private static final MethodId If = MethodId("If"); + public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) { + return invoke(If, cond, thenpart, elsepart); + } + + //javac versions: 6-8 + private static final MethodId Exec = MethodId("Exec"); + public JCExpressionStatement Exec(JCExpression expr) { + return invoke(Exec, expr); + } + + //javac versions: 6-8 + private static final MethodId Break = MethodId("Break"); + public JCBreak Break(Name label) { + return invoke(Break, label); + } + + //javac versions: 6-8 + private static final MethodId Continue = MethodId("Continue"); + public JCContinue Continue(Name label) { + return invoke(Continue, label); + } + + //javac versions: 6-8 + private static final MethodId Return = MethodId("Return"); + public JCReturn Return(JCExpression expr) { + return invoke(Return, expr); + } + + //javac versions: 6-8 + private static final MethodId Throw = MethodId("Throw"); + public JCThrow Throw(JCTree expr) { + return invoke(Throw, expr); + } + + //javac versions: 6-8 + private static final MethodId Assert = MethodId("Assert"); + public JCAssert Assert(JCExpression cond, JCExpression detail) { + return invoke(Assert, cond, detail); + } + + //javac versions: 6-8 + private static final MethodId Apply = MethodId("Apply"); + public JCMethodInvocation Apply(List typeargs, JCExpression fn, List args) { + return invoke(Apply, typeargs, fn, args); + } + + //javac versions: 6-8 + private static final MethodId NewClass = MethodId("NewClass"); + public JCNewClass NewClass(JCExpression encl, List typeargs, JCExpression clazz, List args, JCClassDecl def) { + return invoke(NewClass, encl, typeargs, clazz, args, def); + } + + //javac versions: 6-8 + private static final MethodId NewArray = MethodId("NewArray"); + public JCNewArray NewArray(JCExpression elemtype, List dims, List elems) { + return invoke(NewArray, elemtype, dims, elems); + } + + //javac versions: 8 +// private static final MethodId Lambda = MethodId("Lambda"); +// public JCLambda Lambda(List params, JCTree body) { +// return invoke(Lambda, params, body); +// } + + //javac versions: 6-8 + private static final MethodId Parens = MethodId("Parens"); + public JCParens Parens(JCExpression expr) { + return invoke(Parens, expr); + } + + //javac versions: 6-8 + private static final MethodId Assign = MethodId("Assign"); + public JCAssign Assign(JCExpression lhs, JCExpression rhs) { + return invoke(Assign, lhs, rhs); + } + + //javac versions: 6-8 + //opcode = [6-7] int [8] JCTree.Tag + private static final MethodId Assignop = MethodId("Assignop"); + public JCAssignOp Assignop(TreeTag opcode, JCTree lhs, JCTree rhs) { + return invoke(Assignop, opcode.value, lhs, rhs); + } + + //javac versions: 6-8 + //opcode = [6-7] int [8] JCTree.Tag + private static final MethodId Unary = MethodId("Unary"); + public JCUnary Unary(TreeTag opcode, JCExpression arg) { + return invoke(Unary, opcode.value, arg); + } + + //javac versions: 6-8 + //opcode = [6-7] int [8] JCTree.Tag + private static final MethodId Binary = MethodId("Binary"); + public JCBinary Binary(TreeTag opcode, JCExpression lhs, JCExpression rhs) { + return invoke(Binary, opcode.value, lhs, rhs); + } + + //javac versions: 6-8 + private static final MethodId TypeCast = MethodId("TypeCast"); + public JCTypeCast TypeCast(JCTree expr, JCExpression type) { + return invoke(TypeCast, expr, type); + } + + //javac versions: 6-8 + private static final MethodId TypeTest = MethodId("TypeTest"); + public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) { + return invoke(TypeTest, expr, clazz); + } + + //javac versions: 6-8 + private static final MethodId Indexed = MethodId("Indexed"); + public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) { + return invoke(Indexed, indexed, index); + } + + //javac versions: 6-8 + private static final MethodId Select = MethodId("Select"); + public JCFieldAccess Select(JCExpression selected, Name selector) { + return invoke(Select, selected, selector); + } + + //javac versions: 8 +// private static final MethodId Reference = MethodId("Reference"); +// public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, JCExpression expr, List typeargs) { +// return invoke(Reference, mode, name, expr, typeargs); +// } + + //javac versions: 6-8 + private static final MethodId Ident = MethodId("Ident", JCIdent.class, Name.class); + public JCIdent Ident(Name idname) { + return invoke(Ident, idname); + } + + //javac versions: 6-8 + //tag = [6-7] int [8] TypeTag + private static final MethodId Literal = MethodId("Literal", JCLiteral.class, TypeTag.class, Object.class); + public JCLiteral Literal(TypeTag tag, Object value) { + return invoke(Literal, tag.value, value); + } + + //javac versions: 6-8 + //typetag = [6-7] int [8] TypeTag + private static final MethodId TypeIdent = MethodId("TypeIdent"); + public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) { + return invoke(TypeIdent, typetag.value); + } + //javac versions: 6-8 + private static final MethodId TypeArray = MethodId("TypeArray"); + public JCArrayTypeTree TypeArray(JCExpression elemtype) { + return invoke(TypeArray, elemtype); + } + + //javac versions: 6-8 + private static final MethodId TypeApply = MethodId("TypeApply"); + public JCTypeApply TypeApply(JCExpression clazz, List arguments) { + return invoke(TypeApply, clazz, arguments); + } + + //javac versions: 7-8 +// private static final MethodId TypeUnion = MethodId("TypeUnion"); +// public JCTypeUnion TypeUnion(List components) { +// return invoke(TypeUnion, compoonents); +// } + + //javac versions: 8 +// private static final MethodId TypeIntersection = MethodId("TypeIntersection"); +// public JCTypeIntersection TypeIntersection(List components) { +// return invoke(TypeIntersection, components); +// } + + //javac versions: 6-8 + private static final MethodId TypeParameter = MethodId("TypeParameter", JCTypeParameter.class, Name.class, List.class); + public JCTypeParameter TypeParameter(Name name, List bounds) { + return invoke(TypeParameter, name, bounds); + } + + //javac versions: 8 + private static final MethodId TypeParameterWithAnnos = MethodId("TypeParameter", JCTypeParameter.class, Name.class, List.class, List.class); + public JCTypeParameter TypeParameter(Name name, List bounds, List annos) { + return invoke(TypeParameterWithAnnos, name, bounds, annos); + } + + //javac versions: 6-8 + private static final MethodId Wildcard = MethodId("Wildcard"); + public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) { + return invoke(Wildcard, kind, type); + } + + //javac versions: 6-8 + private static final MethodId TypeBoundKind = MethodId("TypeBoundKind"); + public TypeBoundKind TypeBoundKind(BoundKind kind) { + return invoke(TypeBoundKind, kind); + } + + //javac versions: 6-8 + private static final MethodId Annotation = MethodId("Annotation", JCAnnotation.class, JCTree.class, List.class); + public JCAnnotation Annotation(JCTree annotationType, List args) { + return invoke(Annotation, annotationType, args); + } + + //javac versions: 8 + private static final MethodId TypeAnnotation = MethodId("TypeAnnotation", JCAnnotation.class, JCTree.class, List.class); + public JCAnnotation TypeAnnotation(JCTree annotationType, List args) { + return invoke(TypeAnnotation, annotationType, args); + } + + //javac versions: 6-8 + private static final MethodId ModifiersWithAnnotations = MethodId("Modifiers", JCModifiers.class, long.class, List.class); + public JCModifiers Modifiers(long flags, List annotations) { + return invoke(ModifiersWithAnnotations, flags, annotations); + } + + //javac versions: 6-8 + private static final MethodId Modifiers = MethodId("Modifiers", JCModifiers.class, long.class); + public JCModifiers Modifiers(long flags) { + return invoke(Modifiers, flags); + } + + //javac versions: 8 +// private static final MethodId AnnotatedType = MethodId("AnnotatedType"); +// public JCAnnotatedType AnnotatedType(List annotations, JCExpression underlyingType) { +// return invoke(AnnotatedType, annotations, underlyingType); +// } + + //javac versions: 6-8 + private static final MethodId Erroneous = MethodId("Erroneous", JCErroneous.class); + public JCErroneous Erroneous() { + return invoke(Erroneous); + } + + //javac versions: 6-8 + private static final MethodId ErroneousWithErrs = MethodId("Erroneous", JCErroneous.class, List.class); + public JCErroneous Erroneous(List errs) { + return invoke(ErroneousWithErrs, errs); + } + + //javac versions: 6-8 + private static final MethodId LetExpr = MethodId("LetExpr", LetExpr.class, List.class, JCTree.class); + public LetExpr LetExpr(List defs, JCTree expr) { + return invoke(LetExpr, defs, expr); + } + + //javac versions: 6-8 + private static final MethodId AnonymousClassDef = MethodId("AnonymousClassDef"); + public JCClassDecl AnonymousClassDef(JCModifiers mods, List defs) { + return invoke(AnonymousClassDef, mods, defs); + } + + //javac versions: 6-8 + private static final MethodId LetExprSingle = MethodId("LetExpr", LetExpr.class, JCVariableDecl.class, JCTree.class); + public LetExpr LetExpr(JCVariableDecl def, JCTree expr) { + return invoke(LetExprSingle, def, expr); + } + + //javac versions: 6-8 + private static final MethodId IdentVarDecl = MethodId("Ident", JCIdent.class, JCVariableDecl.class); + public JCExpression Ident(JCVariableDecl param) { + return invoke(IdentVarDecl, param); + } + + //javac versions: 6-8 + private static final MethodId> Idents = MethodId("Idents"); + public List Idents(List params) { + return invoke(Idents, params); + } + + //javac versions: 6-8 + private static final MethodId App2 = MethodId("App", JCMethodInvocation.class, JCExpression.class, List.class); + public JCMethodInvocation App(JCExpression meth, List args) { + return invoke(App2, meth, args); + } + + //javac versions: 6-8 + private static final MethodId App1 = MethodId("App", JCMethodInvocation.class, JCExpression.class); + public JCMethodInvocation App(JCExpression meth) { + return invoke(App1, meth); + } + + //javac versions: 6-8 + private static final MethodId> Annotations = MethodId("Annotations"); + public List Annotations(List attributes) { + return invoke(Annotations, attributes); + } + + //javac versions: 6-8 + private static final MethodId LiteralWithValue = MethodId("Literal", JCLiteral.class, Object.class); + public JCLiteral Literal(Object value) { + return invoke(LiteralWithValue, value); + } + + //javac versions: 6-8 + private static final MethodId AnnotationWithAttributeOnly = MethodId("Annotation", JCAnnotation.class, Attribute.class); + public JCAnnotation Annotation(Attribute a) { + return invoke(AnnotationWithAttributeOnly, a); + } + + //javac versions: 8 + private static final MethodId TypeAnnotationWithAttributeOnly = MethodId("TypeAnnotation", JCAnnotation.class, Attribute.class); + public JCAnnotation TypeAnnotation(Attribute a) { + return invoke(TypeAnnotationWithAttributeOnly, a); + } + + //javac versions: 6-8 + private static final MethodId Call = MethodId("Call"); + public JCStatement Call(JCExpression apply) { + return invoke(Call, apply); + } +} \ No newline at end of file -- cgit From 4dbe3802fda3b317bb82bca80d7c69f58b239cfd Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 28 Jul 2013 03:10:34 +0200 Subject: more progress. This one is less JDK8 compatible, but it has major refactorings to make JDK6-8 support possibly with much prettier code. --- build.xml | 24 +- src/core/lombok/javac/JavacResolution.java | 35 +-- src/core/lombok/javac/handlers/HandleBuilder.java | 6 +- src/core/lombok/javac/handlers/HandleGetter.java | 9 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 24 +- src/core/lombok/javac/handlers/NonNullHandler.java | 7 +- .../lombok/delombok/PrettyCommentsPrinter.java | 242 +++++++-------------- src/utils/lombok/javac/Javac.java | 86 +------- src/utils/lombok/javac/JavacTreeMaker.java | 178 ++++++++++++--- src/utils/lombok/javac/TreeMirrorMaker.java | 5 +- 10 files changed, 295 insertions(+), 321 deletions(-) (limited to 'src/core') diff --git a/build.xml b/build.xml index 2ed0ba71..b44d6673 100644 --- a/build.xml +++ b/build.xml @@ -332,7 +332,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr - + @@ -345,7 +345,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr - + @@ -360,9 +360,11 @@ the common tasks and can be called on to run the main aspects of all the sub-scr + + - - + + Tests will now run against Oracle JDK7 @@ -371,11 +373,11 @@ the common tasks and can be called on to run the main aspects of all the sub-scr - - + + - - + + Tests will now run against Oracle JDK8 @@ -390,8 +392,10 @@ Eventually, this environment concept will be extended to also include an ecj and You can let this ant script set them up for you: -* ant setupJava6TestEnvironment -* ant setupJava7TestEnvironment +* ant setupJavaOpenJDK6TestEnvironment +* ant setupJavaOpenJDK7TestEnvironment +* ant setupJavaOracle7TestEnvironment +* ant setupJavaOracle8TestEnvironment These will set up test environments based on OpenJDK6 and OpenJDK7, and download all required files automatically. This will be a relatively large download. You can switch by running this command again; the downloads are cached so switching is fast. diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 42299572..7d4bdabd 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -35,6 +35,8 @@ import java.util.Queue; import javax.lang.model.type.TypeKind; import javax.tools.DiagnosticListener; +import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; + import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symtab; @@ -56,7 +58,6 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -389,7 +390,7 @@ public class JavacResolution { } public static JCExpression createJavaLangObject(JavacAST ast) { - TreeMaker maker = ast.getTreeMaker(); + JavacTreeMaker maker = ast.getTreeMaker(); JCExpression out = maker.Ident(ast.toName("java")); out = maker.Select(out, ast.toName("lang")); out = maker.Select(out, ast.toName("Object")); @@ -416,10 +417,10 @@ public class JavacResolution { // NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too. // -- so we write our own take on that here. - TreeMaker maker = ast.getTreeMaker(); + JavacTreeMaker maker = ast.getTreeMaker(); - if (Javac.compareCTC(type.tag, CTC_BOT)) return createJavaLangObject(ast); - if (Javac.compareCTC(type.tag, CTC_VOID)) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast); + if (CTC_BOT.equals(typeTag(type))) return createJavaLangObject(ast); + if (CTC_VOID.equals(typeTag(type))) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast); if (type.isPrimitive()) return primitiveToJCTree(type.getKind(), maker); if (type.isErroneous()) throw new TypeNotConvertibleException("Type cannot be resolved"); @@ -453,7 +454,7 @@ public class JavacResolution { upper = type.getUpperBound(); } if (allowCompound) { - if (lower == null || Javac.compareCTC(lower.tag, CTC_BOT)) { + if (lower == null || CTC_BOT.equals(typeTag(lower))) { if (upper == null || upper.toString().equals("java.lang.Object")) { return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null); } @@ -478,7 +479,7 @@ public class JavacResolution { String qName; if (symbol.isLocal()) { qName = symbol.getSimpleName().toString(); - } else if (symbol.type != null && symbol.type.getEnclosingType() != null && Javac.compareCTC(symbol.type.getEnclosingType().tag, Javac.getTypeTag("CLASS"))) { + } else if (symbol.type != null && symbol.type.getEnclosingType() != null && typeTag(symbol.type.getEnclosingType()).equals(typeTag("CLASS"))) { replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false); qName = symbol.getSimpleName().toString(); } else { @@ -511,26 +512,26 @@ public class JavacResolution { return rawTypeNode; } - private static JCExpression primitiveToJCTree(TypeKind kind, TreeMaker maker) throws TypeNotConvertibleException { + private static JCExpression primitiveToJCTree(TypeKind kind, JavacTreeMaker maker) throws TypeNotConvertibleException { switch (kind) { case BYTE: - return Javac.makeTypeIdent(maker, CTC_BYTE); + return maker.TypeIdent(CTC_BYTE); case CHAR: - return Javac.makeTypeIdent(maker, CTC_CHAR); + return maker.TypeIdent( CTC_CHAR); case SHORT: - return Javac.makeTypeIdent(maker, CTC_SHORT); + return maker.TypeIdent(CTC_SHORT); case INT: - return Javac.makeTypeIdent(maker, CTC_INT); + return maker.TypeIdent(CTC_INT); case LONG: - return Javac.makeTypeIdent(maker, CTC_LONG); + return maker.TypeIdent(CTC_LONG); case FLOAT: - return Javac.makeTypeIdent(maker, CTC_FLOAT); + return maker.TypeIdent(CTC_FLOAT); case DOUBLE: - return Javac.makeTypeIdent(maker, CTC_DOUBLE); + return maker.TypeIdent(CTC_DOUBLE); case BOOLEAN: - return Javac.makeTypeIdent(maker, CTC_BOOLEAN); + return maker.TypeIdent(CTC_BOOLEAN); case VOID: - return Javac.makeTypeIdent(maker, CTC_VOID); + return maker.TypeIdent(CTC_VOID); case NULL: case NONE: case OTHER: diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 1c0f2ec0..4f48b69f 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; @@ -53,13 +52,14 @@ import lombok.core.HandlerPriority; import lombok.core.TransformationsUtil; import lombok.experimental.Builder; import lombok.experimental.NonFinal; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; import lombok.javac.handlers.HandleConstructor.SkipIfConstructorExists; 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. @@ -240,7 +240,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName); call = maker.Apply(typeParams.toList(), fn, args.toList()); - if (returnType instanceof JCPrimitiveTypeTree && compareCTC(Javac.getTypeTag((JCPrimitiveTypeTree) returnType), CTC_VOID)) { + if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) { statement = maker.Exec(call); } else { statement = maker.Return(call); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index f5bf2b6c..f6c14add 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; @@ -35,10 +36,10 @@ import lombok.Getter; 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.JavacTreeMaker.TypeTag; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -289,9 +290,9 @@ public class HandleGetter extends JavacAnnotationHandler { private static final String JLO = "java.lang.Object"; private static final List NIL_EXPRESSION = List.nil(); - private static final java.util.Map TYPE_MAP; + private static final java.util.Map TYPE_MAP; static { - Map m = new HashMap(); + Map m = new HashMap(); m.put(CTC_INT, "java.lang.Integer"); m.put(CTC_DOUBLE, "java.lang.Double"); m.put(CTC_FLOAT, "java.lang.Float"); @@ -335,7 +336,7 @@ public class HandleGetter extends JavacAnnotationHandler { 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); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 630cc31a..d0673c57 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1277,17 +1277,17 @@ public class JavacHandlerUtil { */ public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) { 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]); -// } -// } -// } catch (Exception ignore) {} + 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]); + } + } + } catch (Exception ignore) {} } } diff --git a/src/core/lombok/javac/handlers/NonNullHandler.java b/src/core/lombok/javac/handlers/NonNullHandler.java index d74fb55d..3cf76f26 100644 --- a/src/core/lombok/javac/handlers/NonNullHandler.java +++ b/src/core/lombok/javac/handlers/NonNullHandler.java @@ -46,6 +46,9 @@ 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 { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -138,10 +141,10 @@ public class NonNullHandler extends JavacAnnotationHandler { while (cond instanceof JCParens) cond = ((JCParens) cond).expr; if (!(cond instanceof JCBinary)) return null; JCBinary bin = (JCBinary) cond; - if (compareCTC(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 (compareCTC(getTypeTag((JCLiteral) bin.rhs), CTC_BOT)) return null; + if (!CTC_BOT.equals(typeTag(bin.rhs))) return null; return ((JCIdent) bin.lhs).name.toString(); } } diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 481380f7..fd0b0f0d 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -45,9 +45,13 @@ import java.util.HashMap; import java.util.Map; import lombok.javac.CommentInfo; -import lombok.javac.Javac; import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; +import lombok.javac.JavacTreeMaker.TreeTag; +import lombok.javac.JavacTreeMaker.TypeTag; +import static lombok.javac.Javac.*; +import static lombok.javac.JavacTreeMaker.TreeTag.treeTag; +import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import com.sun.source.tree.Tree; import com.sun.tools.javac.code.BoundKind; @@ -123,88 +127,48 @@ import com.sun.tools.javac.util.Position; */ @SuppressWarnings("all") // Mainly sun code that has other warning settings public class PrettyCommentsPrinter extends JCTree.Visitor { + private static final TreeTag PARENS = treeTag("PARENS"); + private static final TreeTag IMPORT = treeTag("IMPORT"); + private static final TreeTag VARDEF = treeTag("VARDEF"); + private static final TreeTag SELECT = treeTag("SELECT"); - private static final Method GET_TAG_METHOD; - private static final Field TAG_FIELD; - - private static final Object PARENS = Javac.getTreeTag("PARENS"); - private static final Object IMPORT = Javac.getTreeTag("IMPORT"); - private static final Object VARDEF = Javac.getTreeTag("VARDEF"); - private static final Object SELECT = Javac.getTreeTag("SELECT"); - - private static final Map OPERATORS; + private static final Map OPERATORS; static { - Method m = null; - Field f = null; - try { - m = JCTree.class.getDeclaredMethod("getTag"); - } - catch (NoSuchMethodException e) { - try { - f = JCTree.class.getDeclaredField("tag"); - } - catch (NoSuchFieldException e1) { - e1.printStackTrace(); - } - } - GET_TAG_METHOD = m; - TAG_FIELD = f; - - Map map = new HashMap(); + Map map = new HashMap(); - map.put(Javac.getTreeTag("POS"), "+"); - map.put(Javac.getTreeTag("NEG"), "-"); - map.put(Javac.getTreeTag("NOT"), "!"); - map.put(Javac.getTreeTag("COMPL"), "~"); - map.put(Javac.getTreeTag("PREINC"), "++"); - map.put(Javac.getTreeTag("PREDEC"), "--"); - map.put(Javac.getTreeTag("POSTINC"), "++"); - map.put(Javac.getTreeTag("POSTDEC"), "--"); - map.put(Javac.getTreeTag("NULLCHK"), "<*nullchk*>"); - map.put(Javac.getTreeTag("OR"), "||"); - map.put(Javac.getTreeTag("AND"), "&&"); - map.put(Javac.getTreeTag("EQ"), "=="); - map.put(Javac.getTreeTag("NE"), "!="); - map.put(Javac.getTreeTag("LT"), "<"); - map.put(Javac.getTreeTag("GT"), ">"); - map.put(Javac.getTreeTag("LE"), "<="); - map.put(Javac.getTreeTag("GE"), ">="); - map.put(Javac.getTreeTag("BITOR"), "|"); - map.put(Javac.getTreeTag("BITXOR"), "^"); - map.put(Javac.getTreeTag("BITAND"), "&"); - map.put(Javac.getTreeTag("SL"), "<<"); - map.put(Javac.getTreeTag("SR"), ">>"); - map.put(Javac.getTreeTag("USR"), ">>>"); - map.put(Javac.getTreeTag("PLUS"), "+"); - map.put(Javac.getTreeTag("MINUS"), "-"); - map.put(Javac.getTreeTag("MUL"), "*"); - map.put(Javac.getTreeTag("DIV"), "/"); - map.put(Javac.getTreeTag("MOD"), "%"); + map.put(treeTag("POS"), "+"); + map.put(treeTag("NEG"), "-"); + map.put(treeTag("NOT"), "!"); + map.put(treeTag("COMPL"), "~"); + map.put(treeTag("PREINC"), "++"); + map.put(treeTag("PREDEC"), "--"); + map.put(treeTag("POSTINC"), "++"); + map.put(treeTag("POSTDEC"), "--"); + map.put(treeTag("NULLCHK"), "<*nullchk*>"); + map.put(treeTag("OR"), "||"); + map.put(treeTag("AND"), "&&"); + map.put(treeTag("EQ"), "=="); + map.put(treeTag("NE"), "!="); + map.put(treeTag("LT"), "<"); + map.put(treeTag("GT"), ">"); + map.put(treeTag("LE"), "<="); + map.put(treeTag("GE"), ">="); + map.put(treeTag("BITOR"), "|"); + map.put(treeTag("BITXOR"), "^"); + map.put(treeTag("BITAND"), "&"); + map.put(treeTag("SL"), "<<"); + map.put(treeTag("SR"), ">>"); + map.put(treeTag("USR"), ">>>"); + map.put(treeTag("PLUS"), "+"); + map.put(treeTag("MINUS"), "-"); + map.put(treeTag("MUL"), "*"); + map.put(treeTag("DIV"), "/"); + map.put(treeTag("MOD"), "%"); OPERATORS = map; } - static Object getTag(JCTree tree) { - if (GET_TAG_METHOD != null) { - try { - return GET_TAG_METHOD.invoke(tree); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) { - throw new RuntimeException(e.getCause()); - } - } - try { - return TAG_FIELD.get(tree); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - private List comments; private final JCCompilationUnit cu; private boolean onNewLine = true; @@ -634,7 +598,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { /** Is the given tree an enumerator definition? */ boolean isEnumerator(JCTree t) { - return Javac.compareCTC(getTag(t), VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0; + return VARDEF.equals(treeTag(t)) && (((JCVariableDecl) t).mods.flags & ENUM) != 0; } /** Print unit consisting of package clause and import statements in toplevel, @@ -645,7 +609,8 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { * toplevel tree. */ public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { - docComments = tree.docComments; + Object dc = getDocComments(tree); + if (dc instanceof Map) this.docComments = (Map) dc; printDocComment(tree); if (tree.pid != null) { consumeComments(tree.pos, tree); @@ -656,9 +621,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } boolean firstImport = true; for (List l = tree.defs; - l.nonEmpty() && (cdef == null || getTag(l.head) == IMPORT); + l.nonEmpty() && (cdef == null || IMPORT.equals(treeTag(l.head))); l = l.tail) { - if (Javac.compareCTC(getTag(l.head), IMPORT)) { + if (IMPORT.equals(treeTag(l.head))) { JCImport imp = (JCImport)l.head; Name name = TreeInfo.name(imp.qualid); if (name == name.table.fromChars(new char[] {'*'}, 0, 1) || @@ -742,9 +707,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { else print("class " + tree.name); printTypeParameters(tree.typarams); - if (Javac.getExtendsClause(tree) != null) { + if (getExtendsClause(tree) != null) { print(" extends "); - printExpr(Javac.getExtendsClause(tree)); + printExpr(getExtendsClause(tree)); } if (tree.implementing.nonEmpty()) { print(" implements "); @@ -877,7 +842,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { printStat(tree.body); align(); print(" while "); - if (Javac.compareCTC(getTag(tree.cond), PARENS)) { + if (PARENS.equals(treeTag(tree.cond))) { printExpr(tree.cond); } else { print("("); @@ -893,7 +858,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitWhileLoop(JCWhileLoop tree) { try { print("while "); - if (Javac.compareCTC(getTag(tree.cond), PARENS)) { + if (PARENS.equals(treeTag(tree.cond))) { printExpr(tree.cond); } else { print("("); @@ -911,7 +876,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { try { print("for ("); if (tree.init.nonEmpty()) { - if (Javac.compareCTC(getTag(tree.init.head), VARDEF)) { + if (VARDEF.equals(treeTag(tree.init.head))) { printExpr(tree.init.head); for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) { JCVariableDecl vdef = (JCVariableDecl)l.head; @@ -958,7 +923,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitSwitch(JCSwitch tree) { try { print("switch "); - if (Javac.compareCTC(getTag(tree.selector), PARENS)) { + if (PARENS.equals(treeTag(tree.selector))) { printExpr(tree.selector); } else { print("("); @@ -997,7 +962,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitSynchronized(JCSynchronized tree) { try { print("synchronized "); - if (Javac.compareCTC(getTag(tree.lock), PARENS)) { + if (PARENS.equals(treeTag(tree.lock))) { printExpr(tree.lock); } else { print("("); @@ -1078,7 +1043,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitIf(JCIf tree) { try { print("if "); - if (Javac.compareCTC(getTag(tree.cond), PARENS)) { + if (PARENS.equals(treeTag(tree.cond))) { printExpr(tree.cond); } else { print("("); @@ -1174,7 +1139,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitApply(JCMethodInvocation tree) { try { if (!tree.typeargs.isEmpty()) { - if (Javac.compareCTC(getTag(tree.meth), SELECT)) { + if (SELECT.equals(treeTag(tree.meth))) { JCFieldAccess left = (JCFieldAccess)tree.meth; printExpr(left.selected); print(".<"); @@ -1278,7 +1243,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - public String operatorName(Object tag) { + public String operatorName(TreeTag tag) { String result = OPERATORS.get(tag); if (result == null) throw new Error(); return result; @@ -1300,9 +1265,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitUnary(JCUnary tree) { try { int ownprec = isOwnPrec(tree); - String opname = operatorName(getTag(tree)); + String opname = operatorName(treeTag(tree)); open(prec, ownprec); - if (isPostUnary(tree)) { + if (isPrefixUnary(tree)) { print(opname); printExpr(tree.arg, ownprec); } else { @@ -1315,63 +1280,18 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - private String assignOpName(JCExpression tree) { - try { - Object tag = getTag(tree); - if (JavaCompiler.version().startsWith("1.8")) { - return operatorName(tag.getClass().getMethod("noAssignOp").invoke(tree)); - } else { - return operatorName((Integer)((Integer)tag - (Integer)JCTree.class.getField("ASGOffset").get(null))); - } - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException) e; - throw new RuntimeException(e); - } + private int isOwnPrec(JCExpression tree) { + return treeTag(tree).getOperatorPrecedenceLevel(); } - private int isOwnPrec(JCExpression tree) { - try { - if (JavaCompiler.version().startsWith("1.8")) { - return (Integer)TreeInfo.class.getMethod("opPrec", Class.forName("com.sun.tools.javac.code.TypeTag")).invoke(null, getTag(tree)); - } else { - return (Integer)TreeInfo.class.getMethod("opPrec", Integer.TYPE).invoke(null, getTag(tree)); - } - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException) e; - throw new RuntimeException(e); - } + private boolean isPrefixUnary(JCUnary tree) { + return treeTag(tree).isPrefixUnaryOp(); } - private boolean isPostUnary(JCUnary tree) { - try { - Object tag = getTag(tree); - if (JavaCompiler.version().startsWith("1.8")) { - return (Boolean) tag.getClass().getMethod("isPostUnaryOp").invoke(tree); - } else { - return ((Integer) tag) <= ((Integer) Javac.getTreeTag("PREDEC")); - } - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException) e; - throw new RuntimeException(e); - } - } - public void visitBinary(JCBinary tree) { try { int ownprec = isOwnPrec(tree); - String opname = operatorName(getTag(tree)); + String opname = operatorName(treeTag(tree)); open(prec, ownprec); printExpr(tree.lhs, ownprec); print(" " + opname + " "); @@ -1436,19 +1356,17 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } public void visitLiteral(JCLiteral tree) { + TypeTag typeTag = typeTag(tree); try { - if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_INT)) print(tree.value.toString()); - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_LONG)) print(tree.value + "L"); - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_FLOAT)) print(tree.value + "F"); - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_DOUBLE)) print(tree.value.toString()); - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_CHAR)) { - print("\'" + - Convert.quote( - String.valueOf((char)((Number)tree.value).intValue()))+ - "\'"); + if (CTC_INT.equals(typeTag)) print(tree.value.toString()); + else if (CTC_LONG.equals(typeTag)) print(tree.value + "L"); + else if (CTC_FLOAT.equals(typeTag)) print(tree.value + "F"); + else if (CTC_DOUBLE.equals(typeTag)) print(tree.value.toString()); + else if (CTC_CHAR.equals(typeTag)) { + print("\'" + Convert.quote(String.valueOf((char)((Number)tree.value).intValue())) + "\'"); } - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOOLEAN)) print(((Number)tree.value).intValue() == 1 ? "true" : "false"); - else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOT)) print("null"); + else if (CTC_BOOLEAN.equals(typeTag)) print(((Number)tree.value).intValue() == 1 ? "true" : "false"); + else if (CTC_BOT.equals(typeTag)) print("null"); else print("\"" + Convert.quote(tree.value.toString()) + "\""); } catch (IOException e) { throw new UncheckedIOException(e); @@ -1456,17 +1374,17 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } public void visitTypeIdent(JCPrimitiveTypeTree tree) { - Object typetag = Javac.getTreeTypeTag(tree); + TypeTag typetag = typeTag(tree); try { - if (Javac.compareCTC(typetag, Javac.CTC_BYTE)) print("byte"); - else if (Javac.compareCTC(typetag, Javac.CTC_CHAR)) print("char"); - else if (Javac.compareCTC(typetag, Javac.CTC_SHORT)) print("short"); - else if (Javac.compareCTC(typetag, Javac.CTC_INT)) print("int"); - else if (Javac.compareCTC(typetag, Javac.CTC_LONG)) print("long"); - else if (Javac.compareCTC(typetag, Javac.CTC_FLOAT)) print("float"); - else if (Javac.compareCTC(typetag, Javac.CTC_DOUBLE)) print("double"); - else if (Javac.compareCTC(typetag, Javac.CTC_BOOLEAN)) print("boolean"); - else if (Javac.compareCTC(typetag, Javac.CTC_VOID)) print("void"); + if (CTC_BYTE.equals(typetag)) print ("byte"); + else if (CTC_CHAR.equals(typetag)) print ("char"); + else if (CTC_SHORT.equals(typetag)) print ("short"); + else if (CTC_INT.equals(typetag)) print ("int"); + else if (CTC_LONG.equals(typetag)) print ("long"); + else if (CTC_FLOAT.equals(typetag)) print ("float"); + else if (CTC_DOUBLE.equals(typetag)) print ("double"); + else if (CTC_BOOLEAN.equals(typetag)) print ("boolean"); + else if (CTC_VOID.equals(typetag)) print ("void"); else print("error"); } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index b0540997..014007d4 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -47,7 +47,6 @@ import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCLiteral; -import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** @@ -133,34 +132,17 @@ public class Javac { public static final TypeTag CTC_CLASS = typeTag("CLASS"); public static final TreeTag CTC_NOT_EQUAL = treeTag("NE"); + public static final TreeTag CTC_POS = treeTag("POS"); + public static final TreeTag CTC_NEG = treeTag("NEG"); public static final TreeTag CTC_NOT = treeTag("NOT"); + public static final TreeTag CTC_COMPL = treeTag("COMPL"); public static final TreeTag CTC_BITXOR = treeTag("BITXOR"); public static final TreeTag CTC_UNSIGNED_SHIFT_RIGHT = treeTag("USR"); public static final TreeTag CTC_MUL = treeTag("MUL"); public static final TreeTag CTC_PLUS = treeTag("PLUS"); public static final TreeTag CTC_EQUAL = treeTag("EQ"); - - public static boolean compareCTC(TreeTag ctc1, TreeTag ctc2) { - boolean ctc1IsNull = ctc1 == null || ctc1.value == null; - boolean ctc2IsNull = ctc2 == null || ctc2.value == null; - if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull; - return ctc1.value.equals(ctc2.value); - } - - public static boolean compareCTC(TypeTag ctc1, TypeTag ctc2) { - boolean ctc1IsNull = ctc1 == null || ctc1.value == null; - boolean ctc2IsNull = ctc2 == null || ctc2.value == null; - if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull; - return ctc1.value.equals(ctc2.value); - } - - public static Object getTreeTypeTag(JCPrimitiveTypeTree tree) { - return tree.typetag; - } - - public static Object getTreeTypeTag(JCLiteral tree) { - return tree.typetag; - } + public static final TreeTag CTC_PREINC = treeTag("PREINC"); + public static final TreeTag CTC_PREDEC = treeTag("PREDEC"); private static final Method getExtendsClause, getEndPosition; @@ -245,7 +227,7 @@ public class Javac { return new JCNoType(((Integer) tag.value).intValue()); } else { try { - if (compareCTC(tag, CTC_VOID)) { + if (CTC_VOID.equals(tag)) { return (Type) JC_VOID_TYPE.newInstance(); } else { return (Type) JC_NO_TYPE.newInstance(); @@ -276,28 +258,9 @@ public class Javac { } } - private static final Field JCTREE_TAG, JCLITERAL_TYPETAG, JCPRIMITIVETYPETREE_TYPETAG, JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS; - private static final Method JCTREE_GETTAG; + private static final Field JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS; static { Field f = null; - try { - f = JCTree.class.getDeclaredField("tag"); - } catch (NoSuchFieldException e) {} - JCTREE_TAG = f; - - f = null; - try { - f = JCLiteral.class.getDeclaredField("typetag"); - } catch (NoSuchFieldException e) {} - JCLITERAL_TYPETAG = f; - - f = null; - try { - f = JCPrimitiveTypeTree.class.getDeclaredField("typetag"); - } catch (NoSuchFieldException e) {} - JCPRIMITIVETYPETREE_TYPETAG = f; - - f = null; try { f = JCCompilationUnit.class.getDeclaredField("endPositions"); } catch (NoSuchFieldException e) {} @@ -308,41 +271,6 @@ public class Javac { f = JCCompilationUnit.class.getDeclaredField("docComments"); } catch (NoSuchFieldException e) {} JCCOMPILATIONUNIT_DOCCOMMENTS = f; - - Method m = null; - try { - m = JCTree.class.getDeclaredMethod("getTag"); - } catch (NoSuchMethodException e) {} - JCTREE_GETTAG = m; - } - - public static Object getTag(JCTree node) { - if (JCTREE_GETTAG != null) { - try { - return JCTREE_GETTAG.invoke(node); - } catch (Exception e) {} - } - try { - return JCTREE_TAG.get(node); - } catch (Exception e) { - throw new IllegalStateException("Can't get node tag"); - } - } - - public static Object getTypeTag(JCLiteral node) { - try { - return JCLITERAL_TYPETAG.get(node); - } catch (Exception e) { - throw new IllegalStateException("Can't get JCLiteral typetag"); - } - } - - public static Object getTypeTag(JCPrimitiveTypeTree node) { - try { - return JCPRIMITIVETYPETREE_TYPETAG.get(node); - } catch (Exception e) { - throw new IllegalStateException("Can't get JCPrimitiveTypeTree typetag"); - } } static RuntimeException sneakyThrow(Throwable t) { diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index 916c8735..edbf55af 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -21,6 +21,7 @@ */ package lombok.javac; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentHashMap; @@ -29,6 +30,7 @@ import java.util.concurrent.ConcurrentMap; import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Symbol; +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.JCArrayAccess; @@ -81,6 +83,7 @@ import com.sun.tools.javac.tree.JCTree.JCWhileLoop; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.LetExpr; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; @@ -92,49 +95,101 @@ public class JavacTreeMaker { this.tm = tm; } + public TreeMaker getUnderlyingTreeMaker() { + return tm; + } + public JavacTreeMaker at(int pos) { tm.at(pos); return this; } private static class MethodId { + private final Class owner; private final String name; private final Class returnType; private final Class[] paramTypes; - MethodId(String name, Class returnType, Class... types) { + MethodId(Class owner, String name, Class returnType, Class... types) { + this.owner = owner; this.name = name; this.paramTypes = types; this.returnType = returnType; } - } - private static Object getFieldCached(ConcurrentMap cache, String className, String fieldName) { - Object value = cache.get(fieldName); - if (value != null) return value; - try { - value = Class.forName(className).getField(fieldName).get(null); - } catch (NoSuchFieldException e) { - throw Javac.sneakyThrow(e); - } catch (IllegalAccessException e) { - throw Javac.sneakyThrow(e); - } catch (ClassNotFoundException e) { - throw Javac.sneakyThrow(e); + private static class SchroedingerType { + final Object value; + + private SchroedingerType(Object value) { + this.value = value; + } + + @Override public int hashCode() { + return value == null ? -1 : value.hashCode(); } - cache.putIfAbsent(fieldName, value); - return value; + @Override public boolean equals(Object obj) { + if (obj instanceof SchroedingerType) { + Object other = ((SchroedingerType) obj).value; + return value == null ? other == null : value.equals(other); + } + return false; + } + + static Object getFieldCached(ConcurrentMap cache, String className, String fieldName) { + Object value = cache.get(fieldName); + if (value != null) return value; + try { + value = Class.forName(className).getField(fieldName).get(null); + } catch (NoSuchFieldException e) { + throw Javac.sneakyThrow(e); + } catch (IllegalAccessException e) { + throw Javac.sneakyThrow(e); + } catch (ClassNotFoundException e) { + throw Javac.sneakyThrow(e); + } + + cache.putIfAbsent(fieldName, value); + return value; + } + + static Object getFieldCached(ConcurrentMap, Field> cache, Object ref, String fieldName) { + Class c = ref.getClass(); + Field field = cache.get(c); + if (field == null) { + try { + field = c.getField(fieldName); + } catch (NoSuchFieldException e) { + throw Javac.sneakyThrow(e); + } + field.setAccessible(true); + Field old = cache.putIfAbsent(c, field); + if (old != null) field = old; + } + + try { + return field.get(ref); + } catch (IllegalAccessException e) { + throw Javac.sneakyThrow(e); + } + } } - private static interface SchroedingerType {} - - public static class TypeTag implements SchroedingerType { + public static class TypeTag extends SchroedingerType { private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); - public final Object value; + private static final ConcurrentMap, Field> FIELD_CACHE = new ConcurrentHashMap, Field>(); private TypeTag(Object value) { - this.value = value; + super(value); + } + + public static TypeTag typeTag(JCTree o) { + return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag")); + } + + public static TypeTag typeTag(Type t) { + return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag")); } public static TypeTag typeTag(String identifier) { @@ -142,17 +197,63 @@ public class JavacTreeMaker { } } - public static class TreeTag implements SchroedingerType { + public static class TreeTag extends SchroedingerType { private static final ConcurrentMap TREE_TAG_CACHE = new ConcurrentHashMap(); - public final Object value; + private static final Field TAG_FIELD; + private static final Method TAG_METHOD; + private static final MethodId OP_PREC = MethodId(TreeInfo.class, "opPrec", int.class, TreeTag.class); + + static { + Method m = null; + try { + m = JCTree.class.getDeclaredMethod("getTag"); + m.setAccessible(true); + } catch (NoSuchMethodException e) {} + + if (m != null) { + TAG_FIELD = null; + TAG_METHOD = m; + } else { + Field f = null; + try { + f = JCTree.class.getDeclaredField("tag"); + f.setAccessible(true); + } catch (NoSuchFieldException e) {} + TAG_FIELD = f; + TAG_METHOD = null; + } + } private TreeTag(Object value) { - this.value = value; + super(value); + } + + public static TreeTag treeTag(JCTree o) { + try { + if (TAG_METHOD != null) return new TreeTag(TAG_METHOD.invoke(o)); + else return new TreeTag(TAG_FIELD.get(o)); + } catch (InvocationTargetException e) { + throw Javac.sneakyThrow(e.getCause()); + } catch (IllegalAccessException e) { + throw Javac.sneakyThrow(e); + } } public static TreeTag treeTag(String identifier) { return new TreeTag(getFieldCached(TREE_TAG_CACHE, Javac.getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.tree.JCTree" : "com.sun.tools.javac.tree.JCTree$Tag", identifier)); } + + public int getOperatorPrecedenceLevel() { + return invokeAny(null, OP_PREC, value); + } + + public boolean isPrefixUnaryOp() { + return Javac.CTC_NEG.equals(this) || Javac.CTC_POS.equals(this) || Javac.CTC_NOT.equals(this) || Javac.CTC_COMPL.equals(this) || Javac.CTC_PREDEC.equals(this) || Javac.CTC_PREINC.equals(this); + } + } + + static MethodId MethodId(Class owner, String name, Class returnType, Class... types) { + return new MethodId(owner, name, returnType, types); } /** @@ -163,8 +264,8 @@ public class JavacTreeMaker { * Either (A) the type listed here is the same as, or a subtype of, the type of the method in javac's TreeMaker, or * (B) the type listed here is a subtype of SchroedingerType. */ - static MethodId MethodId(String name, Class returnType, Class... types) { - return new MethodId(name, returnType, types); + static MethodId MethodId(String name, Class returnType, Class... types) { + return new MethodId(TreeMaker.class, name, returnType, types); } /** @@ -176,7 +277,7 @@ public class JavacTreeMaker { if (m.getName().equals(name)) { @SuppressWarnings("unchecked") Class r = (Class) m.getReturnType(); Class[] p = m.getParameterTypes(); - return new MethodId(name, r, p); + return new MethodId(TreeMaker.class, name, r, p); } } @@ -185,14 +286,27 @@ public class JavacTreeMaker { private static final ConcurrentHashMap, Method> METHOD_CACHE = new ConcurrentHashMap, Method>(); private J invoke(MethodId m, Object... args) { + return invokeAny(tm, m, args); + } + + @SuppressWarnings("unchecked") private static J invokeAny(Object owner, MethodId m, Object... args) { Method method = METHOD_CACHE.get(m); if (method == null) method = addToCache(m); try { - return m.returnType.cast(method.invoke(tm, args)); + if (m.returnType.isPrimitive()) { + Object res = method.invoke(owner, args); + String sn = res.getClass().getSimpleName().toLowerCase(); + if (!sn.startsWith(m.returnType.getSimpleName())) throw new ClassCastException(res.getClass() + " to " + m.returnType); + return (J) res; + } + return m.returnType.cast(method.invoke(owner, args)); } catch (InvocationTargetException e) { throw Javac.sneakyThrow(e.getCause()); } catch (IllegalAccessException e) { throw Javac.sneakyThrow(e); + } catch (IllegalArgumentException e) { + System.err.println(method); + throw Javac.sneakyThrow(e); } } @@ -200,7 +314,7 @@ public class JavacTreeMaker { Method found = null; outer: - for (Method method : TreeMaker.class.getDeclaredMethods()) { + for (Method method : m.owner.getDeclaredMethods()) { if (!m.name.equals(method.getName())) continue; Class[] t = method.getParameterTypes(); if (t.length != m.paramTypes.length) continue; @@ -210,7 +324,7 @@ public class JavacTreeMaker { if (t[i].isPrimitive()) { if (t[i] != m.paramTypes[i]) continue outer; } else { - if (t[i].isAssignableFrom(m.paramTypes[i])) continue outer; + if (!t[i].isAssignableFrom(m.paramTypes[i])) continue outer; } } } @@ -659,4 +773,10 @@ public class JavacTreeMaker { public JCStatement Call(JCExpression apply) { return invoke(Call, apply); } + + //javac versions: 6-8 + private static final MethodId Type = MethodId("Type"); + public JCExpression Type(Type type) { + return invoke(Type, type); + } } \ No newline at end of file diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java index 30915572..23ec2406 100644 --- a/src/utils/lombok/javac/TreeMirrorMaker.java +++ b/src/utils/lombok/javac/TreeMirrorMaker.java @@ -31,7 +31,6 @@ import com.sun.source.tree.VariableTree; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeCopier; -import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; /** @@ -47,8 +46,8 @@ import com.sun.tools.javac.util.List; public class TreeMirrorMaker extends TreeCopier { private final IdentityHashMap originalToCopy = new IdentityHashMap(); - public TreeMirrorMaker(TreeMaker maker) { - super(maker); + public TreeMirrorMaker(JavacTreeMaker maker) { + super(maker.getUnderlyingTreeMaker()); } @Override public T copy(T original) { -- cgit From d0d2dd6f5d1b9bd33e9e127f8d66b3387f487271 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 28 Jul 2013 07:16:12 +0200 Subject: Some work on actually making lombok work on JDK8's javac. --- src/core/lombok/javac/JavacAST.java | 2 +- src/core/lombok/javac/JavacNode.java | 9 + .../lombok/javac/handlers/JavacHandlerUtil.java | 12 +- .../lombok/delombok/PrettyCommentsPrinter.java | 225 +++++++++++---------- src/utils/lombok/javac/JavacTreeMaker.java | 58 +++++- 5 files changed, 184 insertions(+), 122 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 1f3b04a4..e49d8ac8 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -375,7 +375,7 @@ public class JavacAST extends AST { if (pos == null) pos = astObject.pos(); } if (pos != null && attemptToRemoveErrorsInRange) { - removeFromDeferredDiagnostics(pos.getStartPosition(), pos.getEndPosition(top.endPositions)); + removeFromDeferredDiagnostics(pos.getStartPosition(), node.getEndPosition(pos)); } try { switch (kind) { diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java index 30a470a9..6eef36eb 100644 --- a/src/core/lombok/javac/JavacNode.java +++ b/src/core/lombok/javac/JavacNode.java @@ -51,6 +51,15 @@ public class JavacNode extends lombok.core.LombokNode docComments = (Map) dc; + String javadoc = 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]); + docComments.put(to, filtered[0]); + docComments.put(from.get(), filtered[1]); } } } catch (Exception ignore) {} diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index fd0b0f0d..9978a681 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -131,12 +131,12 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { private static final TreeTag IMPORT = treeTag("IMPORT"); private static final TreeTag VARDEF = treeTag("VARDEF"); private static final TreeTag SELECT = treeTag("SELECT"); - + private static final Map OPERATORS; static { - Map map = new HashMap(); - + Map map = new HashMap(); + map.put(treeTag("POS"), "+"); map.put(treeTag("NEG"), "-"); map.put(treeTag("NOT"), "!"); @@ -165,132 +165,133 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { map.put(treeTag("MUL"), "*"); map.put(treeTag("DIV"), "/"); map.put(treeTag("MOD"), "%"); - - OPERATORS = map; + + OPERATORS = map; } - private List comments; - private final JCCompilationUnit cu; - private boolean onNewLine = true; - private boolean aligned = false; - private boolean inParams = false; - - private boolean needsSpace = false; - private boolean needsNewLine = false; - private boolean needsAlign = false; - + private List comments; + private final JCCompilationUnit cu; + private boolean onNewLine = true; + private boolean aligned = false; + private boolean inParams = false; + + private boolean needsSpace = false; + private boolean needsNewLine = false; + private boolean needsAlign = false; + public PrettyCommentsPrinter(Writer out, JCCompilationUnit cu, List comments) { this.out = out; - this.comments = comments; - this.cu = cu; + this.comments = comments; + this.cu = cu; + } + + private int endPos(JCTree tree) { + return getEndPosition(tree, cu); + } + + private void consumeComments(int until) throws IOException { + consumeComments(until, null); } - - private int endPos(JCTree tree) { - return tree.getEndPosition(cu.endPositions); - } - private void consumeComments(int until) throws IOException { - consumeComments(until, null); - } private void consumeComments(int until, JCTree tree) throws IOException { - boolean prevNewLine = onNewLine; - boolean found = false; - CommentInfo head = comments.head; - while (comments.nonEmpty() && head.pos < until) { - if (tree != null && docComments != null && docComments.containsKey(tree) && head.isJavadoc() && noFurtherJavadocForthcoming(until)) { - // This is (presumably) the exact same javadoc that has already been associated with the node that we're just about to - // print. These javadoc can be modified by lombok handlers, and as such we should NOT print them from the consumed comments db, - // and instead print the actual javadoc associated with the upcoming node (which the visit method for that node will take care of). - } else { - printComment(head); - } - comments = comments.tail; - head = comments.head; - } - if (!onNewLine && prevNewLine) { - println(); - } - } + boolean prevNewLine = onNewLine; + boolean found = false; + CommentInfo head = comments.head; + while (comments.nonEmpty() && head.pos < until) { + if (tree != null && docComments != null && docComments.containsKey(tree) && head.isJavadoc() && noFurtherJavadocForthcoming(until)) { + // This is (presumably) the exact same javadoc that has already been associated with the node that we're just about to + // print. These javadoc can be modified by lombok handlers, and as such we should NOT print them from the consumed comments db, + // and instead print the actual javadoc associated with the upcoming node (which the visit method for that node will take care of). + } else { + printComment(head); + } + comments = comments.tail; + head = comments.head; + } + if (!onNewLine && prevNewLine) { + println(); + } + } private boolean noFurtherJavadocForthcoming(int until) { - List c = comments; - if (c.nonEmpty()) c = c.tail; - while (c.nonEmpty()) { - if (c.head.pos >= until) return true; - if (c.head.isJavadoc()) return false; - c = c.tail; - } - return true; + List c = comments; + if (c.nonEmpty()) c = c.tail; + while (c.nonEmpty()) { + if (c.head.pos >= until) return true; + if (c.head.isJavadoc()) return false; + c = c.tail; + } + return true; } - + private void consumeTrailingComments(int from) throws IOException { - boolean prevNewLine = onNewLine; - CommentInfo head = comments.head; - boolean stop = false; - while (comments.nonEmpty() && head.prevEndPos == from && !stop && !(head.start == StartConnection.ON_NEXT_LINE || head.start == StartConnection.START_OF_LINE)) { - from = head.endPos; - printComment(head); - stop = (head.end == EndConnection.ON_NEXT_LINE); - comments = comments.tail; - head = comments.head; - } - if (!onNewLine && prevNewLine) { - println(); - } - } - - private void printComment(CommentInfo comment) throws IOException { - prepareComment(comment.start); - print(comment.content); - switch (comment.end) { - case ON_NEXT_LINE: - if (!aligned) { - needsNewLine = true; - needsAlign = true; - } - break; - case AFTER_COMMENT: - needsSpace = true; - break; - case DIRECT_AFTER_COMMENT: - // do nothing - break; - } + boolean prevNewLine = onNewLine; + CommentInfo head = comments.head; + boolean stop = false; + while (comments.nonEmpty() && head.prevEndPos == from && !stop && !(head.start == StartConnection.ON_NEXT_LINE || head.start == StartConnection.START_OF_LINE)) { + from = head.endPos; + printComment(head); + stop = (head.end == EndConnection.ON_NEXT_LINE); + comments = comments.tail; + head = comments.head; + } + if (!onNewLine && prevNewLine) { + println(); + } + } + + private void printComment(CommentInfo comment) throws IOException { + prepareComment(comment.start); + print(comment.content); + switch (comment.end) { + case ON_NEXT_LINE: + if (!aligned) { + needsNewLine = true; + needsAlign = true; + } + break; + case AFTER_COMMENT: + needsSpace = true; + break; + case DIRECT_AFTER_COMMENT: + // do nothing + break; + } + } + + private void prepareComment(StartConnection start) throws IOException { + switch (start) { + case DIRECT_AFTER_PREVIOUS: + needsSpace = false; + break; + case AFTER_PREVIOUS: + needsSpace = true; + break; + case START_OF_LINE: + needsNewLine = true; + needsAlign = false; + break; + case ON_NEXT_LINE: + if (!aligned) { + needsNewLine = true; + needsAlign = true; + } + break; + } } - - private void prepareComment(StartConnection start) throws IOException { - switch (start) { - case DIRECT_AFTER_PREVIOUS: - needsSpace = false; - break; - case AFTER_PREVIOUS: - needsSpace = true; - break; - case START_OF_LINE: - needsNewLine = true; - needsAlign = false; - break; - case ON_NEXT_LINE: - if (!aligned) { - needsNewLine = true; - needsAlign = true; - } - break; - } - } /** The output stream on which trees are printed. */ Writer out; - + /** The current left margin. */ int lmargin = 0; - + /** The enclosing class name. */ Name enclClassName; - + /** A hashtable mapping trees to their documentation comments * (can be null) */ @@ -304,19 +305,19 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { needsAlign = false; for (int i = 0; i < lmargin; i++) out.write("\t"); } - + /** Increase left margin by indentation width. */ void indent() { lmargin++; } - + /** Decrease left margin by indentation width. */ void undent() { lmargin--; } - + /** Enter a new precedence level. Emit a `(' if new precedence level * is less than precedence level so far. * @param contextPrec The precedence level in force so far. @@ -325,7 +326,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { void open(int contextPrec, int ownPrec) throws IOException { if (ownPrec < contextPrec) out.write("("); } - + /** Leave precedence level. Emit a `(' if inner precedence level * is less than precedence level we revert to. * @param contextPrec The precedence level we revert to. @@ -334,7 +335,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { void close(int contextPrec, int ownPrec) throws IOException { if (ownPrec < contextPrec) out.write(")"); } - + /** Print string, replacing all non-ascii character with unicode escapes. */ public void print(Object s) throws IOException { diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index edbf55af..12baf5af 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -116,6 +116,18 @@ public class JavacTreeMaker { this.paramTypes = types; this.returnType = returnType; } + + @Override public String toString() { + StringBuilder out = new StringBuilder(); + out.append(returnType.getName()).append(" ").append(owner.getName()).append(".").append(name).append("("); + boolean f = true; + for (Class p : paramTypes) { + if (f) f = false; + else out.append(", "); + out.append(p.getName()); + } + return out.append(")").toString(); + } } private static class SchroedingerType { @@ -154,13 +166,23 @@ public class JavacTreeMaker { return value; } - static Object getFieldCached(ConcurrentMap, Field> cache, Object ref, String fieldName) { + private static Field NOSUCHFIELDEX_MARKER; + static { + try { + NOSUCHFIELDEX_MARKER = SchroedingerType.class.getDeclaredField("NOSUCHFIELDEX_MARKER"); + } catch (NoSuchFieldException e) { + throw Javac.sneakyThrow(e); + } + } + + static Object getFieldCached(ConcurrentMap, Field> cache, Object ref, String fieldName) throws NoSuchFieldException { Class c = ref.getClass(); Field field = cache.get(c); if (field == null) { try { field = c.getField(fieldName); } catch (NoSuchFieldException e) { + cache.putIfAbsent(c, NOSUCHFIELDEX_MARKER); throw Javac.sneakyThrow(e); } field.setAccessible(true); @@ -168,6 +190,7 @@ public class JavacTreeMaker { if (old != null) field = old; } + if (field == NOSUCHFIELDEX_MARKER) throw new NoSuchFieldException(fieldName); try { return field.get(ref); } catch (IllegalAccessException e) { @@ -179,17 +202,42 @@ public class JavacTreeMaker { public static class TypeTag extends SchroedingerType { private static final ConcurrentMap TYPE_TAG_CACHE = new ConcurrentHashMap(); private static final ConcurrentMap, Field> FIELD_CACHE = new ConcurrentHashMap, Field>(); + private static final Method TYPE_TYPETAG_METHOD; + + static { + Method m = null; + try { + m = Type.class.getDeclaredMethod("getTag"); + m.setAccessible(true); + } catch (NoSuchMethodException e) {} + TYPE_TYPETAG_METHOD = m; + } private TypeTag(Object value) { super(value); } public static TypeTag typeTag(JCTree o) { - return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag")); + try { + return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag")); + } catch (NoSuchFieldException e) { + throw Javac.sneakyThrow(e); + } } public static TypeTag typeTag(Type t) { - return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag")); + try { + return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag")); + } catch (NoSuchFieldException e) { + if (TYPE_TYPETAG_METHOD == null) throw new IllegalStateException("Type " + t.getClass() + " has neither 'tag' nor getTag()"); + try { + return new TypeTag(TYPE_TYPETAG_METHOD.invoke(t)); + } catch (IllegalAccessException ex) { + throw Javac.sneakyThrow(ex); + } catch (InvocationTargetException ex) { + throw Javac.sneakyThrow(ex.getCause()); + } + } } public static TypeTag typeTag(String identifier) { @@ -331,7 +379,7 @@ public class JavacTreeMaker { if (found == null) found = method; else throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m); } - if (found == null) throw new IllegalStateException("Lombok TreeMaker frontedn issue: no match when looking for method: " + m); + if (found == null) throw new IllegalStateException("Lombok TreeMaker frontend issue: no match when looking for method: " + m); found.setAccessible(true); Object marker = METHOD_CACHE.putIfAbsent(m, found); if (marker == null) return found; @@ -496,7 +544,7 @@ public class JavacTreeMaker { //javac versions: 6-8 private static final MethodId Throw = MethodId("Throw"); - public JCThrow Throw(JCTree expr) { + public JCThrow Throw(JCExpression expr) { return invoke(Throw, expr); } -- cgit From 9ed14b8cbf8beb209f0d63e69e472bf81efe1d35 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 6 Aug 2013 21:22:24 +0200 Subject: added Flags.PARAMETER to all the parameters we generate in javac. --- src/core/lombok/javac/handlers/HandleConstructor.java | 4 ++-- src/core/lombok/javac/handlers/HandleDelegate.java | 2 +- src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java | 4 ++-- src/core/lombok/javac/handlers/HandleSetter.java | 2 +- src/core/lombok/javac/handlers/HandleWither.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 1134c45c..99c426de 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -231,7 +231,7 @@ public class HandleConstructor { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); List nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List 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)), field.name, 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)); @@ -292,7 +292,7 @@ public class HandleConstructor { JCExpression pType = cloneType(maker, field.vartype, source); List nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List 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)), field.name, pType, null); params.append(param); args.append(maker.Ident(field.name)); } diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index 33627072..6af34f20 100644 --- a/src/core/lombok/javac/handlers/HandleDelegate.java +++ b/src/core/lombok/javac/handlers/HandleDelegate.java @@ -305,7 +305,7 @@ public class HandleDelegate extends JavacAnnotationHandler { 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)); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 88ab3871..9e871b4e 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -371,7 +371,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler statements = ListBuffer.lb(); - final List params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null)); + final List 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), @@ -501,7 +501,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), otherName, objectType, null)); + List params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), otherName, objectType, null)); JCBlock body = maker.Block(0, List.of( maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode))))); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 1f8caa9b..6f345418 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -211,7 +211,7 @@ public class HandleSetter extends JavacAnnotationHandler { Name methodName = field.toName(setterName); List 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)); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 9397caa0..4bda5464 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -214,7 +214,7 @@ public class HandleWither extends JavacAnnotationHandler { Name methodName = field.toName(witherName); List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); - JCVariableDecl param = maker.VarDef(maker.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; -- cgit From df69425550d55da3de07f922fced3872432cd9d3 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 6 Aug 2013 21:22:48 +0200 Subject: position now set for all code generated by javac handlers; this also solves the AssertionError in the Bits class on javac8-ea. --- src/core/lombok/javac/handlers/JavacHandlerUtil.java | 3 +++ src/delombok/lombok/delombok/Delombok.java | 18 +++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index c245d506..65997f9a 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -97,6 +97,7 @@ public class JavacHandlerUtil { } @Override public void scan(JCTree tree) { + if (tree == null) return; setGeneratedBy(tree, source); super.scan(tree); } @@ -134,10 +135,12 @@ public class JavacHandlerUtil { } public static 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(source)); } + if (source != null) node.pos = source.pos; return node; } diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 7291ac29..473afb5c 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -30,6 +30,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.Writer; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; @@ -49,6 +50,7 @@ import javax.tools.JavaFileObject; import lombok.Lombok; import lombok.javac.CommentCatcher; import lombok.javac.LombokOptions; +import lombok.javac.apt.Processor; import com.sun.tools.javac.comp.Todo; import com.sun.tools.javac.main.JavaCompiler; @@ -363,7 +365,7 @@ public class Delombok { if (classpath != null) options.putJavacOption("CLASSPATH", classpath); if (sourcepath != null) options.putJavacOption("SOURCEPATH", sourcepath); if (bootclasspath != null) options.putJavacOption("BOOTCLASSPATH", bootclasspath); - options.put("compilePolicy", "attr"); + options.put("compilePolicy", "check"); CommentCatcher catcher = CommentCatcher.create(context); JavaCompiler compiler = catcher.getCompiler(); @@ -374,10 +376,7 @@ public class Delombok { compiler.initProcessAnnotations(Collections.singleton(new lombok.javac.apt.Processor())); for (File fileToParse : filesToParse) { - - @SuppressWarnings("deprecation") - JCCompilationUnit unit = compiler.parse(fileToParse.getAbsolutePath()); - + @SuppressWarnings("deprecation") JCCompilationUnit unit = compiler.parse(fileToParse.getAbsolutePath()); baseMap.put(unit, fileToBase.get(fileToParse)); roots.add(unit); } @@ -386,8 +385,13 @@ public class Delombok { return false; } - JavaCompiler delegate = compiler.processAnnotations(compiler.enterTrees(toJavacList(roots))); - callFlowMethodOnJavaCompiler(delegate, callAttributeMethodOnJavaCompiler(delegate, delegate.todo)); + com.sun.tools.javac.util.List trees = compiler.enterTrees(toJavacList(roots)); + + JavaCompiler delegate = compiler.processAnnotations(trees); + + Object care = callAttributeMethodOnJavaCompiler(delegate, delegate.todo); + + callFlowMethodOnJavaCompiler(delegate, care); for (JCCompilationUnit unit : roots) { DelombokResult result = new DelombokResult(catcher.getComments(unit), unit, force || options.isChanged(unit)); if (verbose) feedback.printf("File: %s [%s]\n", unit.sourcefile.getName(), result.isChanged() ? "delomboked" : "unchanged"); -- cgit From 7faff42d85c2e21b9a3b2e0014ebc36dbe5eb155 Mon Sep 17 00:00:00 2001 From: Jan Ouwens Date: Sun, 11 Aug 2013 20:39:30 +0200 Subject: Fixed two typos --- src/core/lombok/core/Version.java | 2 +- src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index bd83c1f8..867694e0 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -29,7 +29,7 @@ public class Version { // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). private static final String VERSION = "0.12.1"; - private static final String RELEASE_NAME = "Angry Butterfy"; + private static final String RELEASE_NAME = "Angry Butterfly"; private Version() { //Prevent instantiation diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 6990e609..3c8a7039 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -221,7 +221,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler Date: Sun, 11 Aug 2013 21:13:16 +0200 Subject: Oops: didn't realise the text appeared in multiple places. --- src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java | 2 +- .../EqualsAndHashCodeWithSomeExistingMethods.java.messages | 4 ++-- .../EqualsAndHashCodeWithSomeExistingMethods.java.messages | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 3b1e226f..e8dde83c 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -195,7 +195,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler Date: Mon, 12 Aug 2013 22:51:13 +0200 Subject: replaced double underscore as new standard way of writing the dummy annotation for onX instead of single underscore, which emits warnings on javac8+. Also made dollars and Xes legal in addition to underscores, in case double underscore disappears later too. --- .../eclipse/handlers/EclipseHandlerUtil.java | 36 +++++++++++----------- .../lombok/javac/handlers/JavacHandlerUtil.java | 12 ++++---- test/transform/resource/before/Constructors.java | 2 +- test/transform/resource/before/GetterOnMethod.java | 4 +-- .../resource/before/GetterOnMethodErrors.java | 2 +- .../resource/before/GetterOnMethodErrors2.java | 14 ++++----- .../resource/before/SetterOnMethodOnParam.java | 4 +-- .../GetterOnMethodErrors2.java.messages | 8 ++--- .../GetterOnMethodErrors2.java.messages | 8 ++--- 9 files changed, 45 insertions(+), 45 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 9bd634f7..d74b8981 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1562,9 +1562,9 @@ public class EclipseHandlerUtil { intLiteralFactoryMethod = intLiteralFactoryMethod_; } - private static boolean isAllUnderscores(char[] in) { + private static boolean isAllValidOnXCharacters(char[] in) { if (in == null || in.length == 0) return false; - for (char c : in) if (c != '_') return false; + for (char c : in) if (c != '_' && c != 'X' && c != 'x' && c != '$') return false; return true; } @@ -1597,31 +1597,31 @@ public class EclipseHandlerUtil { if (i > 0) System.arraycopy(pairs, 0, newPairs, 0, i); if (i < pairs.length - 1) System.arraycopy(pairs, i + 1, newPairs, i, pairs.length - i - 1); normalAnnotation.memberValuePairs = newPairs; - // We have now removed the annotation parameter and stored '@_({... annotations ...})', + // We have now removed the annotation parameter and stored '@__({... annotations ...})', // which we must now unbox. if (!(value instanceof Annotation)) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } - Annotation atUnderscore = (Annotation) value; - if (!(atUnderscore.type instanceof SingleTypeReference) || - !isAllUnderscores(((SingleTypeReference) atUnderscore.type).token)) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + Annotation atDummyIdentifier = (Annotation) value; + if (!(atDummyIdentifier.type instanceof SingleTypeReference) || + !isAllValidOnXCharacters(((SingleTypeReference) atDummyIdentifier.type).token)) { + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } - if (atUnderscore instanceof MarkerAnnotation) { - // It's @getter(onMethod=@_). This is weird, but fine. + if (atDummyIdentifier instanceof MarkerAnnotation) { + // It's @Getter(onMethod=@__). This is weird, but fine. return Collections.emptyList(); } Expression content = null; - if (atUnderscore instanceof NormalAnnotation) { - MemberValuePair[] mvps = ((NormalAnnotation) atUnderscore).memberValuePairs; + if (atDummyIdentifier instanceof NormalAnnotation) { + MemberValuePair[] mvps = ((NormalAnnotation) atDummyIdentifier).memberValuePairs; if (mvps == null || mvps.length == 0) { - // It's @getter(onMethod=@_()). This is weird, but fine. + // It's @Getter(onMethod=@__()). This is weird, but fine. return Collections.emptyList(); } if (mvps.length == 1 && Arrays.equals("value".toCharArray(), mvps[0].name)) { @@ -1629,12 +1629,12 @@ public class EclipseHandlerUtil { } } - if (atUnderscore instanceof SingleMemberAnnotation) { - content = ((SingleMemberAnnotation) atUnderscore).memberValue; + if (atDummyIdentifier instanceof SingleMemberAnnotation) { + content = ((SingleMemberAnnotation) atDummyIdentifier).memberValue; } if (content == null) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } @@ -1646,13 +1646,13 @@ public class EclipseHandlerUtil { if (expressions != null) for (Expression ex : expressions) { if (ex instanceof Annotation) result.add((Annotation) ex); else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } } return result; } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 65997f9a..d518c4df 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1009,9 +1009,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) { @@ -1020,7 +1020,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; } } @@ -1032,12 +1032,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; } } @@ -1045,7 +1045,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}))"); } } } diff --git a/test/transform/resource/before/Constructors.java b/test/transform/resource/before/Constructors.java index 0ab7b7f0..45b3a199 100644 --- a/test/transform/resource/before/Constructors.java +++ b/test/transform/resource/before/Constructors.java @@ -10,7 +10,7 @@ final int x; String name; } -@lombok.RequiredArgsConstructor(onConstructor=@_(@Deprecated)) class RequiredArgsConstructorWithAnnotations { +@lombok.RequiredArgsConstructor(onConstructor=@__(@Deprecated)) class RequiredArgsConstructorWithAnnotations { final int x; String name; } diff --git a/test/transform/resource/before/GetterOnMethod.java b/test/transform/resource/before/GetterOnMethod.java index 558f3f64..3e56a66e 100644 --- a/test/transform/resource/before/GetterOnMethod.java +++ b/test/transform/resource/before/GetterOnMethod.java @@ -1,6 +1,6 @@ class GetterOnMethod { - @lombok.Getter(onMethod=@_(@Deprecated)) int i; - @lombok.Getter(onMethod=@_({@java.lang.Deprecated, @Test})) int j, k; + @lombok.Getter(onMethod=@__(@Deprecated)) int i; + @lombok.Getter(onMethod=@__({@java.lang.Deprecated, @Test})) int j, k; public @interface Test { } diff --git a/test/transform/resource/before/GetterOnMethodErrors.java b/test/transform/resource/before/GetterOnMethodErrors.java index ae5d5b54..ec4704f0 100644 --- a/test/transform/resource/before/GetterOnMethodErrors.java +++ b/test/transform/resource/before/GetterOnMethodErrors.java @@ -1,6 +1,6 @@ class PlaceFillerToMakeSurePositionIsRelevant { } -@lombok.Getter(onMethod=@_(@Deprecated)) +@lombok.Getter(onMethod=@__(@Deprecated)) class GetterOnMethodErrors { private int test; } diff --git a/test/transform/resource/before/GetterOnMethodErrors2.java b/test/transform/resource/before/GetterOnMethodErrors2.java index 423183b9..2fd98c83 100644 --- a/test/transform/resource/before/GetterOnMethodErrors2.java +++ b/test/transform/resource/before/GetterOnMethodErrors2.java @@ -1,12 +1,12 @@ class GetterOnMethodErrors2 { @lombok.Getter(onMethod=@_A_(@Deprecated)) private int bad1; - @lombok.Getter(onMethod=@_(5)) private int bad2; - @lombok.Getter(onMethod=@_({@Deprecated, 5})) private int bad3; - @lombok.Getter(onMethod=@_(bar=@Deprecated)) private int bad4; - @lombok.Getter(onMethod=@_) private int good1; - @lombok.Getter(onMethod=@_()) private int good2; - @lombok.Getter(onMethod=@_(value=@Deprecated)) private int good3; - @lombok.Getter(onMethod=@_(value={@Deprecated, @Test})) private int good4; + @lombok.Getter(onMethod=@__(5)) private int bad2; + @lombok.Getter(onMethod=@__({@Deprecated, 5})) private int bad3; + @lombok.Getter(onMethod=@$(bar=@Deprecated)) private int bad4; + @lombok.Getter(onMethod=@__) private int good1; + @lombok.Getter(onMethod=@X()) private int good2; + @lombok.Getter(onMethod=@__(value=@Deprecated)) private int good3; + @lombok.Getter(onMethod=@xXx$$(value={@Deprecated, @Test})) private int good4; public @interface Test { } } diff --git a/test/transform/resource/before/SetterOnMethodOnParam.java b/test/transform/resource/before/SetterOnMethodOnParam.java index 70f3dc8c..4e042cf4 100644 --- a/test/transform/resource/before/SetterOnMethodOnParam.java +++ b/test/transform/resource/before/SetterOnMethodOnParam.java @@ -1,6 +1,6 @@ class SetterOnMethodOnParam { - @lombok.Setter(onMethod=@_(@Deprecated)) int i; - @lombok.Setter(onMethod=@_({@java.lang.Deprecated, @Test}), onParam=@_(@Test)) int j, k; + @lombok.Setter(onMethod=@__(@Deprecated)) int i; + @lombok.Setter(onMethod=@__({@java.lang.Deprecated, @Test}), onParam=@__(@Test)) int j, k; public @interface Test { } diff --git a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages index ead040a5..b5bad45b 100644 --- a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2:9 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -3:9 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -4:9 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -5:9 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +2:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +3:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +4:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +5:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) diff --git a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages index 6b949f41..f87b9f13 100644 --- a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2:31 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -3:93 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -4:143 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) -5:208 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +2:31 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +3:93 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +4:144 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +5:210 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -- cgit From b93318da303b36957f3774015090121af778665f Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 14 Aug 2013 07:05:31 +0200 Subject: * Fixed 553: @XArgsConstructor (and @Builder on a class) did not look at @Accessors to handle field accessors. * various operations on names in javac were really slow; they are faster now. --- src/core/lombok/core/TransformationsUtil.java | 5 +- .../eclipse/handlers/EclipseHandlerUtil.java | 31 +++++++++++ .../lombok/eclipse/handlers/HandleBuilder.java | 2 +- .../lombok/eclipse/handlers/HandleConstructor.java | 11 ++-- .../lombok/javac/handlers/HandleAccessors.java | 2 + src/core/lombok/javac/handlers/HandleBuilder.java | 2 +- .../lombok/javac/handlers/HandleConstructor.java | 17 ++++-- .../lombok/javac/handlers/JavacHandlerUtil.java | 31 +++++++++++ .../after-delombok/BuilderWithAccessors.java | 65 ++++++++++++++++++++++ .../after-delombok/ConstructorsWithAccessors.java | 15 +++++ .../resource/after-ecj/BuilderWithAccessors.java | 47 ++++++++++++++++ .../after-ecj/ConstructorsWithAccessors.java | 13 +++++ .../resource/before/BuilderWithAccessors.java | 7 +++ .../resource/before/ConstructorsWithAccessors.java | 6 ++ 14 files changed, 241 insertions(+), 13 deletions(-) create mode 100644 test/transform/resource/after-delombok/BuilderWithAccessors.java create mode 100644 test/transform/resource/after-delombok/ConstructorsWithAccessors.java create mode 100644 test/transform/resource/after-ecj/BuilderWithAccessors.java create mode 100644 test/transform/resource/after-ecj/ConstructorsWithAccessors.java create mode 100644 test/transform/resource/before/BuilderWithAccessors.java create mode 100644 test/transform/resource/before/ConstructorsWithAccessors.java (limited to 'src/core') diff --git a/src/core/lombok/core/TransformationsUtil.java b/src/core/lombok/core/TransformationsUtil.java index 8959ad7a..8c7fbd3f 100644 --- a/src/core/lombok/core/TransformationsUtil.java +++ b/src/core/lombok/core/TransformationsUtil.java @@ -70,9 +70,11 @@ public class TransformationsUtil { * @param prefixes A list of prefixes, usually provided by the {@code Accessors} settings annotation, listing field prefixes. * @return The base name of the field. */ - private static CharSequence removePrefix(CharSequence fieldName, String[] prefixes) { + public static CharSequence removePrefix(CharSequence fieldName, String[] prefixes) { if (prefixes == null || prefixes.length == 0) return fieldName; + fieldName = fieldName.toString(); + outer: for (String prefix : prefixes) { if (prefix.length() == 0) return fieldName; @@ -176,6 +178,7 @@ public class TransformationsUtil { private static String toAccessorName(AnnotationValues accessors, CharSequence fieldName, boolean isBoolean, String booleanPrefix, String normalPrefix, boolean adhereToFluent) { + fieldName = fieldName.toString(); if (fieldName.length() == 0) return null; Accessors ac = accessors == null ? null : accessors.getInstance(); diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 9bd634f7..d666084e 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1125,6 +1125,37 @@ public class EclipseHandlerUtil { return true; } + public static char[] removePrefixFromField(EclipseNode field) { + String[] prefixes = null; + for (EclipseNode node : field.down()) { + if (annotationTypeMatches(Accessors.class, node)) { + prefixes = createAnnotation(Accessors.class, node).getInstance().prefix(); + break; + } + } + + if (prefixes == null) { + EclipseNode current = field.up(); + outer: + while (current != null) { + for (EclipseNode 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 newName.toString().toCharArray(); + } + + return ((FieldDeclaration) field.get()).name; + } + public static AnnotationValues getAccessorsForField(EclipseNode field) { for (EclipseNode node : field.down()) { if (annotationTypeMatches(Accessors.class, node)) { diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 70110a9c..981d77dc 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -113,7 +113,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { // 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.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue; - namesOfParameters.add(fd.name); + namesOfParameters.add(removePrefixFromField(fieldNode)); typesOfParameters.add(fd.type); fields.add(fieldNode); } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 1ae680d9..22285b2d 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -230,7 +230,8 @@ public class HandleConstructor { int ctr = 0; for (EclipseNode field : fields) { - fieldNames.expressions[ctr] = new StringLiteral(field.getName().toCharArray(), pS, pE, 0); + char[] fieldName = removePrefixFromField(field); + fieldNames.expressions[ctr] = new StringLiteral(fieldName, pS, pE, 0); setGeneratedBy(fieldNames.expressions[ctr], source); ctr++; } @@ -273,15 +274,17 @@ public class HandleConstructor { for (EclipseNode fieldNode : fields) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - FieldReference thisX = new FieldReference(field.name, p); + char[] rawName = field.name; + char[] fieldName = removePrefixFromField(fieldNode); + FieldReference thisX = new FieldReference(rawName, p); thisX.receiver = new ThisReference((int)(p >> 32), (int)p); - SingleNameReference assignmentNameRef = new SingleNameReference(field.name, p); + SingleNameReference assignmentNameRef = new SingleNameReference(fieldName, p); Assignment assignment = new Assignment(thisX, assignmentNameRef, (int)p); assignment.sourceStart = (int)(p >> 32); assignment.sourceEnd = assignment.statementEnd = (int)(p >> 32); assigns.add(assignment); long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; - Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); + Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL); Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); if (nonNulls.length != 0) { 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 { @Override public void handle(AnnotationValues 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..7e5662cd 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -106,7 +106,7 @@ public class HandleBuilder extends JavacAnnotationHandler { // 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); } diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index ecd982e9..df8739de 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -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) @@ -210,7 +211,8 @@ public class HandleConstructor { JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties"); ListBuffer fieldNames = ListBuffer.lb(); 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.nil(), fieldNames.toList()); JCAnnotation annotation = maker.Annotation(constructorPropertiesType, List.of(fieldNamesArray)); @@ -229,12 +231,14 @@ public class HandleConstructor { for (JavacNode fieldNode : fields) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); + Name fieldName = removePrefixFromField(fieldNode); + Name rawName = field.name; List nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List 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, 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()) { @@ -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 nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List 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, 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.nil(), constructorType, args.toList(), null)); JCBlock body = maker.Block(0, List.of(returnStatement)); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index d7d29da2..ae3fddbf 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -456,6 +456,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 getAccessorsForField(JavacNode field) { for (JavacNode node : field.down()) { if (annotationTypeMatches(Accessors.class, node)) { diff --git a/test/transform/resource/after-delombok/BuilderWithAccessors.java b/test/transform/resource/after-delombok/BuilderWithAccessors.java new file mode 100644 index 00000000..503c33be --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderWithAccessors.java @@ -0,0 +1,65 @@ +class BuilderWithAccessors { + private final int plower; + private final int pUpper; + private int _foo; + private int __bar; + @java.lang.SuppressWarnings("all") + BuilderWithAccessors(final int plower, final int upper, final int foo, final int _bar) { + this.plower = plower; + this.pUpper = upper; + this._foo = foo; + this.__bar = _bar; + } + @java.lang.SuppressWarnings("all") + public static class BuilderWithAccessorsBuilder { + private int plower; + private int upper; + private int foo; + private int _bar; + + @java.lang.SuppressWarnings("all") + BuilderWithAccessorsBuilder() { + + } + + @java.lang.SuppressWarnings("all") + public BuilderWithAccessorsBuilder plower(final int plower) { + this.plower = plower; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderWithAccessorsBuilder upper(final int upper) { + this.upper = upper; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderWithAccessorsBuilder foo(final int foo) { + this.foo = foo; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderWithAccessorsBuilder _bar(final int _bar) { + this._bar = _bar; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderWithAccessors build() { + return new BuilderWithAccessors(plower, upper, foo, _bar); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderWithAccessors.BuilderWithAccessorsBuilder(plower=" + this.plower + ", upper=" + this.upper + ", foo=" + this.foo + ", _bar=" + this._bar + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static BuilderWithAccessorsBuilder builder() { + return new BuilderWithAccessorsBuilder(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/ConstructorsWithAccessors.java b/test/transform/resource/after-delombok/ConstructorsWithAccessors.java new file mode 100644 index 00000000..9937c7ee --- /dev/null +++ b/test/transform/resource/after-delombok/ConstructorsWithAccessors.java @@ -0,0 +1,15 @@ +class ConstructorsWithAccessors { + int plower; + int pUpper; + int _huh; + int __huh2; + + @java.beans.ConstructorProperties({"plower", "upper", "huh", "_huh2"}) + @java.lang.SuppressWarnings("all") + public ConstructorsWithAccessors(final int plower, final int upper, final int huh, final int _huh2) { + this.plower = plower; + this.pUpper = upper; + this._huh = huh; + this.__huh2 = _huh2; + } +} diff --git a/test/transform/resource/after-ecj/BuilderWithAccessors.java b/test/transform/resource/after-ecj/BuilderWithAccessors.java new file mode 100644 index 00000000..79776dc4 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderWithAccessors.java @@ -0,0 +1,47 @@ +@lombok.experimental.Builder @lombok.experimental.Accessors(prefix = {"p", "_"}) class BuilderWithAccessors { + public static @java.lang.SuppressWarnings("all") class BuilderWithAccessorsBuilder { + private int plower; + private int upper; + private int foo; + private int _bar; + @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder plower(final int plower) { + this.plower = plower; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder upper(final int upper) { + this.upper = upper; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder foo(final int foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder _bar(final int _bar) { + this._bar = _bar; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderWithAccessors build() { + return new BuilderWithAccessors(plower, upper, foo, _bar); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((((("BuilderWithAccessors.BuilderWithAccessorsBuilder(plower=" + this.plower) + ", upper=") + this.upper) + ", foo=") + this.foo) + ", _bar=") + this._bar) + ")"); + } + } + private final int plower; + private final int pUpper; + private int _foo; + private int __bar; + @java.lang.SuppressWarnings("all") BuilderWithAccessors(final int plower, final int upper, final int foo, final int _bar) { + super(); + this.plower = plower; + this.pUpper = upper; + this._foo = foo; + this.__bar = _bar; + } + public static @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder builder() { + return new BuilderWithAccessorsBuilder(); + } +} diff --git a/test/transform/resource/after-ecj/ConstructorsWithAccessors.java b/test/transform/resource/after-ecj/ConstructorsWithAccessors.java new file mode 100644 index 00000000..0df8fbe1 --- /dev/null +++ b/test/transform/resource/after-ecj/ConstructorsWithAccessors.java @@ -0,0 +1,13 @@ +@lombok.AllArgsConstructor @lombok.experimental.Accessors(prefix = {"p", "_"}) class ConstructorsWithAccessors { + int plower; + int pUpper; + int _huh; + int __huh2; + public @java.beans.ConstructorProperties({"plower", "upper", "huh", "_huh2"}) @java.lang.SuppressWarnings("all") ConstructorsWithAccessors(final int plower, final int upper, final int huh, final int _huh2) { + super(); + this.plower = plower; + this.pUpper = upper; + this._huh = huh; + this.__huh2 = _huh2; + } +} diff --git a/test/transform/resource/before/BuilderWithAccessors.java b/test/transform/resource/before/BuilderWithAccessors.java new file mode 100644 index 00000000..4f5660a1 --- /dev/null +++ b/test/transform/resource/before/BuilderWithAccessors.java @@ -0,0 +1,7 @@ +@lombok.experimental.Builder @lombok.experimental.Accessors(prefix={"p", "_"}) +class BuilderWithAccessors { + private final int plower; + private final int pUpper; + private int _foo; + private int __bar; +} diff --git a/test/transform/resource/before/ConstructorsWithAccessors.java b/test/transform/resource/before/ConstructorsWithAccessors.java new file mode 100644 index 00000000..d242317d --- /dev/null +++ b/test/transform/resource/before/ConstructorsWithAccessors.java @@ -0,0 +1,6 @@ +@lombok.AllArgsConstructor @lombok.experimental.Accessors(prefix={"p", "_"}) class ConstructorsWithAccessors { + int plower; + int pUpper; + int _huh; + int __huh2; +} -- cgit From bad93ae677622c79883f658a53484d455e36ce9a Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 19 Aug 2013 23:50:57 +0200 Subject: Only look at the line number for errors and warnings. --- src/core/lombok/javac/CapturingDiagnosticListener.java | 15 +++------------ test/core/src/lombok/CompilerMessageMatcher.java | 14 +++++--------- test/core/src/lombok/RunTestsViaEcj.java | 2 +- .../resource/messages-delombok/Accessors.java.messages | 2 +- .../messages-delombok/BuilderInvalidUse.java.messages | 4 ++-- .../ConflictingStaticConstructorNames.java.messages | 2 +- .../EqualsAndHashCodeWithExistingMethods.java.messages | 6 +++--- ...qualsAndHashCodeWithSomeExistingMethods.java.messages | 4 ++-- .../messages-delombok/FieldDefaultsNoop.java.messages | 2 +- .../messages-delombok/GetterAlreadyExists.java.messages | 16 ++++++++-------- .../messages-delombok/GetterBoolean.java.messages | 2 +- .../messages-delombok/GetterLazyInvalid.java.messages | 12 ++++++------ .../messages-delombok/GetterOnMethodErrors.java.messages | 2 +- .../GetterOnMethodErrors2.java.messages | 8 ++++---- .../LoggerSlf4jAlreadyExists.java.messages | 2 +- .../LoggerSlf4jOnNonStaticInnerClass.java.messages | 2 +- .../messages-delombok/LoggerSlf4jOnNonType.java.messages | 2 +- .../messages-delombok/LoggerSlf4jTypes.java.messages | 4 ++-- .../messages-delombok/NonNullOnParameter.java.messages | 2 +- .../messages-delombok/NonNullPlain.java.messages | 2 +- .../messages-delombok/SetterAlreadyExists.java.messages | 14 +++++++------- .../messages-delombok/SetterOnMethod.java.messages | 14 +++++++------- .../messages-delombok/SetterOnParam.java.messages | 14 +++++++------- .../SetterOnParamAndOnMethod.java.messages | 4 ++-- .../messages-delombok/SimpleTypeResolution.java.messages | 2 +- .../SynchronizedNameNoSuchField.java.messages | 2 +- .../SynchronizedNameStaticToInstanceRef.java.messages | 2 +- .../resource/messages-delombok/ValErrors.java.messages | 4 ++-- .../messages-delombok/ValInBasicFor.java.messages | 2 +- .../messages-delombok/WitherAlreadyExists.java.messages | 14 +++++++------- .../messages-delombok/WitherOnStatic.java.messages | 4 ++-- .../messages-delombok/WitherWithDollar.java.messages | 2 +- .../resource/messages-ecj/Accessors.java.messages | 2 +- .../messages-ecj/BuilderInvalidUse.java.messages | 4 ++-- .../ConflictingStaticConstructorNames.java.messages | 2 +- .../EqualsAndHashCodeWithExistingMethods.java.messages | 6 +++--- ...qualsAndHashCodeWithSomeExistingMethods.java.messages | 4 ++-- .../messages-ecj/FieldDefaultsNoop.java.messages | 2 +- .../messages-ecj/GetterAlreadyExists.java.messages | 16 ++++++++-------- .../resource/messages-ecj/GetterBoolean.java.messages | 2 +- .../messages-ecj/GetterLazyInvalid.java.messages | 12 ++++++------ .../messages-ecj/GetterOnMethodErrors.java.messages | 2 +- .../messages-ecj/GetterOnMethodErrors2.java.messages | 8 ++++---- .../messages-ecj/LoggerSlf4jAlreadyExists.java.messages | 2 +- .../LoggerSlf4jOnNonStaticInnerClass.java.messages | 2 +- .../messages-ecj/LoggerSlf4jOnNonType.java.messages | 2 +- .../resource/messages-ecj/LoggerSlf4jTypes.java.messages | 4 ++-- .../messages-ecj/NonNullOnParameter.java.messages | 6 +++--- .../resource/messages-ecj/NonNullPlain.java.messages | 2 +- .../messages-ecj/SetterAlreadyExists.java.messages | 14 +++++++------- .../resource/messages-ecj/SetterOnMethod.java.messages | 4 ++-- .../resource/messages-ecj/SetterOnParam.java.messages | 4 ++-- .../messages-ecj/SimpleTypeResolution.java.messages | 2 +- .../resource/messages-ecj/SynchronizedName.java.messages | 2 +- .../SynchronizedNameNoSuchField.java.messages | 2 +- .../SynchronizedNameStaticToInstanceRef.java.messages | 2 +- .../resource/messages-ecj/ValErrors.java.messages | 4 ++-- .../resource/messages-ecj/ValInBasicFor.java.messages | 8 ++++---- .../resource/messages-ecj/ValRawType.java.messages | 2 +- .../messages-ecj/ValueExperimental.java.messages | 2 +- .../messages-ecj/WitherAlreadyExists.java.messages | 14 +++++++------- .../resource/messages-ecj/WitherOnStatic.java.messages | 4 ++-- .../resource/messages-ecj/WitherWithDollar.java.messages | 2 +- .../messages-idempotent/NonNullOnParameter.java.messages | 2 +- .../messages-idempotent/NonNullPlain.java.messages | 6 +++--- .../SimpleTypeResolution.java.messages | 2 +- .../SynchronizedNameStaticToInstanceRef.java.messages | 2 +- .../resource/messages-idempotent/ValErrors.java.messages | 6 +++--- .../messages-idempotent/ValInBasicFor.java.messages | 2 +- 69 files changed, 167 insertions(+), 180 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/CapturingDiagnosticListener.java b/src/core/lombok/javac/CapturingDiagnosticListener.java index 45b4047a..a0ac6adc 100644 --- a/src/core/lombok/javac/CapturingDiagnosticListener.java +++ b/src/core/lombok/javac/CapturingDiagnosticListener.java @@ -52,7 +52,7 @@ public class CapturingDiagnosticListener implements DiagnosticListener>> 32)); result = prime * result + ((message == null) ? 0 : message.hashCode()); - result = prime * result + (int) (columnOrPosition ^ (columnOrPosition >>> 32)); return result; } @@ -121,12 +113,11 @@ public class CapturingDiagnosticListener implements DiagnosticListener messageParts; - public CompilerMessageMatcher(long line, long position, String message) { + public CompilerMessageMatcher(long line, String message) { this.line = line; - this.position = position; this.messageParts = Arrays.asList(message.split("\\s+")); } public static CompilerMessageMatcher asCompilerMessageMatcher(CompilerMessage message) { - return new CompilerMessageMatcher(message.getLine(), message.getColumnOrPosition(), message.getMessage()); + return new CompilerMessageMatcher(message.getLine(), message.getMessage()); } @Override public String toString() { StringBuilder parts = new StringBuilder(); for (String part : messageParts) parts.append(part).append(" "); if (parts.length() > 0) parts.setLength(parts.length() - 1); - return String.format("%d:%d %s", line, position, parts); + return String.format("%d %s", line, parts); } public boolean matches(CompilerMessage message) { if (message.getLine() != this.line) return false; - if (message.getColumnOrPosition() != this.position) return false; for (String token : messageParts) { if (!message.getMessage().contains(token)) return false; } @@ -78,12 +74,12 @@ public class CompilerMessageMatcher { return out; } - private static final Pattern PATTERN = Pattern.compile("^(\\d+):(\\d+) (.*)$"); + private static final Pattern PATTERN = Pattern.compile("^(\\d+) (.*)$"); private static CompilerMessageMatcher read(String line) { line = line.trim(); if (line.isEmpty()) return null; Matcher m = PATTERN.matcher(line); if (!m.matches()) throw new IllegalArgumentException("Typo in test file: " + line); - return new CompilerMessageMatcher(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), m.group(3)); + return new CompilerMessageMatcher(Integer.parseInt(m.group(1)), m.group(2)); } } diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index f7294f1f..586c124a 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.java @@ -112,7 +112,7 @@ public class RunTestsViaEcj extends AbstractRunTests { CategorizedProblem[] problems = compilationResult.getAllProblems(); if (problems != null) for (CategorizedProblem p : problems) { - messages.add(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.getSourceStart(), p.isError(), p.getMessage())); + messages.add(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.isError(), p.getMessage())); } CompilationUnitDeclaration cud = compilationUnit_.get(); diff --git a/test/transform/resource/messages-delombok/Accessors.java.messages b/test/transform/resource/messages-delombok/Accessors.java.messages index 367621bd..265bc745 100644 --- a/test/transform/resource/messages-delombok/Accessors.java.messages +++ b/test/transform/resource/messages-delombok/Accessors.java.messages @@ -1 +1 @@ -19:9 Not generating setter for this field: It does not fit your @Accessors prefix list. \ No newline at end of file +19 Not generating setter for this field: It does not fit your @Accessors prefix list. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/BuilderInvalidUse.java.messages b/test/transform/resource/messages-delombok/BuilderInvalidUse.java.messages index aeeb0c86..a04b4f9b 100644 --- a/test/transform/resource/messages-delombok/BuilderInvalidUse.java.messages +++ b/test/transform/resource/messages-delombok/BuilderInvalidUse.java.messages @@ -1,2 +1,2 @@ -1:1 @Getter, @Setter, @Wither, @Data, @ToString, @EqualsAndHashCode, @AllArgsConstructor are not allowed on builder classes. -12:1 @Value is not allowed on builder classes. \ No newline at end of file +1 @Getter, @Setter, @Wither, @Data, @ToString, @EqualsAndHashCode, @AllArgsConstructor are not allowed on builder classes. +12 @Value is not allowed on builder classes. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/ConflictingStaticConstructorNames.java.messages b/test/transform/resource/messages-delombok/ConflictingStaticConstructorNames.java.messages index 06b88c10..4f915bbe 100644 --- a/test/transform/resource/messages-delombok/ConflictingStaticConstructorNames.java.messages +++ b/test/transform/resource/messages-delombok/ConflictingStaticConstructorNames.java.messages @@ -1 +1 @@ -1:1 Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used. +1 Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used. diff --git a/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages index 057a7521..b3490fd0 100644 --- a/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages +++ b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages @@ -1,3 +1,3 @@ -1:1 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). -10:1 Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated). -19:1 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). +1 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). +10 Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated). +19 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). diff --git a/test/transform/resource/messages-delombok/EqualsAndHashCodeWithSomeExistingMethods.java.messages b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithSomeExistingMethods.java.messages index 9a0b29f3..f5dfd559 100644 --- a/test/transform/resource/messages-delombok/EqualsAndHashCodeWithSomeExistingMethods.java.messages +++ b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithSomeExistingMethods.java.messages @@ -1,2 +1,2 @@ -4:1 Not generating equals: 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). -15:1 Not generating equals and hashCode: 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). +4 Not generating equals: 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). +15 Not generating equals and hashCode: 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). diff --git a/test/transform/resource/messages-delombok/FieldDefaultsNoop.java.messages b/test/transform/resource/messages-delombok/FieldDefaultsNoop.java.messages index ae5dd265..9fac15c4 100644 --- a/test/transform/resource/messages-delombok/FieldDefaultsNoop.java.messages +++ b/test/transform/resource/messages-delombok/FieldDefaultsNoop.java.messages @@ -1 +1 @@ -1:1 This does nothing; provide either level or makeFinal or both. \ No newline at end of file +1 This does nothing; provide either level or makeFinal or both. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/GetterAlreadyExists.java.messages b/test/transform/resource/messages-delombok/GetterAlreadyExists.java.messages index 7a326742..7d99aa69 100644 --- a/test/transform/resource/messages-delombok/GetterAlreadyExists.java.messages +++ b/test/transform/resource/messages-delombok/GetterAlreadyExists.java.messages @@ -1,8 +1,8 @@ -8:9 Not generating isFoo(): A method with that name already exists -14:9 Not generating isFoo(): A method with that name already exists (getFoo) -32:9 Not generating getFoo(): A method with that name already exists -50:9 Not generating getFoo(): A method with that name already exists -62:9 Not generating isFoo(): A method with that name already exists -68:9 Not generating isFoo(): A method with that name already exists (getFoo) -86:9 Not generating getFoo(): A method with that name already exists -104:9 Not generating getFoo(): A method with that name already exists +8 Not generating isFoo(): A method with that name already exists +14 Not generating isFoo(): A method with that name already exists (getFoo) +32 Not generating getFoo(): A method with that name already exists +50 Not generating getFoo(): A method with that name already exists +62 Not generating isFoo(): A method with that name already exists +68 Not generating isFoo(): A method with that name already exists (getFoo) +86 Not generating getFoo(): A method with that name already exists +104 Not generating getFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-delombok/GetterBoolean.java.messages b/test/transform/resource/messages-delombok/GetterBoolean.java.messages index 91ad3512..ab9d659d 100644 --- a/test/transform/resource/messages-delombok/GetterBoolean.java.messages +++ b/test/transform/resource/messages-delombok/GetterBoolean.java.messages @@ -1 +1 @@ -13:9 Not generating isFoo(): A method with that name already exists (getFoo) \ No newline at end of file +13 Not generating isFoo(): A method with that name already exists (getFoo) \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages b/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages index 5c72fd56..5cb47108 100644 --- a/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages +++ b/test/transform/resource/messages-delombok/GetterLazyInvalid.java.messages @@ -1,6 +1,6 @@ -2:9 'lazy' requires the field to be private and final. -6:9 'lazy' requires the field to be private and final. -10:9 'lazy' requires the field to be private and final. -14:9 'lazy' does not work with AccessLevel.NONE. -17:1 'lazy' is not supported for @Getter on a type. -22:9 'lazy' requires field initialization. \ No newline at end of file +2 'lazy' requires the field to be private and final. +6 'lazy' requires the field to be private and final. +10 'lazy' requires the field to be private and final. +14 'lazy' does not work with AccessLevel.NONE. +17 'lazy' is not supported for @Getter on a type. +22 'lazy' requires field initialization. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/GetterOnMethodErrors.java.messages b/test/transform/resource/messages-delombok/GetterOnMethodErrors.java.messages index 4c82f730..26c30298 100644 --- a/test/transform/resource/messages-delombok/GetterOnMethodErrors.java.messages +++ b/test/transform/resource/messages-delombok/GetterOnMethodErrors.java.messages @@ -1 +1 @@ -3:1 'onMethod' is not supported for @Getter on a type. \ No newline at end of file +3 'onMethod' is not supported for @Getter on a type. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages index b5bad45b..af1e3b7a 100644 --- a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -3:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -4:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -5:9 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +2 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +3 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +4 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +5 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages index 8aa22226..db5f9891 100644 --- a/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages +++ b/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages @@ -1 +1 @@ -1:1 Field 'log' already exists. +1 Field 'log' already exists. diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages index 570a169b..128a0c62 100644 --- a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages +++ b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages @@ -1 +1 @@ -2:9 @Log is not legal on non-static inner classes. \ No newline at end of file +2 @Log is not legal on non-static inner classes. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages index ebc23411..262fbb27 100644 --- a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages +++ b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages @@ -1 +1 @@ -2:9 @Log is legal only on types. \ No newline at end of file +2 @Log is legal only on types. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages index a525dd27..08f6bb7b 100644 --- a/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages +++ b/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages @@ -1,2 +1,2 @@ -1:1 @Log is legal only on classes and enums. -4:1 @Log is legal only on classes and enums. \ No newline at end of file +1 @Log is legal only on classes and enums. +4 @Log is legal only on classes and enums. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/NonNullOnParameter.java.messages b/test/transform/resource/messages-delombok/NonNullOnParameter.java.messages index ac87adcd..042c97f8 100644 --- a/test/transform/resource/messages-delombok/NonNullOnParameter.java.messages +++ b/test/transform/resource/messages-delombok/NonNullOnParameter.java.messages @@ -1 +1 @@ -22:89 @NonNull is meaningless on a primitive. +22 @NonNull is meaningless on a primitive. diff --git a/test/transform/resource/messages-delombok/NonNullPlain.java.messages b/test/transform/resource/messages-delombok/NonNullPlain.java.messages index 67eb8abe..4033f645 100644 --- a/test/transform/resource/messages-delombok/NonNullPlain.java.messages +++ b/test/transform/resource/messages-delombok/NonNullPlain.java.messages @@ -1 +1 @@ -7:9 @NonNull is meaningless on a primitive. \ No newline at end of file +8 @NonNull is meaningless on a primitive. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/SetterAlreadyExists.java.messages b/test/transform/resource/messages-delombok/SetterAlreadyExists.java.messages index 9cece93c..4b1e209b 100644 --- a/test/transform/resource/messages-delombok/SetterAlreadyExists.java.messages +++ b/test/transform/resource/messages-delombok/SetterAlreadyExists.java.messages @@ -1,7 +1,7 @@ -2:9 Not generating setFoo(): A method with that name already exists -8:9 Not generating setFoo(): A method with that name already exists -14:9 Not generating setFoo(): A method with that name already exists -20:9 Not generating setFoo(): A method with that name already exists -38:9 Not generating setFoo(): A method with that name already exists -44:9 Not generating setFoo(): A method with that name already exists (setIsFoo) -50:9 Not generating setFoo(): A method with that name already exists +2 Not generating setFoo(): A method with that name already exists +8 Not generating setFoo(): A method with that name already exists +14 Not generating setFoo(): A method with that name already exists +20 Not generating setFoo(): A method with that name already exists +38 Not generating setFoo(): A method with that name already exists +44 Not generating setFoo(): A method with that name already exists (setIsFoo) +50 Not generating setFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-delombok/SetterOnMethod.java.messages b/test/transform/resource/messages-delombok/SetterOnMethod.java.messages index 9473d5b3..1be8f1ea 100644 --- a/test/transform/resource/messages-delombok/SetterOnMethod.java.messages +++ b/test/transform/resource/messages-delombok/SetterOnMethod.java.messages @@ -1,7 +1,7 @@ -3:34 incompatible types -4:44 incompatible types -6:26 incompatible types -11:26 incompatible types -14:44 incompatible types -6:1 'onMethod' is not supported for @Setter on a type. -11:1 'onMethod' is not supported for @Setter on a type. +3 incompatible types +4 incompatible types +6 incompatible types +11 incompatible types +14 incompatible types +6 'onMethod' is not supported for @Setter on a type. +11 'onMethod' is not supported for @Setter on a type. diff --git a/test/transform/resource/messages-delombok/SetterOnParam.java.messages b/test/transform/resource/messages-delombok/SetterOnParam.java.messages index b8c69eca..828d9511 100644 --- a/test/transform/resource/messages-delombok/SetterOnParam.java.messages +++ b/test/transform/resource/messages-delombok/SetterOnParam.java.messages @@ -1,7 +1,7 @@ -3:33 incompatible types -4:43 incompatible types -6:25 incompatible types -11:25 incompatible types -14:43 incompatible types -6:1 'onParam' is not supported for @Setter on a type. -11:1 'onParam' is not supported for @Setter on a type. +3 incompatible types +4 incompatible types +6 incompatible types +11 incompatible types +14 incompatible types +6 'onParam' is not supported for @Setter on a type. +11 'onParam' is not supported for @Setter on a type. diff --git a/test/transform/resource/messages-delombok/SetterOnParamAndOnMethod.java.messages b/test/transform/resource/messages-delombok/SetterOnParamAndOnMethod.java.messages index 7324f6f3..86cbd0e6 100644 --- a/test/transform/resource/messages-delombok/SetterOnParamAndOnMethod.java.messages +++ b/test/transform/resource/messages-delombok/SetterOnParamAndOnMethod.java.messages @@ -1,2 +1,2 @@ -2:34 incompatible types -2:54 incompatible types +2 incompatible types +2 incompatible types diff --git a/test/transform/resource/messages-delombok/SimpleTypeResolution.java.messages b/test/transform/resource/messages-delombok/SimpleTypeResolution.java.messages index 7acd35ed..ec74f090 100644 --- a/test/transform/resource/messages-delombok/SimpleTypeResolution.java.messages +++ b/test/transform/resource/messages-delombok/SimpleTypeResolution.java.messages @@ -1 +1 @@ -2:10 cannot find symbol +2 cannot find symbol diff --git a/test/transform/resource/messages-delombok/SynchronizedNameNoSuchField.java.messages b/test/transform/resource/messages-delombok/SynchronizedNameNoSuchField.java.messages index f282d34d..ae351773 100644 --- a/test/transform/resource/messages-delombok/SynchronizedNameNoSuchField.java.messages +++ b/test/transform/resource/messages-delombok/SynchronizedNameNoSuchField.java.messages @@ -1 +1 @@ -5:9 The field write does not exist. +5 The field write does not exist. diff --git a/test/transform/resource/messages-delombok/SynchronizedNameStaticToInstanceRef.java.messages b/test/transform/resource/messages-delombok/SynchronizedNameStaticToInstanceRef.java.messages index 5d6bc958..fe0653c8 100644 --- a/test/transform/resource/messages-delombok/SynchronizedNameStaticToInstanceRef.java.messages +++ b/test/transform/resource/messages-delombok/SynchronizedNameStaticToInstanceRef.java.messages @@ -1 +1 @@ -5:9 non-static variable read cannot be referenced from a static context \ No newline at end of file +5 non-static variable read cannot be referenced from a static context \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/ValErrors.java.messages b/test/transform/resource/messages-delombok/ValErrors.java.messages index 887b8c21..bb33c6de 100644 --- a/test/transform/resource/messages-delombok/ValErrors.java.messages +++ b/test/transform/resource/messages-delombok/ValErrors.java.messages @@ -1,2 +1,2 @@ -5:21 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved -9:21 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... }) +5 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved +9 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... }) diff --git a/test/transform/resource/messages-delombok/ValInBasicFor.java.messages b/test/transform/resource/messages-delombok/ValInBasicFor.java.messages index 9bca1be6..7166b550 100644 --- a/test/transform/resource/messages-delombok/ValInBasicFor.java.messages +++ b/test/transform/resource/messages-delombok/ValInBasicFor.java.messages @@ -1 +1 @@ -6:53 'val' is not allowed in old-style for loops +6 'val' is not allowed in old-style for loops diff --git a/test/transform/resource/messages-delombok/WitherAlreadyExists.java.messages b/test/transform/resource/messages-delombok/WitherAlreadyExists.java.messages index b68f6398..d5e30e28 100644 --- a/test/transform/resource/messages-delombok/WitherAlreadyExists.java.messages +++ b/test/transform/resource/messages-delombok/WitherAlreadyExists.java.messages @@ -1,7 +1,7 @@ -2:9 Not generating withFoo(): A method with that name already exists -12:9 Not generating withFoo(): A method with that name already exists -22:9 Not generating withFoo(): A method with that name already exists -32:9 Not generating withFoo(): A method with that name already exists -62:9 Not generating withFoo(): A method with that name already exists -72:9 Not generating withFoo(): A method with that name already exists (withIsFoo) -82:9 Not generating withFoo(): A method with that name already exists +2 Not generating withFoo(): A method with that name already exists +12 Not generating withFoo(): A method with that name already exists +22 Not generating withFoo(): A method with that name already exists +32 Not generating withFoo(): A method with that name already exists +62 Not generating withFoo(): A method with that name already exists +72 Not generating withFoo(): A method with that name already exists (withIsFoo) +82 Not generating withFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-delombok/WitherOnStatic.java.messages b/test/transform/resource/messages-delombok/WitherOnStatic.java.messages index 9dd69e75..3af59fa1 100644 --- a/test/transform/resource/messages-delombok/WitherOnStatic.java.messages +++ b/test/transform/resource/messages-delombok/WitherOnStatic.java.messages @@ -1,2 +1,2 @@ -2:9 Not generating wither for this field: Withers cannot be generated for static fields. -3:9 Not generating wither for this field: Withers cannot be generated for static fields. +2 Not generating wither for this field: Withers cannot be generated for static fields. +3 Not generating wither for this field: Withers cannot be generated for static fields. diff --git a/test/transform/resource/messages-delombok/WitherWithDollar.java.messages b/test/transform/resource/messages-delombok/WitherWithDollar.java.messages index 74eeabba..84603868 100644 --- a/test/transform/resource/messages-delombok/WitherWithDollar.java.messages +++ b/test/transform/resource/messages-delombok/WitherWithDollar.java.messages @@ -1 +1 @@ -2:9 Not generating wither for this field: Withers cannot be generated for fields starting with $. +2 Not generating wither for this field: Withers cannot be generated for fields starting with $. diff --git a/test/transform/resource/messages-ecj/Accessors.java.messages b/test/transform/resource/messages-ecj/Accessors.java.messages index 3e6bbd69..c955f664 100644 --- a/test/transform/resource/messages-ecj/Accessors.java.messages +++ b/test/transform/resource/messages-ecj/Accessors.java.messages @@ -1 +1 @@ -19:530 Not generating setter for this field: It does not fit your @Accessors prefix list. +19 Not generating setter for this field: It does not fit your @Accessors prefix list. diff --git a/test/transform/resource/messages-ecj/BuilderInvalidUse.java.messages b/test/transform/resource/messages-ecj/BuilderInvalidUse.java.messages index 8ffc6e26..84942101 100644 --- a/test/transform/resource/messages-ecj/BuilderInvalidUse.java.messages +++ b/test/transform/resource/messages-ecj/BuilderInvalidUse.java.messages @@ -1,2 +1,2 @@ -1:0 @Getter, @Setter, @FieldDefaults, @Wither, @Data, @ToString, @EqualsAndHashCode, @AllArgsConstructor are not allowed on builder classes. -12:331 @Value is not allowed on builder classes. \ No newline at end of file +1 @Getter, @Setter, @FieldDefaults, @Wither, @Data, @ToString, @EqualsAndHashCode, @AllArgsConstructor are not allowed on builder classes. +12 @Value is not allowed on builder classes. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/ConflictingStaticConstructorNames.java.messages b/test/transform/resource/messages-ecj/ConflictingStaticConstructorNames.java.messages index 50f2e97f..4f915bbe 100644 --- a/test/transform/resource/messages-ecj/ConflictingStaticConstructorNames.java.messages +++ b/test/transform/resource/messages-ecj/ConflictingStaticConstructorNames.java.messages @@ -1 +1 @@ -1:0 Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used. +1 Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used. diff --git a/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages index db144316..b3490fd0 100644 --- a/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages +++ b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages @@ -1,3 +1,3 @@ -1:0 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). -10:125 Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated). -19:274 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). +1 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). +10 Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated). +19 Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated). diff --git a/test/transform/resource/messages-ecj/EqualsAndHashCodeWithSomeExistingMethods.java.messages b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithSomeExistingMethods.java.messages index cf6ebea2..f5dfd559 100644 --- a/test/transform/resource/messages-ecj/EqualsAndHashCodeWithSomeExistingMethods.java.messages +++ b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithSomeExistingMethods.java.messages @@ -1,2 +1,2 @@ -4:57 Not generating equals: 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). -15:194 Not generating equals and hashCode: 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). +4 Not generating equals: 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). +15 Not generating equals and hashCode: 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). diff --git a/test/transform/resource/messages-ecj/FieldDefaultsNoop.java.messages b/test/transform/resource/messages-ecj/FieldDefaultsNoop.java.messages index 5903679b..9fac15c4 100644 --- a/test/transform/resource/messages-ecj/FieldDefaultsNoop.java.messages +++ b/test/transform/resource/messages-ecj/FieldDefaultsNoop.java.messages @@ -1 +1 @@ -1:0 This does nothing; provide either level or makeFinal or both. \ No newline at end of file +1 This does nothing; provide either level or makeFinal or both. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/GetterAlreadyExists.java.messages b/test/transform/resource/messages-ecj/GetterAlreadyExists.java.messages index ae62a1fb..7d99aa69 100644 --- a/test/transform/resource/messages-ecj/GetterAlreadyExists.java.messages +++ b/test/transform/resource/messages-ecj/GetterAlreadyExists.java.messages @@ -1,8 +1,8 @@ -8:102 Not generating isFoo(): A method with that name already exists -14:186 Not generating isFoo(): A method with that name already exists (getFoo) -32:436 Not generating getFoo(): A method with that name already exists -50:688 Not generating getFoo(): A method with that name already exists -62:868 Not generating isFoo(): A method with that name already exists -68:961 Not generating isFoo(): A method with that name already exists (getFoo) -86:1240 Not generating getFoo(): A method with that name already exists -104:1510 Not generating getFoo(): A method with that name already exists +8 Not generating isFoo(): A method with that name already exists +14 Not generating isFoo(): A method with that name already exists (getFoo) +32 Not generating getFoo(): A method with that name already exists +50 Not generating getFoo(): A method with that name already exists +62 Not generating isFoo(): A method with that name already exists +68 Not generating isFoo(): A method with that name already exists (getFoo) +86 Not generating getFoo(): A method with that name already exists +104 Not generating getFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-ecj/GetterBoolean.java.messages b/test/transform/resource/messages-ecj/GetterBoolean.java.messages index 8ae086f6..8ebf0a31 100644 --- a/test/transform/resource/messages-ecj/GetterBoolean.java.messages +++ b/test/transform/resource/messages-ecj/GetterBoolean.java.messages @@ -1 +1 @@ -13:220 Not generating isFoo(): A method with that name already exists (getFoo) +13 Not generating isFoo(): A method with that name already exists (getFoo) diff --git a/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages b/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages index 9ecf0fc0..b18843e6 100644 --- a/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages +++ b/test/transform/resource/messages-ecj/GetterLazyInvalid.java.messages @@ -1,6 +1,6 @@ -2:35 'lazy' requires the field to be private and final. -6:132 'lazy' requires the field to be private and final. -10:232 'lazy' requires the field to be private and final. -14:315 'lazy' does not work with AccessLevel.NONE. -17:412 'lazy' is not supported for @Getter on a type. -22:544 'lazy' requires field initialization. +2 'lazy' requires the field to be private and final. +6 'lazy' requires the field to be private and final. +10 'lazy' requires the field to be private and final. +14 'lazy' does not work with AccessLevel.NONE. +17 'lazy' is not supported for @Getter on a type. +22 'lazy' requires field initialization. diff --git a/test/transform/resource/messages-ecj/GetterOnMethodErrors.java.messages b/test/transform/resource/messages-ecj/GetterOnMethodErrors.java.messages index 804e8a3c..26c30298 100644 --- a/test/transform/resource/messages-ecj/GetterOnMethodErrors.java.messages +++ b/test/transform/resource/messages-ecj/GetterOnMethodErrors.java.messages @@ -1 +1 @@ -3:50 'onMethod' is not supported for @Getter on a type. \ No newline at end of file +3 'onMethod' is not supported for @Getter on a type. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages index f87b9f13..af1e3b7a 100644 --- a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2:31 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -3:93 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -4:144 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -5:210 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +2 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +3 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +4 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) +5 The correct format is @Getter(onMethod=@_({@SomeAnnotation, @SomeOtherAnnotation})) diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages index 859e29d8..db5f9891 100644 --- a/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages +++ b/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages @@ -1 +1 @@ -1:0 Field 'log' already exists. +1 Field 'log' already exists. diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages index 570a169b..128a0c62 100644 --- a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages +++ b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages @@ -1 +1 @@ -2:9 @Log is not legal on non-static inner classes. \ No newline at end of file +2 @Log is not legal on non-static inner classes. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages index b6848135..81e9b718 100644 --- a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages +++ b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages @@ -1 +1 @@ -2:30 The annotation @Slf4j is disallowed for this location +2 The annotation @Slf4j is disallowed for this location diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages index b9f8b63f..949886d5 100644 --- a/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages +++ b/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages @@ -1,2 +1,2 @@ -1:0 @Slf4j is legal only on classes and enums. -4:67 @Slf4j is legal only on classes and enums. +1 @Slf4j is legal only on classes and enums. +4 @Slf4j is legal only on classes and enums. diff --git a/test/transform/resource/messages-ecj/NonNullOnParameter.java.messages b/test/transform/resource/messages-ecj/NonNullOnParameter.java.messages index 1539929b..4b7d18b3 100644 --- a/test/transform/resource/messages-ecj/NonNullOnParameter.java.messages +++ b/test/transform/resource/messages-ecj/NonNullOnParameter.java.messages @@ -1,3 +1,3 @@ -15:460 Dead code -22:683 @NonNull is meaningless on a primitive. -28:823 Dead code \ No newline at end of file +15 Dead code +22 @NonNull is meaningless on a primitive. +28 Dead code \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/NonNullPlain.java.messages b/test/transform/resource/messages-ecj/NonNullPlain.java.messages index 96eed252..1c33c701 100644 --- a/test/transform/resource/messages-ecj/NonNullPlain.java.messages +++ b/test/transform/resource/messages-ecj/NonNullPlain.java.messages @@ -1 +1 @@ -7:116 @NonNull is meaningless on a primitive. \ No newline at end of file +7 @NonNull is meaningless on a primitive. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/SetterAlreadyExists.java.messages b/test/transform/resource/messages-ecj/SetterAlreadyExists.java.messages index 5fc0a365..4b1e209b 100644 --- a/test/transform/resource/messages-ecj/SetterAlreadyExists.java.messages +++ b/test/transform/resource/messages-ecj/SetterAlreadyExists.java.messages @@ -1,7 +1,7 @@ -2:17 Not generating setFoo(): A method with that name already exists -8:96 Not generating setFoo(): A method with that name already exists -14:174 Not generating setFoo(): A method with that name already exists -20:252 Not generating setFoo(): A method with that name already exists -38:480 Not generating setFoo(): A method with that name already exists -44:570 Not generating setFoo(): A method with that name already exists (setIsFoo) -50:653 Not generating setFoo(): A method with that name already exists +2 Not generating setFoo(): A method with that name already exists +8 Not generating setFoo(): A method with that name already exists +14 Not generating setFoo(): A method with that name already exists +20 Not generating setFoo(): A method with that name already exists +38 Not generating setFoo(): A method with that name already exists +44 Not generating setFoo(): A method with that name already exists (setIsFoo) +50 Not generating setFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-ecj/SetterOnMethod.java.messages b/test/transform/resource/messages-ecj/SetterOnMethod.java.messages index ecfa3f69..8e7ff7f8 100644 --- a/test/transform/resource/messages-ecj/SetterOnMethod.java.messages +++ b/test/transform/resource/messages-ecj/SetterOnMethod.java.messages @@ -1,2 +1,2 @@ -6:0 'onMethod' is not supported for @Setter on a type. -11:0 'onMethod' is not supported for @Setter on a type. \ No newline at end of file +6 'onMethod' is not supported for @Setter on a type. +11 'onMethod' is not supported for @Setter on a type. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/SetterOnParam.java.messages b/test/transform/resource/messages-ecj/SetterOnParam.java.messages index 7d0c4a1e..dbab4caa 100644 --- a/test/transform/resource/messages-ecj/SetterOnParam.java.messages +++ b/test/transform/resource/messages-ecj/SetterOnParam.java.messages @@ -1,2 +1,2 @@ -6:0 'onParam' is not supported for @Setter on a type. -11:0 'onParam' is not supported for @Setter on a type. \ No newline at end of file +6 'onParam' is not supported for @Setter on a type. +11 'onParam' is not supported for @Setter on a type. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/SimpleTypeResolution.java.messages b/test/transform/resource/messages-ecj/SimpleTypeResolution.java.messages index eb33b0df..87edc6c2 100644 --- a/test/transform/resource/messages-ecj/SimpleTypeResolution.java.messages +++ b/test/transform/resource/messages-ecj/SimpleTypeResolution.java.messages @@ -1 +1 @@ -2:35 Getter cannot be resolved to a type +2 Getter cannot be resolved to a type diff --git a/test/transform/resource/messages-ecj/SynchronizedName.java.messages b/test/transform/resource/messages-ecj/SynchronizedName.java.messages index 0ad3be0a..5322f9d2 100644 --- a/test/transform/resource/messages-ecj/SynchronizedName.java.messages +++ b/test/transform/resource/messages-ecj/SynchronizedName.java.messages @@ -1 +1 @@ -8:185 The static field SynchronizedName.READ should be accessed in a static way +8 The static field SynchronizedName.READ should be accessed in a static way diff --git a/test/transform/resource/messages-ecj/SynchronizedNameNoSuchField.java.messages b/test/transform/resource/messages-ecj/SynchronizedNameNoSuchField.java.messages index b07f020c..ae351773 100644 --- a/test/transform/resource/messages-ecj/SynchronizedNameNoSuchField.java.messages +++ b/test/transform/resource/messages-ecj/SynchronizedNameNoSuchField.java.messages @@ -1 +1 @@ -5:120 The field write does not exist. +5 The field write does not exist. diff --git a/test/transform/resource/messages-ecj/SynchronizedNameStaticToInstanceRef.java.messages b/test/transform/resource/messages-ecj/SynchronizedNameStaticToInstanceRef.java.messages index 834877ef..98b9c948 100644 --- a/test/transform/resource/messages-ecj/SynchronizedNameStaticToInstanceRef.java.messages +++ b/test/transform/resource/messages-ecj/SynchronizedNameStaticToInstanceRef.java.messages @@ -1 +1 @@ -5:127 Cannot make a static reference to the non-static field SynchronizedNameStaticToInstanceRef.read +5 Cannot make a static reference to the non-static field SynchronizedNameStaticToInstanceRef.read diff --git a/test/transform/resource/messages-ecj/ValErrors.java.messages b/test/transform/resource/messages-ecj/ValErrors.java.messages index fda58094..6d53ddd6 100644 --- a/test/transform/resource/messages-ecj/ValErrors.java.messages +++ b/test/transform/resource/messages-ecj/ValErrors.java.messages @@ -1,2 +1,2 @@ -5:95 d cannot be resolved to a variable -9:143 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... }) +5 d cannot be resolved to a variable +9 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... }) diff --git a/test/transform/resource/messages-ecj/ValInBasicFor.java.messages b/test/transform/resource/messages-ecj/ValInBasicFor.java.messages index 068d72b9..43cd7ce8 100644 --- a/test/transform/resource/messages-ecj/ValInBasicFor.java.messages +++ b/test/transform/resource/messages-ecj/ValInBasicFor.java.messages @@ -1,4 +1,4 @@ -6:160 'val' is not allowed in old-style for loops -6:171 Type mismatch: cannot convert from int to val -6:174 'val' is not allowed in old-style for loops -6:187 'val' is not allowed in old-style for loops +6 'val' is not allowed in old-style for loops +6 Type mismatch: cannot convert from int to val +6 'val' is not allowed in old-style for loops +6 'val' is not allowed in old-style for loops diff --git a/test/transform/resource/messages-ecj/ValRawType.java.messages b/test/transform/resource/messages-ecj/ValRawType.java.messages index b7669ede..2a1fbba6 100644 --- a/test/transform/resource/messages-ecj/ValRawType.java.messages +++ b/test/transform/resource/messages-ecj/ValRawType.java.messages @@ -1 +1 @@ -13:260 List is a raw type. References to generic type List should be parameterized +13 List is a raw type. References to generic type List should be parameterized diff --git a/test/transform/resource/messages-ecj/ValueExperimental.java.messages b/test/transform/resource/messages-ecj/ValueExperimental.java.messages index db4520ca..e454a878 100644 --- a/test/transform/resource/messages-ecj/ValueExperimental.java.messages +++ b/test/transform/resource/messages-ecj/ValueExperimental.java.messages @@ -1 +1 @@ -1:7 The type Value is deprecated \ No newline at end of file +1 The type Value is deprecated \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/WitherAlreadyExists.java.messages b/test/transform/resource/messages-ecj/WitherAlreadyExists.java.messages index 87459eb2..d5e30e28 100644 --- a/test/transform/resource/messages-ecj/WitherAlreadyExists.java.messages +++ b/test/transform/resource/messages-ecj/WitherAlreadyExists.java.messages @@ -1,7 +1,7 @@ -2:17 Not generating withFoo(): A method with that name already exists -12:141 Not generating withFoo(): A method with that name already exists -22:264 Not generating withFoo(): A method with that name already exists -32:386 Not generating withFoo(): A method with that name already exists -62:746 Not generating withFoo(): A method with that name already exists -72:880 Not generating withFoo(): A method with that name already exists (withIsFoo) -82:1008 Not generating withFoo(): A method with that name already exists +2 Not generating withFoo(): A method with that name already exists +12 Not generating withFoo(): A method with that name already exists +22 Not generating withFoo(): A method with that name already exists +32 Not generating withFoo(): A method with that name already exists +62 Not generating withFoo(): A method with that name already exists +72 Not generating withFoo(): A method with that name already exists (withIsFoo) +82 Not generating withFoo(): A method with that name already exists diff --git a/test/transform/resource/messages-ecj/WitherOnStatic.java.messages b/test/transform/resource/messages-ecj/WitherOnStatic.java.messages index 72e39f62..3af59fa1 100644 --- a/test/transform/resource/messages-ecj/WitherOnStatic.java.messages +++ b/test/transform/resource/messages-ecj/WitherOnStatic.java.messages @@ -1,2 +1,2 @@ -2:24 Not generating wither for this field: Withers cannot be generated for static fields. -3:73 Not generating wither for this field: Withers cannot be generated for static fields. +2 Not generating wither for this field: Withers cannot be generated for static fields. +3 Not generating wither for this field: Withers cannot be generated for static fields. diff --git a/test/transform/resource/messages-ecj/WitherWithDollar.java.messages b/test/transform/resource/messages-ecj/WitherWithDollar.java.messages index 93203dbb..84603868 100644 --- a/test/transform/resource/messages-ecj/WitherWithDollar.java.messages +++ b/test/transform/resource/messages-ecj/WitherWithDollar.java.messages @@ -1 +1 @@ -2:26 Not generating wither for this field: Withers cannot be generated for fields starting with $. +2 Not generating wither for this field: Withers cannot be generated for fields starting with $. diff --git a/test/transform/resource/messages-idempotent/NonNullOnParameter.java.messages b/test/transform/resource/messages-idempotent/NonNullOnParameter.java.messages index fd23a32a..57556bf3 100644 --- a/test/transform/resource/messages-idempotent/NonNullOnParameter.java.messages +++ b/test/transform/resource/messages-idempotent/NonNullOnParameter.java.messages @@ -1 +1 @@ -33:89 @NonNull is meaningless on a primitive. \ No newline at end of file +33 @NonNull is meaningless on a primitive. \ No newline at end of file diff --git a/test/transform/resource/messages-idempotent/NonNullPlain.java.messages b/test/transform/resource/messages-idempotent/NonNullPlain.java.messages index c48da311..1d8c4d9c 100644 --- a/test/transform/resource/messages-idempotent/NonNullPlain.java.messages +++ b/test/transform/resource/messages-idempotent/NonNullPlain.java.messages @@ -1,3 +1,3 @@ -4:9 @NonNull is meaningless on a primitive. -18:29 @NonNull is meaningless on a primitive. -44:26 @NonNull is meaningless on a primitive. \ No newline at end of file +3 @NonNull is meaningless on a primitive. +15 @NonNull is meaningless on a primitive. +37 @NonNull is meaningless on a primitive. \ No newline at end of file diff --git a/test/transform/resource/messages-idempotent/SimpleTypeResolution.java.messages b/test/transform/resource/messages-idempotent/SimpleTypeResolution.java.messages index 7acd35ed..ec74f090 100644 --- a/test/transform/resource/messages-idempotent/SimpleTypeResolution.java.messages +++ b/test/transform/resource/messages-idempotent/SimpleTypeResolution.java.messages @@ -1 +1 @@ -2:10 cannot find symbol +2 cannot find symbol diff --git a/test/transform/resource/messages-idempotent/SynchronizedNameStaticToInstanceRef.java.messages b/test/transform/resource/messages-idempotent/SynchronizedNameStaticToInstanceRef.java.messages index ed3eccb1..53b39d98 100644 --- a/test/transform/resource/messages-idempotent/SynchronizedNameStaticToInstanceRef.java.messages +++ b/test/transform/resource/messages-idempotent/SynchronizedNameStaticToInstanceRef.java.messages @@ -1 +1 @@ -5:66 non-static variable read cannot be referenced from a static context +5 non-static variable read cannot be referenced from a static context diff --git a/test/transform/resource/messages-idempotent/ValErrors.java.messages b/test/transform/resource/messages-idempotent/ValErrors.java.messages index 9bee37d4..c2432c6a 100644 --- a/test/transform/resource/messages-idempotent/ValErrors.java.messages +++ b/test/transform/resource/messages-idempotent/ValErrors.java.messages @@ -1,3 +1,3 @@ -3:44 cannot find symbol -6:17 cannot find symbol -6:25 illegal initializer for +3 cannot find symbol +6 cannot find symbol +6 illegal initializer for diff --git a/test/transform/resource/messages-idempotent/ValInBasicFor.java.messages b/test/transform/resource/messages-idempotent/ValInBasicFor.java.messages index fb675485..67842eb9 100644 --- a/test/transform/resource/messages-idempotent/ValInBasicFor.java.messages +++ b/test/transform/resource/messages-idempotent/ValInBasicFor.java.messages @@ -1 +1 @@ -5:53 'val' is not allowed in old-style for loops +5 'val' is not allowed in old-style for loops -- cgit From 1c319579cbbd2153b6fd33a792bcb03e6a02ab74 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 19 Aug 2013 23:54:34 +0200 Subject: Fix suppressing diagnostic messages during resolution in #java8 #val --- src/core/lombok/javac/JavacResolution.java | 104 +++++++++++++++++++---------- 1 file changed, 67 insertions(+), 37 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 7d4bdabd..acd4b3bd 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -22,6 +22,7 @@ package lombok.javac; import static lombok.javac.Javac.*; +import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import java.io.IOException; import java.io.OutputStream; @@ -31,12 +32,12 @@ import java.util.ArrayDeque; import java.util.LinkedList; import java.util.Map; import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.lang.model.type.TypeKind; import javax.tools.DiagnosticListener; -import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; - import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symtab; @@ -79,7 +80,9 @@ public class JavacResolution { private static final class LogDisabler { private final Log log; private static final Field errWriterField, warnWriterField, noticeWriterField, dumpOnErrorField, promptOnErrorField, diagnosticListenerField; - private static final Field deferDiagnosticsField, deferredDiagnosticsField; + private static final Field deferDiagnosticsField, deferredDiagnosticsField, diagnosticHandlerField; + private static final ConcurrentMap, Field> handlerDeferredFields = new ConcurrentHashMap, Field>(); + private static final Field NULL_FIELD; private PrintWriter errWriter, warnWriter, noticeWriter; private Boolean dumpOnError, promptOnError; private DiagnosticListener contextDiagnosticListener, logDiagnosticListener; @@ -91,43 +94,40 @@ public class JavacResolution { private static final ThreadLocal> queueCache = new ThreadLocal>(); static { - boolean z; - Field a = null, b = null, c = null, d = null, e = null, f = null, g = null, h = null; - try { - a = Log.class.getDeclaredField("errWriter"); - b = Log.class.getDeclaredField("warnWriter"); - c = Log.class.getDeclaredField("noticeWriter"); - d = Log.class.getDeclaredField("dumpOnError"); - e = Log.class.getDeclaredField("promptOnError"); - f = Log.class.getDeclaredField("diagListener"); - z = false; - a.setAccessible(true); - b.setAccessible(true); - c.setAccessible(true); - d.setAccessible(true); - e.setAccessible(true); - f.setAccessible(true); - } catch (Throwable x) { - z = true; - } + errWriterField = getDeclaredField(Log.class, "errWriter"); + warnWriterField = getDeclaredField(Log.class, "warnWriter"); + noticeWriterField = getDeclaredField(Log.class, "noticeWriter"); + dumpOnErrorField = getDeclaredField(Log.class, "dumpOnError"); + promptOnErrorField = getDeclaredField(Log.class, "promptOnError"); + diagnosticListenerField = getDeclaredField(Log.class, "diagListener"); + + dontBother = + errWriterField == null || + warnWriterField == null || + noticeWriterField == null || + dumpOnErrorField == null || + promptOnErrorField == null || + diagnosticListenerField == null; + + deferDiagnosticsField = getDeclaredField(Log.class, "deferDiagnostics"); + deferredDiagnosticsField = getDeclaredField(Log.class, "deferredDiagnostics"); + + // javac8 + diagnosticHandlerField = getDeclaredField(Log.class, "diagnosticHandler"); + + NULL_FIELD = getDeclaredField(JavacResolution.class, "NULL_FIELD"); + } + + static Field getDeclaredField(Class c, String fieldName) { try { - g = Log.class.getDeclaredField("deferDiagnostics"); - h = Log.class.getDeclaredField("deferredDiagnostics"); - g.setAccessible(true); - h.setAccessible(true); - } catch (Throwable x) { + Field field = c.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + catch (Throwable t) { + return null; } - - errWriterField = a; - warnWriterField = b; - noticeWriterField = c; - dumpOnErrorField = d; - promptOnErrorField = e; - diagnosticListenerField = f; - deferDiagnosticsField = g; - deferredDiagnosticsField = h; - dontBother = z; } LogDisabler(Context context) { @@ -155,6 +155,16 @@ public class JavacResolution { } } catch (Exception e) {} + if (diagnosticHandlerField != null) try { + Object handler = diagnosticHandlerField.get(log); + Field field = getDeferredField(handler); + if (field != null) { + queueCache.set((Queue) field.get(handler)); + Queue empty = new LinkedList(); + field.set(handler, empty); + } + } catch (Exception e) {} + if (!dontBotherInstance) try { errWriter = (PrintWriter) errWriterField.get(log); errWriterField.set(log, dummyWriter); @@ -201,6 +211,17 @@ public class JavacResolution { return !dontBotherInstance; } + private static Field getDeferredField(Object handler) { + Class key = handler.getClass(); + Field field = handlerDeferredFields.get(key); + if (field != null) { + return field == NULL_FIELD ? null : field; + } + Field value = getDeclaredField(key, "deferred"); + handlerDeferredFields.put(key, value == null ? NULL_FIELD : value); + return getDeferredField(handler); + } + void enableLoggers() { if (contextDiagnosticListener != null) { context.put(DiagnosticListener.class, contextDiagnosticListener); @@ -237,6 +258,15 @@ public class JavacResolution { logDiagnosticListener = null; } catch (Exception e) {} + if (diagnosticHandlerField != null && queueCache.get() != null) try { + Object handler = diagnosticHandlerField.get(log); + Field field = getDeferredField(handler); + if (field != null) { + field.set(handler, queueCache.get()); + queueCache.set(null); + } + } catch (Exception e) {} + if (deferDiagnosticsField != null && queueCache.get() != null) try { deferredDiagnosticsField.set(log, queueCache.get()); queueCache.set(null); -- cgit From 0932ccb51b83ac6b98450f3b96f4b1b764a81651 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 9 Sep 2013 20:16:16 +0200 Subject: added a todo comment only --- src/core/lombok/javac/JavacAST.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index e49d8ac8..d565b0ef 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -405,6 +405,8 @@ public class JavacAST extends AST { ((CapturingDiagnosticListener) listener).suppress(startPos, endPos); } try { + // TODO: This changed a bit in java8; there is now also a Handler thingie; see JavacResolution for what changed. + // Possibly integrate these 2 code paths. if (JAVAC7_DEFERRED_DIAGNOSTICS != null) { ListBuffer deferredDiagnostics = (ListBuffer) JAVAC7_DEFERRED_DIAGNOSTICS.get(log); ListBuffer newDeferredDiagnostics = ListBuffer.lb(); -- cgit From 0ac3aedbca28844a1220a77c0403e56106011947 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 10 Sep 2013 00:09:55 +0200 Subject: version naming and changelog update for edge release --- doc/changelog.markdown | 3 +++ src/core/lombok/core/Version.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 0e15e7e2..7782f1fa 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,6 +1,9 @@ Lombok Changelog ---------------- +### v0.12.1 "Edgy Guinea Pig" +* PLATFORM: Initial (not quite totally finished) JDK8 support, without affecting existing support for JDK6 and 7. [Issue #451](https://code.google.com/p/projectlombok/issues/detail?id=451). + ### v0.12.0 "Angry Butterfly" (July 16th, 2013) * FEATURE: javadoc on fields will now be copied to generated getters / setters / withers. There are ways to specify separate javadoc for the field, the setter, and the getter, and `@param` and `@return` are handled appropriately. Addresses feature request [Issue #59](https://code.google.com/p/projectlombok/issues/detail?id=59). [@Getter and @Setter documentation](http://projectlombok.org/features/GetterSetter.html). [@Wither documentation](http://projectlombok.org/features/experimental/Wither.html). * CHANGE: The desugaring of @Getter(lazy=true) is now less object creation intensive. Documentation has been updated to reflect what the new desugaring looks like. [@Getter(lazy=true) documentation](http://projectlombok.org/features/GetterLazy.html). diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index bd83c1f8..25c1b469 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -29,7 +29,8 @@ public class Version { // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). private static final String VERSION = "0.12.1"; - private static final String RELEASE_NAME = "Angry Butterfy"; + private static final String RELEASE_NAME = "Edgy Guinea Pig"; +// private static final String RELEASE_NAME = "Angry Butterfly"; private Version() { //Prevent instantiation -- cgit From 72b55dccb18f38b8aefd0ac8e7c2e8bd2dd5c057 Mon Sep 17 00:00:00 2001 From: Sander Koning Date: Fri, 20 Sep 2013 17:13:39 +0200 Subject: Issue 559: NullPointerException when @NonNull is used in abstract method - Prevent NPE in javac and give a proper warning in both eclipse and javac - Add test cases --- src/core/lombok/eclipse/handlers/NonNullHandler.java | 5 +++++ src/core/lombok/javac/handlers/NonNullHandler.java | 5 +++++ .../resource/after-delombok/NonNullOnParameterAbstract.java | 10 ++++++++++ .../resource/after-ecj/NonNullOnParameterAbstract.java | 13 +++++++++++++ .../resource/before/NonNullOnParameterAbstract.java | 7 +++++++ .../NonNullOnParameterAbstract.java.messages | 1 + .../messages-ecj/NonNullOnParameterAbstract.java.messages | 1 + .../NonNullOnParameterAbstract.java.messages | 1 + 8 files changed, 43 insertions(+) create mode 100644 test/transform/resource/after-delombok/NonNullOnParameterAbstract.java create mode 100644 test/transform/resource/after-ecj/NonNullOnParameterAbstract.java create mode 100644 test/transform/resource/before/NonNullOnParameterAbstract.java create mode 100644 test/transform/resource/messages-delombok/NonNullOnParameterAbstract.java.messages create mode 100644 test/transform/resource/messages-ecj/NonNullOnParameterAbstract.java.messages create mode 100644 test/transform/resource/messages-idempotent/NonNullOnParameterAbstract.java.messages (limited to 'src/core') diff --git a/src/core/lombok/eclipse/handlers/NonNullHandler.java b/src/core/lombok/eclipse/handlers/NonNullHandler.java index 5c58069c..59fda801 100644 --- a/src/core/lombok/eclipse/handlers/NonNullHandler.java +++ b/src/core/lombok/eclipse/handlers/NonNullHandler.java @@ -82,6 +82,11 @@ public class NonNullHandler extends EclipseAnnotationHandler { if (isGenerated(declaration)) return; + if (declaration.isAbstract()) { + 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and // wrap all references to it in the super/this to a call to this method. diff --git a/src/core/lombok/javac/handlers/NonNullHandler.java b/src/core/lombok/javac/handlers/NonNullHandler.java index 415d6032..392e8390 100644 --- a/src/core/lombok/javac/handlers/NonNullHandler.java +++ b/src/core/lombok/javac/handlers/NonNullHandler.java @@ -76,6 +76,11 @@ public class NonNullHandler extends JavacAnnotationHandler { 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and // wrap all references to it in the super/this to a call to this method. diff --git a/test/transform/resource/after-delombok/NonNullOnParameterAbstract.java b/test/transform/resource/after-delombok/NonNullOnParameterAbstract.java new file mode 100644 index 00000000..e0330bd6 --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullOnParameterAbstract.java @@ -0,0 +1,10 @@ +abstract class NonNullOnParameterAbstract { + public void test(@lombok.NonNull String arg) { + if (arg == null) { + throw new java.lang.NullPointerException("arg"); + } + System.out.println("Hey"); + } + + public abstract void test2(@lombok.NonNull String arg); +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/NonNullOnParameterAbstract.java b/test/transform/resource/after-ecj/NonNullOnParameterAbstract.java new file mode 100644 index 00000000..a7dae247 --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullOnParameterAbstract.java @@ -0,0 +1,13 @@ +abstract class NonNullOnParameterAbstract { + NonNullOnParameterAbstract() { + super(); + } + public void test(@lombok.NonNull String arg) { + if ((arg == null)) + { + throw new java.lang.NullPointerException("arg"); + } + System.out.println("Hey"); + } + public abstract void test2(@lombok.NonNull String arg); +} \ No newline at end of file diff --git a/test/transform/resource/before/NonNullOnParameterAbstract.java b/test/transform/resource/before/NonNullOnParameterAbstract.java new file mode 100644 index 00000000..16691184 --- /dev/null +++ b/test/transform/resource/before/NonNullOnParameterAbstract.java @@ -0,0 +1,7 @@ +abstract class NonNullOnParameterAbstract { + public void test(@lombok.NonNull String arg) { + System.out.println("Hey"); + } + + public abstract void test2(@lombok.NonNull String arg); +} \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/NonNullOnParameterAbstract.java.messages b/test/transform/resource/messages-delombok/NonNullOnParameterAbstract.java.messages new file mode 100644 index 00000000..1ebeea05 --- /dev/null +++ b/test/transform/resource/messages-delombok/NonNullOnParameterAbstract.java.messages @@ -0,0 +1 @@ +6:36 @NonNull is meaningless on a parameter of an abstract method. diff --git a/test/transform/resource/messages-ecj/NonNullOnParameterAbstract.java.messages b/test/transform/resource/messages-ecj/NonNullOnParameterAbstract.java.messages new file mode 100644 index 00000000..48d1508e --- /dev/null +++ b/test/transform/resource/messages-ecj/NonNullOnParameterAbstract.java.messages @@ -0,0 +1 @@ +6:154 @NonNull is meaningless on a parameter of an abstract method. \ No newline at end of file diff --git a/test/transform/resource/messages-idempotent/NonNullOnParameterAbstract.java.messages b/test/transform/resource/messages-idempotent/NonNullOnParameterAbstract.java.messages new file mode 100644 index 00000000..00547171 --- /dev/null +++ b/test/transform/resource/messages-idempotent/NonNullOnParameterAbstract.java.messages @@ -0,0 +1 @@ +9:36 @NonNull is meaningless on a parameter of an abstract method. \ No newline at end of file -- cgit From 7ee868659f4ff3cb286b676d649e8c57e9248d87 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 24 Sep 2013 01:11:13 +0200 Subject: Fixed netbeans 7.4RC1 issue (JavaCompiler.version() was returning bogus values, so we now work around that javac bug). --- src/core/lombok/core/debug/DebugSnapshotStore.java | 2 +- src/delombok/lombok/delombok/DelombokApp.java | 2 +- src/utils/lombok/core/debug/FileLog.java | 61 ++++++++++++++++++++++ src/utils/lombok/javac/Javac.java | 32 +++++++++--- 4 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 src/utils/lombok/core/debug/FileLog.java (limited to 'src/core') diff --git a/src/core/lombok/core/debug/DebugSnapshotStore.java b/src/core/lombok/core/debug/DebugSnapshotStore.java index 64c91473..11192bd3 100644 --- a/src/core/lombok/core/debug/DebugSnapshotStore.java +++ b/src/core/lombok/core/debug/DebugSnapshotStore.java @@ -82,7 +82,7 @@ public class DebugSnapshotStore { } try { - File logFile = new File(System.getProperty("user.home", "."), String.format("lombok164-%d.err", System.currentTimeMillis())); + File logFile = new File(System.getProperty("user.home", "."), String.format("lombokdss-%d.err", System.currentTimeMillis())); OutputStream stream = new FileOutputStream(logFile); try { stream.write(out.toString().getBytes("UTF-8")); diff --git a/src/delombok/lombok/delombok/DelombokApp.java b/src/delombok/lombok/delombok/DelombokApp.java index 52c6b1d4..a1ce3b3f 100644 --- a/src/delombok/lombok/delombok/DelombokApp.java +++ b/src/delombok/lombok/delombok/DelombokApp.java @@ -84,7 +84,7 @@ public class DelombokApp extends LombokApp { return null; } - @SuppressWarnings("resource") final JarFile toolsJarFile = new JarFile(toolsJar); + @SuppressWarnings({"resource", "all"}) final JarFile toolsJarFile = new JarFile(toolsJar); ClassLoader loader = new ClassLoader() { private Class loadStreamAsClass(String name, boolean resolve, InputStream in) throws ClassNotFoundException { diff --git a/src/utils/lombok/core/debug/FileLog.java b/src/utils/lombok/core/debug/FileLog.java new file mode 100644 index 00000000..dedec40e --- /dev/null +++ b/src/utils/lombok/core/debug/FileLog.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.core.debug; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class FileLog { + private static FileOutputStream fos; + + public static void log(String message) { + log(message, null); + } + public synchronized static void log(String message, Throwable t) { + try { + if (fos == null) { + fos = new FileOutputStream(new File(System.getProperty("user.home"), "LOMBOK-DEBUG-OUT.txt")); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + try { + fos.close(); + } catch (Throwable ignore) {} + } + }); + } + fos.write(message.getBytes("UTF-8")); + fos.write('\n'); + if (t != null) { + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + fos.write(sw.toString().getBytes("UTF-8")); + fos.write('\n'); + } + fos.flush(); + } catch (IOException e) { + throw new IllegalStateException("Internal lombok file-based debugging not possible", e); + } + } +} diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 2f3c9be4..554c778d 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -39,6 +39,7 @@ import javax.lang.model.type.TypeVisitor; import lombok.javac.JavacTreeMaker.TreeTag; import lombok.javac.JavacTreeMaker.TypeTag; +import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; @@ -62,6 +63,7 @@ public class Javac { private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile("^(boolean|byte|short|int|long|float|double|char)$"); private static final Pattern VERSION_PARSER = Pattern.compile("^(\\d{1,6})\\.(\\d{1,6}).*$"); + private static final Pattern SOURCE_PARSER = Pattern.compile("^JDK(\\d{1,6})_(\\d{1,6}).*$"); private static final AtomicInteger compilerVersion = new AtomicInteger(-1); @@ -71,13 +73,29 @@ public class Javac { public static int getJavaCompilerVersion() { int cv = compilerVersion.get(); if (cv != -1) return cv; - Matcher m = VERSION_PARSER.matcher(JavaCompiler.version()); - if (m.matches()) { - int major = Integer.parseInt(m.group(1)); - int minor = Integer.parseInt(m.group(2)); - if (major == 1) { - compilerVersion.set(minor); - return minor; + + /* Main algorithm: Use JavaCompiler's intended method to do this */ { + Matcher m = VERSION_PARSER.matcher(JavaCompiler.version()); + if (m.matches()) { + int major = Integer.parseInt(m.group(1)); + int minor = Integer.parseInt(m.group(2)); + if (major == 1) { + compilerVersion.set(minor); + return minor; + } + } + } + + /* Fallback algorithm one: Check Source's values. Lets hope oracle never releases a javac that recognizes future versions for -source */ { + String name = Source.values()[Source.values().length - 1].name(); + Matcher m = SOURCE_PARSER.matcher(name); + if (m.matches()) { + int major = Integer.parseInt(m.group(1)); + int minor = Integer.parseInt(m.group(2)); + if (major == 1) { + compilerVersion.set(minor); + return minor; + } } } -- cgit From f0cdc27a3f86c0ca728ad598893dd2b95ba38e20 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 24 Sep 2013 01:55:31 +0200 Subject: tiny tiny fix for some incredibly unlikely mix of intellij, ibm stuff, and who knows what. At any rate, Roel is absolutely sure this will fix it, so, hey, who am I to argue? NB: Unicum --- src/core/lombok/javac/apt/Processor.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java index 110acaad..5f28aa88 100644 --- a/src/core/lombok/javac/apt/Processor.java +++ b/src/core/lombok/javac/apt/Processor.java @@ -210,6 +210,7 @@ public class Processor extends AbstractProcessor { Field f = JavacProcessingEnvironment.class.getDeclaredField("processorClassLoader"); f.setAccessible(true); ClassLoader unwrapped = (ClassLoader) f.get(processingEnv); + if (unwrapped == null) return; ClassLoader wrapped = new WrappingClassLoader(unwrapped); f.set(processingEnv, wrapped); } catch (NoSuchFieldException e) { -- cgit From 7fc6e70b36c978ef230e3df41db151f3c0da3da1 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Wed, 25 Sep 2013 21:38:37 +0200 Subject: Pre-emptive fix for the anticipated removal of ListBuffer.lb() in javac8 --- src/core/lombok/javac/JavacAST.java | 2 +- src/core/lombok/javac/JavacResolution.java | 2 +- src/core/lombok/javac/handlers/HandleBuilder.java | 8 ++++---- src/core/lombok/javac/handlers/HandleCleanup.java | 4 ++-- .../lombok/javac/handlers/HandleConstructor.java | 22 ++++++++++---------- .../javac/handlers/HandleEqualsAndHashCode.java | 10 ++++----- src/core/lombok/javac/handlers/HandleGetter.java | 8 ++++---- src/core/lombok/javac/handlers/HandleSetter.java | 2 +- src/core/lombok/javac/handlers/HandleToString.java | 2 +- src/core/lombok/javac/handlers/HandleWither.java | 4 ++-- .../lombok/javac/handlers/JavacHandlerUtil.java | 24 +++++++++++----------- .../javac/java6/CommentCollectingScanner.java | 3 ++- .../javac/java7/CommentCollectingScanner.java | 3 ++- .../javac/java8/CommentCollectingTokenizer.java | 3 ++- 14 files changed, 50 insertions(+), 47 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index d565b0ef..2422b553 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -409,7 +409,7 @@ public class JavacAST extends AST { // Possibly integrate these 2 code paths. if (JAVAC7_DEFERRED_DIAGNOSTICS != null) { ListBuffer deferredDiagnostics = (ListBuffer) JAVAC7_DEFERRED_DIAGNOSTICS.get(log); - ListBuffer newDeferredDiagnostics = ListBuffer.lb(); + ListBuffer newDeferredDiagnostics = new ListBuffer(); for (Object diag : deferredDiagnostics) { if (!(diag instanceof JCDiagnostic)) { newDeferredDiagnostics.add(diag); diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index acd4b3bd..acfca6a6 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -534,7 +534,7 @@ public class JavacResolution { private static JCExpression genericsToJCTreeNodes(List generics, JavacAST ast, JCExpression rawTypeNode) throws TypeNotConvertibleException { if (generics != null && !generics.isEmpty()) { - ListBuffer args = ListBuffer.lb(); + ListBuffer args = new ListBuffer(); for (Type t : generics) args.append(typeToJCTree(t, ast, true, false)); return ast.getTreeMaker().TypeApply(rawTypeNode, args.toList()); } diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index d7ea2806..8a826087 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -98,7 +98,7 @@ public class HandleBuilder extends JavacAnnotationHandler { if (parent.get() instanceof JCClassDecl) { tdParent = parent; JCClassDecl td = (JCClassDecl) tdParent.get(); - ListBuffer allFields = ListBuffer.lb(); + ListBuffer allFields = new ListBuffer(); @SuppressWarnings("deprecation") boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation(lombok.experimental.Value.class, parent)); for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent)) { @@ -224,7 +224,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCExpression call; JCStatement statement; - ListBuffer args = ListBuffer.lb(); + ListBuffer args = new ListBuffer(); for (Name n : fieldNames) { args.append(maker.Ident(n)); } @@ -233,7 +233,7 @@ public class HandleBuilder extends JavacAnnotationHandler { call = maker.NewClass(null, List.nil(), returnType, args.toList(), null); statement = maker.Return(call); } else { - ListBuffer typeParams = ListBuffer.lb(); + ListBuffer typeParams = new ListBuffer(); for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) { typeParams.append(maker.Ident(tp.name)); } @@ -255,7 +255,7 @@ public class HandleBuilder extends JavacAnnotationHandler { private JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, JavacNode type, List typeParams) { JavacTreeMaker maker = type.getTreeMaker(); - ListBuffer typeArgs = ListBuffer.lb(); + ListBuffer typeArgs = new ListBuffer(); for (JCTypeParameter typeParam : typeParams) { typeArgs.append(maker.Ident(typeParam.name)); } diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 417d2815..e7786ffe 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -96,8 +96,8 @@ public class HandleCleanup extends JavacAnnotationHandler { } boolean seenDeclaration = false; - ListBuffer newStatements = ListBuffer.lb(); - ListBuffer tryBlock = ListBuffer.lb(); + ListBuffer newStatements = new ListBuffer(); + ListBuffer tryBlock = new ListBuffer(); for (JCStatement statement : statements) { if (!seenDeclaration) { if (statement == decl) seenDeclaration = true; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 5156d709..b77a5367 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -91,7 +91,7 @@ public class HandleConstructor { } private static List findRequiredFields(JavacNode typeNode) { - ListBuffer fields = ListBuffer.lb(); + ListBuffer fields = new ListBuffer(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); @@ -126,7 +126,7 @@ public class HandleConstructor { } static List findAllFields(JavacNode typeNode) { - ListBuffer fields = ListBuffer.lb(); + ListBuffer fields = new ListBuffer(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); @@ -209,7 +209,7 @@ public class HandleConstructor { if (fields.isEmpty()) return; JavacTreeMaker maker = node.getTreeMaker(); JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties"); - ListBuffer fieldNames = ListBuffer.lb(); + ListBuffer fieldNames = new ListBuffer(); for (JavacNode field : fields) { Name fieldName = removePrefixFromField(field); fieldNames.append(maker.Literal(fieldName.toString())); @@ -225,9 +225,9 @@ public class HandleConstructor { boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0; if (isEnum) level = AccessLevel.PRIVATE; - ListBuffer nullChecks = ListBuffer.lb(); - ListBuffer assigns = ListBuffer.lb(); - ListBuffer params = ListBuffer.lb(); + ListBuffer nullChecks = new ListBuffer(); + ListBuffer assigns = new ListBuffer(); + ListBuffer params = new ListBuffer(); for (JavacNode fieldNode : fields) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); @@ -272,11 +272,11 @@ public class HandleConstructor { JCExpression returnType, constructorType; - ListBuffer typeParams = ListBuffer.lb(); - ListBuffer params = ListBuffer.lb(); - ListBuffer typeArgs1 = ListBuffer.lb(); - ListBuffer typeArgs2 = ListBuffer.lb(); - ListBuffer args = ListBuffer.lb(); + ListBuffer typeParams = new ListBuffer(); + ListBuffer params = new ListBuffer(); + ListBuffer typeArgs1 = new ListBuffer(); + ListBuffer typeArgs2 = new ListBuffer(); + ListBuffer args = new ListBuffer(); if (!type.typarams.isEmpty()) { for (JCTypeParameter param : type.typarams) { diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index ad3b571a..0f8161e1 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -154,7 +154,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler nodesForEquality = ListBuffer.lb(); + ListBuffer nodesForEquality = new ListBuffer(); if (includes != null) { for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -224,7 +224,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); JCExpression returnType = maker.TypeIdent(CTC_INT); - ListBuffer statements = ListBuffer.lb(); + ListBuffer statements = new ListBuffer(); Name primeName = typeNode.toName(PRIME_NAME); Name resultName = typeNode.toName(RESULT_NAME); @@ -370,7 +370,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler statements = ListBuffer.lb(); + ListBuffer statements = new ListBuffer(); final List params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), oName, objectType, null)); /* if (o == this) return true; */ { @@ -387,8 +387,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler other = (MyType) o; */ { if (!fields.isEmpty() || needsCanEqual) { final JCExpression selfType1, selfType2; - ListBuffer wildcards1 = ListBuffer.lb(); - ListBuffer wildcards2 = ListBuffer.lb(); + ListBuffer wildcards1 = new ListBuffer(); + ListBuffer wildcards2 = new ListBuffer(); 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)); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index f6c14add..4ef23170 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -270,7 +270,7 @@ public class HandleGetter extends JavacAnnotationHandler { } if (!delegates.isEmpty()) { - ListBuffer withoutDelegates = ListBuffer.lb(); + ListBuffer withoutDelegates = new ListBuffer(); for (JCAnnotation annotation : fieldNode.mods.annotations) { if (!delegates.contains(annotation)) { withoutDelegates.append(annotation); @@ -328,7 +328,7 @@ public class HandleGetter extends JavacAnnotationHandler { [END IF] */ - ListBuffer statements = ListBuffer.lb(); + ListBuffer statements = new ListBuffer(); JCVariableDecl field = (JCVariableDecl) fieldNode.get(); JCExpression copyOfRawFieldType = copyType(maker, field); @@ -356,14 +356,14 @@ public class HandleGetter extends JavacAnnotationHandler { /* if (value == null) { */ { JCSynchronized synchronizedStatement; /* synchronized (this.fieldName) { */ { - ListBuffer synchronizedStatements = ListBuffer.lb(); + ListBuffer synchronizedStatements = new ListBuffer(); /* 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 innerIfStatements = ListBuffer.lb(); + ListBuffer innerIfStatements = new ListBuffer(); /* final RawValueType actualValue = INITIALIZER_EXPRESSION; */ { innerIfStatements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), actualValueName, copyOfRawFieldType, field.init)); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 6f345418..c4977b2b 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -204,7 +204,7 @@ public class HandleSetter extends JavacAnnotationHandler { JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD); JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name)); - ListBuffer statements = ListBuffer.lb(); + ListBuffer statements = new ListBuffer(); List nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); List nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index ea526009..9bd5b920 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -129,7 +129,7 @@ public class HandleToString extends JavacAnnotationHandler { return; } - ListBuffer nodesForToString = ListBuffer.lb(); + ListBuffer nodesForToString = new ListBuffer(); if (includes != null) { for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 4bda5464..9cfa4531 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -207,7 +207,7 @@ public class HandleWither extends JavacAnnotationHandler { JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); - ListBuffer statements = ListBuffer.lb(); + ListBuffer statements = new ListBuffer(); List nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); List nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); @@ -219,7 +219,7 @@ public class HandleWither extends JavacAnnotationHandler { JCExpression selfType = cloneSelfType(field); if (selfType == null) return null; - ListBuffer args = ListBuffer.lb(); + ListBuffer args = new ListBuffer(); for (JavacNode child : field.up().down()) { if (child.getKind() != Kind.FIELD) continue; JCVariableDecl childDecl = (JCVariableDecl) child.get(); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index f25a11c1..f90bb60d 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -338,7 +338,7 @@ public class JavacHandlerUtil { public static void deleteImportFromCompilationUnit(JavacNode node, String name) { if (inNetbeansEditor(node)) return; if (!node.shouldDeleteLombokAnnotations()) return; - ListBuffer newDefs = ListBuffer.lb(); + ListBuffer newDefs = new ListBuffer(); JCCompilationUnit unit = (JCCompilationUnit) node.top().get(); @@ -354,7 +354,7 @@ public class JavacHandlerUtil { } private static List filterList(List annotations, JCTree jcTree) { - ListBuffer newAnnotations = ListBuffer.lb(); + ListBuffer newAnnotations = new ListBuffer(); for (JCAnnotation ann : annotations) { if (jcTree != ann) newAnnotations.append(ann); } @@ -437,7 +437,7 @@ public class JavacHandlerUtil { while (typeNode != null && typeNode.getKind() != Kind.TYPE) typeNode = typeNode.up(); if (typeNode != null && typeNode.get() instanceof JCClassDecl) { JCClassDecl type = (JCClassDecl) typeNode.get(); - ListBuffer typeArgs = ListBuffer.lb(); + ListBuffer typeArgs = new ListBuffer(); if (!type.typarams.isEmpty()) { for (JCTypeParameter tp : type.typarams) { typeArgs.append(maker.Ident(tp.name)); @@ -885,7 +885,7 @@ public class JavacHandlerUtil { } private static List addAllButOne(List defs, int idx) { - ListBuffer out = ListBuffer.lb(); + ListBuffer out = new ListBuffer(); int i = 0; for (JCTree def : defs) { if (i++ != idx) out.append(def); @@ -956,7 +956,7 @@ public class JavacHandlerUtil { * Only the simple name is checked - the package and any containing class are ignored. */ public static List findAnnotations(JavacNode fieldNode, Pattern namePattern) { - ListBuffer result = ListBuffer.lb(); + ListBuffer result = new ListBuffer(); for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); @@ -1006,7 +1006,7 @@ public class JavacHandlerUtil { if (idx > -1) matched[idx] = true; } - ListBuffer problematic = ListBuffer.lb(); + ListBuffer problematic = new ListBuffer(); for (int i = 0 ; i < list.size() ; i++) { if (!matched[i]) problematic.append(i); } @@ -1015,8 +1015,8 @@ public class JavacHandlerUtil { } static List unboxAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName, String errorName, JavacNode errorNode) { - ListBuffer params = ListBuffer.lb(); - ListBuffer result = ListBuffer.lb(); + ListBuffer params = new ListBuffer(); + ListBuffer result = new ListBuffer(); errorNode.removeDeferredErrors(); @@ -1086,13 +1086,13 @@ public class JavacHandlerUtil { public static List copyTypeParams(JavacTreeMaker maker, List params) { if (params == null || params.isEmpty()) return params; - ListBuffer out = ListBuffer.lb(); + ListBuffer out = new ListBuffer(); for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); return out.toList(); } public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List params) { - ListBuffer typeArgs = ListBuffer.lb(); + ListBuffer typeArgs = new ListBuffer(); if (!params.isEmpty()) { for (JCTypeParameter param : params) { @@ -1128,7 +1128,7 @@ public class JavacHandlerUtil { } static List copyAnnotations(List in) { - ListBuffer out = ListBuffer.lb(); + ListBuffer out = new ListBuffer(); for (JCExpression expr : in) { if (!(expr instanceof JCAnnotation)) continue; out.append((JCAnnotation) expr.clone()); @@ -1197,7 +1197,7 @@ public class JavacHandlerUtil { if (in instanceof JCTypeApply) { JCTypeApply ta = (JCTypeApply) in; - ListBuffer lb = ListBuffer.lb(); + ListBuffer lb = new ListBuffer(); for (JCExpression typeArg : ta.arguments) { lb.append(cloneType0(maker, typeArg)); } diff --git a/src/utils/lombok/javac/java6/CommentCollectingScanner.java b/src/utils/lombok/javac/java6/CommentCollectingScanner.java index 5d820ba0..a0e78380 100644 --- a/src/utils/lombok/javac/java6/CommentCollectingScanner.java +++ b/src/utils/lombok/javac/java6/CommentCollectingScanner.java @@ -28,11 +28,12 @@ import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; import com.sun.tools.javac.parser.Scanner; +import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; public class CommentCollectingScanner extends Scanner { - private final ListBuffer comments = ListBuffer.lb(); + private final ListBuffer comments = new ListBuffer(); private int endComment = 0; public CommentCollectingScanner(CommentCollectingScannerFactory factory, CharBuffer charBuffer) { diff --git a/src/utils/lombok/javac/java7/CommentCollectingScanner.java b/src/utils/lombok/javac/java7/CommentCollectingScanner.java index 86c474ea..f97c20a7 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingScanner.java +++ b/src/utils/lombok/javac/java7/CommentCollectingScanner.java @@ -28,11 +28,12 @@ import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; import com.sun.tools.javac.parser.Scanner; +import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; public class CommentCollectingScanner extends Scanner { - private final ListBuffer comments = ListBuffer.lb(); + private final ListBuffer comments = new ListBuffer(); private int endComment = 0; public CommentCollectingScanner(CommentCollectingScannerFactory factory, CharBuffer charBuffer) { diff --git a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java index 95945f8f..a81ebab1 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java +++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java @@ -12,12 +12,13 @@ import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.parser.UnicodeReader; +import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; class CommentCollectingTokenizer extends JavaTokenizer { private int prevEndPosition = 0; - private final ListBuffer comments = ListBuffer.lb(); + private final ListBuffer comments = new ListBuffer(); private int endComment = 0; CommentCollectingTokenizer(ScannerFactory fac, char[] buf, int inputLength) { -- cgit From 00a8b08226aa0daa2061d171607bf0d5369ed292 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Wed, 25 Sep 2013 22:12:05 +0200 Subject: [jdk8support] there was a bunch of duplicate code in both JavacAST and JavacResolution. We've unified this (and fixed the fact that the JavacAST variant didn't work with javac8). --- .../lombok/javac/CompilerMessageSuppressor.java | 286 +++++++++++++++++++++ src/core/lombok/javac/JavacAST.java | 44 +--- src/core/lombok/javac/JavacResolution.java | 225 +--------------- 3 files changed, 295 insertions(+), 260 deletions(-) create mode 100644 src/core/lombok/javac/CompilerMessageSuppressor.java (limited to 'src/core') diff --git a/src/core/lombok/javac/CompilerMessageSuppressor.java b/src/core/lombok/javac/CompilerMessageSuppressor.java new file mode 100644 index 00000000..a17e0c62 --- /dev/null +++ b/src/core/lombok/javac/CompilerMessageSuppressor.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2011-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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Log; + +/** + * During resolution, the resolver will emit resolution errors, but without appropriate file names and line numbers. If these resolution errors stick around + * then they will be generated AGAIN, this time with proper names and line numbers, at the end. Therefore, we want to suppress the logger. + */ +public final class CompilerMessageSuppressor { + private final Log log; + private static final Field errWriterField, warnWriterField, noticeWriterField, dumpOnErrorField, promptOnErrorField, diagnosticListenerField; + private static final Field deferDiagnosticsField, deferredDiagnosticsField, diagnosticHandlerField; + private static final ConcurrentMap, Field> handlerDeferredFields = new ConcurrentHashMap, Field>(); + private static final Field NULL_FIELD; + private PrintWriter errWriter, warnWriter, noticeWriter; + private Boolean dumpOnError, promptOnError; + private DiagnosticListener contextDiagnosticListener, logDiagnosticListener; + private final Context context; + + // If this is true, the fields changed. Better to print weird error messages than to fail outright. + private static final boolean dontBother; + + private static final ThreadLocal> queueCache = new ThreadLocal>(); + + static { + errWriterField = getDeclaredField(Log.class, "errWriter"); + warnWriterField = getDeclaredField(Log.class, "warnWriter"); + noticeWriterField = getDeclaredField(Log.class, "noticeWriter"); + dumpOnErrorField = getDeclaredField(Log.class, "dumpOnError"); + promptOnErrorField = getDeclaredField(Log.class, "promptOnError"); + diagnosticListenerField = getDeclaredField(Log.class, "diagListener"); + + dontBother = + errWriterField == null || + warnWriterField == null || + noticeWriterField == null || + dumpOnErrorField == null || + promptOnErrorField == null || + diagnosticListenerField == null; + + + deferDiagnosticsField = getDeclaredField(Log.class, "deferDiagnostics"); + deferredDiagnosticsField = getDeclaredField(Log.class, "deferredDiagnostics"); + + // javac8 + diagnosticHandlerField = getDeclaredField(Log.class, "diagnosticHandler"); + + NULL_FIELD = getDeclaredField(JavacResolution.class, "NULL_FIELD"); + } + + static Field getDeclaredField(Class c, String fieldName) { + try { + Field field = c.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + catch (Throwable t) { + return null; + } + } + + public CompilerMessageSuppressor(Context context) { + this.log = Log.instance(context); + this.context = context; + } + + public boolean disableLoggers() { + contextDiagnosticListener = context.get(DiagnosticListener.class); + context.put(DiagnosticListener.class, (DiagnosticListener) null); + if (dontBother) return false; + boolean dontBotherInstance = false; + + PrintWriter dummyWriter = new PrintWriter(new OutputStream() { + @Override public void write(int b) throws IOException { + // Do nothing on purpose + } + }); + + if (deferDiagnosticsField != null) try { + if (Boolean.TRUE.equals(deferDiagnosticsField.get(log))) { + queueCache.set((Queue) deferredDiagnosticsField.get(log)); + Queue empty = new LinkedList(); + deferredDiagnosticsField.set(log, empty); + } + } catch (Exception e) {} + + if (diagnosticHandlerField != null) try { + Object handler = diagnosticHandlerField.get(log); + Field field = getDeferredField(handler); + if (field != null) { + queueCache.set((Queue) field.get(handler)); + Queue empty = new LinkedList(); + field.set(handler, empty); + } + } catch (Exception e) {} + + if (!dontBotherInstance) try { + errWriter = (PrintWriter) errWriterField.get(log); + errWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + warnWriter = (PrintWriter) warnWriterField.get(log); + warnWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + noticeWriter = (PrintWriter) noticeWriterField.get(log); + noticeWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + dumpOnError = (Boolean) dumpOnErrorField.get(log); + dumpOnErrorField.set(log, false); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + promptOnError = (Boolean) promptOnErrorField.get(log); + promptOnErrorField.set(log, false); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + logDiagnosticListener = (DiagnosticListener) diagnosticListenerField.get(log); + diagnosticListenerField.set(log, null); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (dontBotherInstance) enableLoggers(); + return !dontBotherInstance; + } + + private static Field getDeferredField(Object handler) { + Class key = handler.getClass(); + Field field = handlerDeferredFields.get(key); + if (field != null) { + return field == NULL_FIELD ? null : field; + } + Field value = getDeclaredField(key, "deferred"); + handlerDeferredFields.put(key, value == null ? NULL_FIELD : value); + return getDeferredField(handler); + } + + public void enableLoggers() { + if (contextDiagnosticListener != null) { + context.put(DiagnosticListener.class, contextDiagnosticListener); + contextDiagnosticListener = null; + } + + if (errWriter != null) try { + errWriterField.set(log, errWriter); + errWriter = null; + } catch (Exception e) {} + + if (warnWriter != null) try { + warnWriterField.set(log, warnWriter); + warnWriter = null; + } catch (Exception e) {} + + if (noticeWriter != null) try { + noticeWriterField.set(log, noticeWriter); + noticeWriter = null; + } catch (Exception e) {} + + if (dumpOnError != null) try { + dumpOnErrorField.set(log, dumpOnError); + dumpOnError = null; + } catch (Exception e) {} + + if (promptOnError != null) try { + promptOnErrorField.set(log, promptOnError); + promptOnError = null; + } catch (Exception e) {} + + if (logDiagnosticListener != null) try { + diagnosticListenerField.set(log, logDiagnosticListener); + logDiagnosticListener = null; + } catch (Exception e) {} + + if (diagnosticHandlerField != null && queueCache.get() != null) try { + Object handler = diagnosticHandlerField.get(log); + Field field = getDeferredField(handler); + if (field != null) { + field.set(handler, queueCache.get()); + queueCache.set(null); + } + } catch (Exception e) {} + + if (deferDiagnosticsField != null && queueCache.get() != null) try { + deferredDiagnosticsField.set(log, queueCache.get()); + queueCache.set(null); + } catch (Exception e) {} + } + + public void removeAllBetween(JavaFileObject sourcefile, int startPos, int endPos) { + DiagnosticListener listener = context.get(DiagnosticListener.class); + if (listener instanceof CapturingDiagnosticListener) { + ((CapturingDiagnosticListener) listener).suppress(startPos, endPos); + } + + Field field = null; + Object receiver = null; + if (deferDiagnosticsField != null) try { + if (Boolean.TRUE.equals(deferDiagnosticsField.get(log))) { + field = deferredDiagnosticsField; + receiver = log; + } + } catch (Exception e) {} + + if (diagnosticHandlerField != null) try { + Object handler = diagnosticHandlerField.get(log); + field = getDeferredField(handler); + receiver = handler; + } catch (Exception e) {} + + if (field == null || receiver == null) return; + + try { + ListBuffer deferredDiagnostics = (ListBuffer) field.get(receiver); + ListBuffer newDeferredDiagnostics = new ListBuffer(); + for (Object diag_ : deferredDiagnostics) { + if (!(diag_ instanceof JCDiagnostic)) { + newDeferredDiagnostics.add(diag_); + continue; + } + JCDiagnostic diag = (JCDiagnostic) diag_; + long here = diag.getStartPosition(); + if (here >= startPos && here < endPos && diag.getSource() == sourcefile) { + // We eliminate it + } else { + newDeferredDiagnostics.add(diag); + } + } + field.set(receiver, newDeferredDiagnostics); + } catch (Exception e) { + // We do not expect failure here; if failure does occur, the best course of action is to silently continue; the result will be that the error output of + // javac will contain rather a lot of messages, but this is a lot better than just crashing during compilation! + } + } +} \ No newline at end of file diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 2422b553..31bdc3a6 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -29,7 +29,6 @@ import java.util.List; import javax.annotation.processing.Messager; import javax.tools.Diagnostic; -import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; import lombok.core.AST; @@ -53,8 +52,6 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.JCDiagnostic; -import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -343,17 +340,6 @@ public class JavacAST extends AST { if (node != null) nodes.add(node); } - private static final Field JAVAC7_DEFERRED_DIAGNOSTICS; - - static { - Field f = null; - try { - f = Log.class.getField("deferredDiagnostics"); - if (!ListBuffer.class.isAssignableFrom(f.getType())) throw new NoSuchFieldException("deferredDiagnostics does not have the expected type."); - } catch (NoSuchFieldException e) {} - JAVAC7_DEFERRED_DIAGNOSTICS = f; - } - /** * Attempts to remove any compiler errors generated by java whose reporting position is located anywhere between the start and end of the supplied node. */ @@ -400,34 +386,8 @@ public class JavacAST extends AST { } private void removeFromDeferredDiagnostics(int startPos, int endPos) { - DiagnosticListener listener = getContext().get(DiagnosticListener.class); - if (listener instanceof CapturingDiagnosticListener) { - ((CapturingDiagnosticListener) listener).suppress(startPos, endPos); - } - try { - // TODO: This changed a bit in java8; there is now also a Handler thingie; see JavacResolution for what changed. - // Possibly integrate these 2 code paths. - if (JAVAC7_DEFERRED_DIAGNOSTICS != null) { - ListBuffer deferredDiagnostics = (ListBuffer) JAVAC7_DEFERRED_DIAGNOSTICS.get(log); - ListBuffer newDeferredDiagnostics = new ListBuffer(); - for (Object diag : deferredDiagnostics) { - if (!(diag instanceof JCDiagnostic)) { - newDeferredDiagnostics.add(diag); - continue; - } - long here = ((JCDiagnostic) diag).getStartPosition(); - if (here >= startPos && here < endPos) { - // We eliminate it - } else { - newDeferredDiagnostics.add(diag); - } - } - JAVAC7_DEFERRED_DIAGNOSTICS.set(log, newDeferredDiagnostics); - } - } catch (Exception e) { - // We do not expect failure here; if failure does occur, the best course of action is to silently continue; the result will be that the error output of - // javac will contain rather a lot of messages, but this is a lot better than just crashing during compilation! - } + JCCompilationUnit self = (JCCompilationUnit) top().get(); + new CompilerMessageSuppressor(getContext()).removeAllBetween(self.sourcefile, startPos, endPos); } /** {@inheritDoc} */ diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index acfca6a6..5631e62c 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 The Project Lombok Authors. + * Copyright (C) 2011-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 @@ -24,19 +24,10 @@ package lombok.javac; import static lombok.javac.Javac.*; import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.lang.reflect.Field; import java.util.ArrayDeque; -import java.util.LinkedList; import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import javax.lang.model.type.TypeKind; -import javax.tools.DiagnosticListener; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Symbol.TypeSymbol; @@ -62,216 +53,14 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Log; public class JavacResolution { private final Attr attr; - private final LogDisabler logDisabler; + private final CompilerMessageSuppressor messageSuppressor; public JavacResolution(Context context) { attr = Attr.instance(context); - logDisabler = new LogDisabler(context); - } - - /** - * During resolution, the resolver will emit resolution errors, but without appropriate file names and line numbers. If these resolution errors stick around - * then they will be generated AGAIN, this time with proper names and line numbers, at the end. Therefore, we want to suppress the logger. - */ - private static final class LogDisabler { - private final Log log; - private static final Field errWriterField, warnWriterField, noticeWriterField, dumpOnErrorField, promptOnErrorField, diagnosticListenerField; - private static final Field deferDiagnosticsField, deferredDiagnosticsField, diagnosticHandlerField; - private static final ConcurrentMap, Field> handlerDeferredFields = new ConcurrentHashMap, Field>(); - private static final Field NULL_FIELD; - private PrintWriter errWriter, warnWriter, noticeWriter; - private Boolean dumpOnError, promptOnError; - private DiagnosticListener contextDiagnosticListener, logDiagnosticListener; - private final Context context; - - // If this is true, the fields changed. Better to print weird error messages than to fail outright. - private static final boolean dontBother; - - private static final ThreadLocal> queueCache = new ThreadLocal>(); - - static { - errWriterField = getDeclaredField(Log.class, "errWriter"); - warnWriterField = getDeclaredField(Log.class, "warnWriter"); - noticeWriterField = getDeclaredField(Log.class, "noticeWriter"); - dumpOnErrorField = getDeclaredField(Log.class, "dumpOnError"); - promptOnErrorField = getDeclaredField(Log.class, "promptOnError"); - diagnosticListenerField = getDeclaredField(Log.class, "diagListener"); - - dontBother = - errWriterField == null || - warnWriterField == null || - noticeWriterField == null || - dumpOnErrorField == null || - promptOnErrorField == null || - diagnosticListenerField == null; - - - deferDiagnosticsField = getDeclaredField(Log.class, "deferDiagnostics"); - deferredDiagnosticsField = getDeclaredField(Log.class, "deferredDiagnostics"); - - // javac8 - diagnosticHandlerField = getDeclaredField(Log.class, "diagnosticHandler"); - - NULL_FIELD = getDeclaredField(JavacResolution.class, "NULL_FIELD"); - } - - static Field getDeclaredField(Class c, String fieldName) { - try { - Field field = c.getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } - catch (Throwable t) { - return null; - } - } - - LogDisabler(Context context) { - this.log = Log.instance(context); - this.context = context; - } - - boolean disableLoggers() { - contextDiagnosticListener = context.get(DiagnosticListener.class); - context.put(DiagnosticListener.class, (DiagnosticListener) null); - if (dontBother) return false; - boolean dontBotherInstance = false; - - PrintWriter dummyWriter = new PrintWriter(new OutputStream() { - @Override public void write(int b) throws IOException { - // Do nothing on purpose - } - }); - - if (deferDiagnosticsField != null) try { - if (Boolean.TRUE.equals(deferDiagnosticsField.get(log))) { - queueCache.set((Queue) deferredDiagnosticsField.get(log)); - Queue empty = new LinkedList(); - deferredDiagnosticsField.set(log, empty); - } - } catch (Exception e) {} - - if (diagnosticHandlerField != null) try { - Object handler = diagnosticHandlerField.get(log); - Field field = getDeferredField(handler); - if (field != null) { - queueCache.set((Queue) field.get(handler)); - Queue empty = new LinkedList(); - field.set(handler, empty); - } - } catch (Exception e) {} - - if (!dontBotherInstance) try { - errWriter = (PrintWriter) errWriterField.get(log); - errWriterField.set(log, dummyWriter); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (!dontBotherInstance) try { - warnWriter = (PrintWriter) warnWriterField.get(log); - warnWriterField.set(log, dummyWriter); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (!dontBotherInstance) try { - noticeWriter = (PrintWriter) noticeWriterField.get(log); - noticeWriterField.set(log, dummyWriter); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (!dontBotherInstance) try { - dumpOnError = (Boolean) dumpOnErrorField.get(log); - dumpOnErrorField.set(log, false); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (!dontBotherInstance) try { - promptOnError = (Boolean) promptOnErrorField.get(log); - promptOnErrorField.set(log, false); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (!dontBotherInstance) try { - logDiagnosticListener = (DiagnosticListener) diagnosticListenerField.get(log); - diagnosticListenerField.set(log, null); - } catch (Exception e) { - dontBotherInstance = true; - } - - if (dontBotherInstance) enableLoggers(); - return !dontBotherInstance; - } - - private static Field getDeferredField(Object handler) { - Class key = handler.getClass(); - Field field = handlerDeferredFields.get(key); - if (field != null) { - return field == NULL_FIELD ? null : field; - } - Field value = getDeclaredField(key, "deferred"); - handlerDeferredFields.put(key, value == null ? NULL_FIELD : value); - return getDeferredField(handler); - } - - void enableLoggers() { - if (contextDiagnosticListener != null) { - context.put(DiagnosticListener.class, contextDiagnosticListener); - contextDiagnosticListener = null; - } - - if (errWriter != null) try { - errWriterField.set(log, errWriter); - errWriter = null; - } catch (Exception e) {} - - if (warnWriter != null) try { - warnWriterField.set(log, warnWriter); - warnWriter = null; - } catch (Exception e) {} - - if (noticeWriter != null) try { - noticeWriterField.set(log, noticeWriter); - noticeWriter = null; - } catch (Exception e) {} - - if (dumpOnError != null) try { - dumpOnErrorField.set(log, dumpOnError); - dumpOnError = null; - } catch (Exception e) {} - - if (promptOnError != null) try { - promptOnErrorField.set(log, promptOnError); - promptOnError = null; - } catch (Exception e) {} - - if (logDiagnosticListener != null) try { - diagnosticListenerField.set(log, logDiagnosticListener); - logDiagnosticListener = null; - } catch (Exception e) {} - - if (diagnosticHandlerField != null && queueCache.get() != null) try { - Object handler = diagnosticHandlerField.get(log); - Field field = getDeferredField(handler); - if (field != null) { - field.set(handler, queueCache.get()); - queueCache.set(null); - } - } catch (Exception e) {} - - if (deferDiagnosticsField != null && queueCache.get() != null) try { - deferredDiagnosticsField.set(log, queueCache.get()); - queueCache.set(null); - } catch (Exception e) {} - } + messageSuppressor = new CompilerMessageSuppressor(context); } /* @@ -351,7 +140,7 @@ public class JavacResolution { } } - logDisabler.disableLoggers(); + messageSuppressor.disableLoggers(); try { EnvFinder finder = new EnvFinder(node.getContext()); while (!stack.isEmpty()) stack.pop().accept(finder); @@ -362,7 +151,7 @@ public class JavacResolution { attrib(copy, finder.get()); return mirrorMaker.getOriginalToCopyMap(); } finally { - logDisabler.enableLoggers(); + messageSuppressor.enableLoggers(); } } @@ -377,14 +166,14 @@ public class JavacResolution { } } - logDisabler.disableLoggers(); + messageSuppressor.disableLoggers(); try { EnvFinder finder = new EnvFinder(node.getContext()); while (!stack.isEmpty()) stack.pop().accept(finder); attrib(node.get(), finder.get()); } finally { - logDisabler.enableLoggers(); + messageSuppressor.enableLoggers(); } } -- cgit From 728dddbc81d9f9bfbbd3f8217b8c94f3f201c83d Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Wed, 25 Sep 2013 23:04:04 +0200 Subject: [jdk8support] ... and javadoc copying support is back for javac8. Also fixed some copyright headers. --- .../lombok/javac/handlers/JavacHandlerUtil.java | 42 +++++++++++++++++ .../lombok/delombok/DocCommentIntegrator.java | 25 +++++++++- .../lombok/delombok/PrettyCommentsPrinter.java | 54 ++++++++++++---------- src/stubs/com/sun/tools/javac/parser/Tokens.java | 12 ++++- .../com/sun/tools/javac/tree/DocCommentTable.java | 10 ++++ .../javac/java6/CommentCollectingParser.java | 21 +++++++++ .../java6/CommentCollectingParserFactory.java | 21 +++++++++ .../javac/java6/CommentCollectingScanner.java | 3 +- .../javac/java7/CommentCollectingParser.java | 21 +++++++++ .../java7/CommentCollectingParserFactory.java | 21 +++++++++ .../javac/java7/CommentCollectingScanner.java | 3 +- .../javac/java8/CommentCollectingParser.java | 21 +++++++++ .../java8/CommentCollectingParserFactory.java | 21 +++++++++ .../javac/java8/CommentCollectingScanner.java | 21 +++++++++ .../javac/java8/CommentCollectingTokenizer.java | 22 ++++++++- 15 files changed, 287 insertions(+), 31 deletions(-) create mode 100644 src/stubs/com/sun/tools/javac/tree/DocCommentTable.java (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index f90bb60d..6d6426aa 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -50,6 +50,8 @@ 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; @@ -216,6 +218,17 @@ public class JavacHandlerUtil { return false; } + /** + * 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. * @@ -1325,7 +1338,36 @@ public class JavacHandlerUtil { docComments.put(to, filtered[0]); docComments.put(from.get(), filtered[1]); } + } else if (dc instanceof DocCommentTable) { + 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)); + } } } catch (Exception ignore) {} } + + 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); + } + }; + } } diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java index 80aec16a..c1eb02b6 100644 --- a/src/delombok/lombok/delombok/DocCommentIntegrator.java +++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java @@ -8,7 +8,10 @@ import java.util.regex.Pattern; import lombok.javac.CommentInfo; import lombok.javac.Javac; +import lombok.javac.handlers.JavacHandlerUtil; +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.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -50,7 +53,7 @@ public class DocCommentIntegrator { } private static final Pattern CONTENT_STRIPPER = Pattern.compile("^(?:\\s*\\*)?[ \\t]*(.*?)$", Pattern.MULTILINE); - @SuppressWarnings("unchecked") private boolean attach(JCCompilationUnit top, JCTree node, CommentInfo cmt) { + @SuppressWarnings("unchecked") private boolean attach(JCCompilationUnit top, final JCTree node, CommentInfo cmt) { String docCommentContent = cmt.content; if (docCommentContent.startsWith("/**")) docCommentContent = docCommentContent.substring(3); if (docCommentContent.endsWith("*/")) docCommentContent = docCommentContent.substring(0, docCommentContent.length() -2); @@ -63,6 +66,26 @@ public class DocCommentIntegrator { if (map_ instanceof Map) { ((Map) map_).put(node, docCommentContent); return true; + } else if (map_ instanceof DocCommentTable) { + final String docCommentContent_ = docCommentContent; + ((DocCommentTable) map_).putComment(node, new Comment() { + @Override public String getText() { + return docCommentContent_; + } + + @Override public int getSourcePos(int index) { + return -1; + } + + @Override public CommentStyle getStyle() { + return CommentStyle.JAVADOC; + } + + @Override public boolean isDeprecated() { + return JavacHandlerUtil.nodeHasDeprecatedFlag(node); + } + }); + return true; } return false; diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 525773f4..67c313ab 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -101,6 +101,7 @@ import com.sun.tools.javac.tree.JCTree.JCWhileLoop; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.LetExpr; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.DocCommentTable; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Convert; @@ -270,6 +271,13 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { * (can be null) */ Map docComments = null; + DocCommentTable docTable = null; + + String getJavadocFor(JCTree node) { + if (docComments != null) return docComments.get(node); + if (docTable != null) return docTable.getCommentText(node); + return null; + } /** Align code to be indented to left margin. */ @@ -464,31 +472,28 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { * @param tree The tree for which a documentation comment should be printed. */ public void printDocComment(JCTree tree) throws IOException { - if (docComments != null) { - String dc = docComments.get(tree); - if (dc != null) { - print("/**"); println(); - int pos = 0; - int endpos = lineEndPos(dc, pos); - boolean atStart = true; - while (pos < dc.length()) { - String line = dc.substring(pos, endpos); - if (line.trim().isEmpty() && atStart) { - atStart = false; - continue; - } - atStart = false; - align(); - print(" *"); - if (pos < dc.length() && dc.charAt(pos) > ' ') print(" "); - print(dc.substring(pos, endpos)); println(); - pos = endpos + 1; - endpos = lineEndPos(dc, pos); - } - align(); print(" */"); println(); - align(); + String dc = getJavadocFor(tree); + if (dc == null) return; + print("/**"); println(); + int pos = 0; + int endpos = lineEndPos(dc, pos); + boolean atStart = true; + while (pos < dc.length()) { + String line = dc.substring(pos, endpos); + if (line.trim().isEmpty() && atStart) { + atStart = false; + continue; } + atStart = false; + align(); + print(" *"); + if (pos < dc.length() && dc.charAt(pos) > ' ') print(" "); + print(dc.substring(pos, endpos)); println(); + pos = endpos + 1; + endpos = lineEndPos(dc, pos); } + align(); print(" */"); println(); + align(); } //where static int lineEndPos(String s, int start) { @@ -586,6 +591,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { Object dc = getDocComments(tree); if (dc instanceof Map) this.docComments = (Map) dc; + else if (dc instanceof DocCommentTable) this.docTable = (DocCommentTable) dc; printDocComment(tree); if (tree.pid != null) { consumeComments(tree.pos, tree); @@ -767,7 +773,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitVarDef(JCVariableDecl tree) { try { - if (docComments != null && docComments.get(tree) != null) { + if (getJavadocFor(tree) != null) { println(); align(); } printDocComment(tree); diff --git a/src/stubs/com/sun/tools/javac/parser/Tokens.java b/src/stubs/com/sun/tools/javac/parser/Tokens.java index 3d14d27c..6e0aa479 100644 --- a/src/stubs/com/sun/tools/javac/parser/Tokens.java +++ b/src/stubs/com/sun/tools/javac/parser/Tokens.java @@ -6,6 +6,16 @@ public class Tokens { } public interface Comment { - enum CommentStyle {} + enum CommentStyle { + LINE, BLOCK, JAVADOC, + } + + String getText(); + + int getSourcePos(int index); + + CommentStyle getStyle(); + + boolean isDeprecated(); } } diff --git a/src/stubs/com/sun/tools/javac/tree/DocCommentTable.java b/src/stubs/com/sun/tools/javac/tree/DocCommentTable.java new file mode 100644 index 00000000..75b2526a --- /dev/null +++ b/src/stubs/com/sun/tools/javac/tree/DocCommentTable.java @@ -0,0 +1,10 @@ +package com.sun.tools.javac.tree; + +import com.sun.tools.javac.parser.Tokens.Comment; + +public interface DocCommentTable { + boolean hasComment(JCTree tree); + Comment getComment(JCTree tree); + String getCommentText(JCTree tree); + void putComment(JCTree tree, Comment c); +} diff --git a/src/utils/lombok/javac/java6/CommentCollectingParser.java b/src/utils/lombok/javac/java6/CommentCollectingParser.java index 94a85e55..30192b06 100644 --- a/src/utils/lombok/javac/java6/CommentCollectingParser.java +++ b/src/utils/lombok/javac/java6/CommentCollectingParser.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java6; import java.util.Map; diff --git a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java index 7e34b723..b250b898 100644 --- a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java +++ b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java6; import java.lang.reflect.Field; diff --git a/src/utils/lombok/javac/java6/CommentCollectingScanner.java b/src/utils/lombok/javac/java6/CommentCollectingScanner.java index a0e78380..df383b93 100644 --- a/src/utils/lombok/javac/java6/CommentCollectingScanner.java +++ b/src/utils/lombok/javac/java6/CommentCollectingScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Project Lombok Authors. + * Copyright (C) 2011-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 @@ -28,7 +28,6 @@ import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; import com.sun.tools.javac.parser.Scanner; -import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; diff --git a/src/utils/lombok/javac/java7/CommentCollectingParser.java b/src/utils/lombok/javac/java7/CommentCollectingParser.java index 82f19c42..0e8a4ef6 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingParser.java +++ b/src/utils/lombok/javac/java7/CommentCollectingParser.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java7; import java.util.List; diff --git a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java index e9575c14..ed8279df 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java +++ b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java7; import java.lang.reflect.Field; diff --git a/src/utils/lombok/javac/java7/CommentCollectingScanner.java b/src/utils/lombok/javac/java7/CommentCollectingScanner.java index f97c20a7..3f76f910 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingScanner.java +++ b/src/utils/lombok/javac/java7/CommentCollectingScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Project Lombok Authors. + * Copyright (C) 2011-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 @@ -28,7 +28,6 @@ import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; import com.sun.tools.javac.parser.Scanner; -import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; diff --git a/src/utils/lombok/javac/java8/CommentCollectingParser.java b/src/utils/lombok/javac/java8/CommentCollectingParser.java index 6cf65dca..e305e44f 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingParser.java +++ b/src/utils/lombok/javac/java8/CommentCollectingParser.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java8; import java.util.List; diff --git a/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java index 594ff8ba..6b5f9198 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java +++ b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java8; import java.lang.reflect.Field; diff --git a/src/utils/lombok/javac/java8/CommentCollectingScanner.java b/src/utils/lombok/javac/java8/CommentCollectingScanner.java index 1b8474ac..b59a9390 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingScanner.java +++ b/src/utils/lombok/javac/java8/CommentCollectingScanner.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java8; import lombok.javac.CommentInfo; diff --git a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java index a81ebab1..1834fb00 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java +++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.javac.java8; import java.nio.CharBuffer; @@ -12,7 +33,6 @@ import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.parser.UnicodeReader; -import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; -- cgit From 08961edcfeef9b181621351e36bbc267f9395415 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 10 Oct 2013 20:41:29 +0200 Subject: Whoops, Classload errors running lombok on javac with backing JVM 7 or below; fixed. --- .../lombok/javac/handlers/JavacHandlerUtil.java | 78 ++++++++++++---------- .../lombok/delombok/DocCommentIntegrator.java | 15 +++-- src/utils/lombok/javac/Javac.java | 14 ++++ 3 files changed, 69 insertions(+), 38 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 6d6426aa..50e80169 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1323,51 +1323,61 @@ public class JavacHandlerUtil { * * in 'SETTER' mode, stripping works similarly to 'GETTER' mode, except {@code param} are copied and stripped from the original and {@code @return} are skipped. */ - @SuppressWarnings("unchecked") public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) { if (copyMode == null) copyMode = CopyJavadoc.VERBATIM; try { JCCompilationUnit cu = ((JCCompilationUnit) from.top().get()); Object dc = Javac.getDocComments(cu); if (dc instanceof Map) { - Map docComments = (Map) 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]); - } - } else if (dc instanceof DocCommentTable) { - 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)); - } + copyJavadoc_jdk6_7(from, to, copyMode, dc); + } else if (Javac.instanceOfDocCommentTable(dc)) { + CopyJavadoc_8.copyJavadoc(from, to, copyMode, dc); } } catch (Exception ignore) {} } - private static Comment createJavadocComment(final String text, final JavacNode field) { - return new Comment() { - @Override public String getText() { - return text; - } + 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()); - @Override public int getSourcePos(int index) { - return -1; + if (javadoc != null) { + String[] filtered = copyMode.split(javadoc.getText()); + dct.putComment(to, createJavadocComment(filtered[0], from)); + dct.putComment(from.get(), createJavadocComment(filtered[1], from)); } - - @Override public CommentStyle getStyle() { - return CommentStyle.JAVADOC; - } - - @Override public boolean isDeprecated() { - return text.contains("@deprecated") && field.getKind() == Kind.FIELD && isFieldDeprecated(field); - } - }; + } + + 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 docComments = (Map) 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]); + } } } diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java index c1eb02b6..0955a003 100644 --- a/src/delombok/lombok/delombok/DocCommentIntegrator.java +++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java @@ -66,7 +66,17 @@ public class DocCommentIntegrator { if (map_ instanceof Map) { ((Map) map_).put(node, docCommentContent); return true; - } else if (map_ instanceof DocCommentTable) { + } else if (Javac.instanceOfDocCommentTable(map_)) { + CommentAttacher_8.attach(node, docCommentContent, map_); + return true; + } + + return false; + } + + /* Container for code which will cause class loader exceptions on javac below 8. By being in a separate class, we avoid the problem. */ + private static class CommentAttacher_8 { + static void attach(final JCTree node, String docCommentContent, Object map_) { final String docCommentContent_ = docCommentContent; ((DocCommentTable) map_).putComment(node, new Comment() { @Override public String getText() { @@ -85,10 +95,7 @@ public class DocCommentIntegrator { return JavacHandlerUtil.nodeHasDeprecatedFlag(node); } }); - return true; } - - return false; } private JCTree findJavadocableNodeOnOrAfter(JCCompilationUnit unit, int endPos) { diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 554c778d..bdf5e7a0 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -103,6 +103,20 @@ public class Javac { return 6; } + private static final Class DOCCOMMENTTABLE_CLASS; + + static { + Class c = null; + try { + c = Class.forName("com.sun.tools.javac.tree.DocCommentTable"); + } catch (Throwable ignore) {} + DOCCOMMENTTABLE_CLASS = c; + } + + public static boolean instanceOfDocCommentTable(Object o) { + return DOCCOMMENTTABLE_CLASS != null && DOCCOMMENTTABLE_CLASS.isInstance(o); + } + /** * Checks if the given expression (that really ought to refer to a type * expression) represents a primitive type. -- cgit From a9b4fb0c685fbc52079d57532c04277e78c95ec2 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 10 Oct 2013 22:36:16 +0200 Subject: Fix for issues when mixing @NonNull on params with @SneakyThrows or @Synchronized [Issue #588] --- doc/changelog.markdown | 9 +- src/core/lombok/core/Version.java | 2 +- .../lombok/eclipse/handlers/HandleNonNull.java | 175 ++++++++++++++++++++ .../eclipse/handlers/HandleSneakyThrows.java | 2 + .../eclipse/handlers/HandleSynchronized.java | 2 + .../lombok/eclipse/handlers/NonNullHandler.java | 152 ----------------- src/core/lombok/javac/handlers/HandleNonNull.java | 179 +++++++++++++++++++++ .../lombok/javac/handlers/HandleSneakyThrows.java | 2 + .../lombok/javac/handlers/HandleSynchronized.java | 2 + src/core/lombok/javac/handlers/NonNullHandler.java | 156 ------------------ .../after-delombok/NonNullWithSneakyThrows.java | 12 ++ test/transform/resource/after-ecj/InjectField.java | 4 +- .../after-ecj/NonNullWithSneakyThrows.java | 18 +++ .../resource/before/NonNullWithSneakyThrows.java | 5 + 14 files changed, 407 insertions(+), 313 deletions(-) create mode 100644 src/core/lombok/eclipse/handlers/HandleNonNull.java delete mode 100644 src/core/lombok/eclipse/handlers/NonNullHandler.java create mode 100644 src/core/lombok/javac/handlers/HandleNonNull.java delete mode 100644 src/core/lombok/javac/handlers/NonNullHandler.java create mode 100644 test/transform/resource/after-delombok/NonNullWithSneakyThrows.java create mode 100644 test/transform/resource/after-ecj/NonNullWithSneakyThrows.java create mode 100644 test/transform/resource/before/NonNullWithSneakyThrows.java (limited to 'src/core') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 7782f1fa..1ee3504c 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,8 +1,13 @@ Lombok Changelog ---------------- -### v0.12.1 "Edgy Guinea Pig" -* PLATFORM: Initial (not quite totally finished) JDK8 support, without affecting existing support for JDK6 and 7. [Issue #451](https://code.google.com/p/projectlombok/issues/detail?id=451). +### v1.12.2 (October 10th, 2013) +* PLATFORM: Initial JDK8 support, without affecting existing support for JDK6 and 7. [Issue #451](https://code.google.com/p/projectlombok/issues/detail?id=451). While lombok will now work on JDK8 / javac8, and netbeans 7.4 and up, lombok does not (yet) support new language features introduced with java8, such as lambda expressions. Support for these features will be added in a future version. +* PLATFORM: Running javac on IBM J9 VM would cause NullPointerExceptions when compiling with lombok. These issues should be fixed. [Issue #554](https://code.google.com/p/projectlombok/issues/detail?id=554). +* CHANGE: [JDK8-related] The canonical way to write onMethod / onParameter / onConstructor annotation now uses a double underscore instead of a single underscore, so, now, the proper way to use this feature is `@RequiredArgsConstructor(onConstructor=@__(@Inject))`. The old way (single underscore) still works, but generates warnings on javac 8. +* BUGFIX: Using `@NonNull` on an abstract method used to cause exceptions during compilation. [Issue #559](https://code.google.com/p/projectlombok/issues/detail?id=559). +* BUGFIX: Using `@NonNull` on methods that also have `@SneakyThrows` or `@Synchronized` caused arbitrary behaviour. [Issue #588](https://code.google.com/p/projectlombok/issues/detail?id=588). +* GERMANY: Major version bumped from 0 to 1, because allegedly this is important. Rest assured, this change is nevertheless backwards compatible. ### v0.12.0 "Angry Butterfly" (July 16th, 2013) * FEATURE: javadoc on fields will now be copied to generated getters / setters / withers. There are ways to specify separate javadoc for the field, the setter, and the getter, and `@param` and `@return` are handled appropriately. Addresses feature request [Issue #59](https://code.google.com/p/projectlombok/issues/detail?id=59). [@Getter and @Setter documentation](http://projectlombok.org/features/GetterSetter.html). [@Wither documentation](http://projectlombok.org/features/experimental/Wither.html). diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 24faf821..318075d3 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011 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 diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java new file mode 100644 index 00000000..634cb2d9 --- /dev/null +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.eclipse.handlers; + +import static lombok.eclipse.Eclipse.isPrimitive; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import java.util.Arrays; + +import lombok.NonNull; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; +import lombok.eclipse.DeferUntilPostDiet; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; + +import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Argument; +import org.eclipse.jdt.internal.compiler.ast.Block; +import org.eclipse.jdt.internal.compiler.ast.EqualExpression; +import org.eclipse.jdt.internal.compiler.ast.Expression; +import org.eclipse.jdt.internal.compiler.ast.IfStatement; +import org.eclipse.jdt.internal.compiler.ast.NullLiteral; +import org.eclipse.jdt.internal.compiler.ast.OperatorIds; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; +import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; +import org.eclipse.jdt.internal.compiler.ast.TryStatement; +import org.mangosdk.spi.ProviderFor; + +@DeferUntilPostDiet +@ProviderFor(EclipseAnnotationHandler.class) +@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. +public class HandleNonNull extends EclipseAnnotationHandler { + @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { + if (annotationNode.up().getKind() == Kind.FIELD) { + // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), + // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to + // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning + // behaviour on _OUR_ 'lombok.NonNull'. + + try { + if (isPrimitive(((AbstractVariableDeclaration) annotationNode.up().get()).type)) { + annotationNode.addWarning("@NonNull is meaningless on a primitive."); + } + } catch (Exception ignore) {} + + return; + } + + if (annotationNode.up().getKind() != Kind.ARGUMENT) return; + + Argument arg; + AbstractMethodDeclaration declaration; + + try { + arg = (Argument) annotationNode.up().get(); + declaration = (AbstractMethodDeclaration) annotationNode.up().up().get(); + } catch (Exception e) { + return; + } + + if (isGenerated(declaration)) return; + + if (declaration.isAbstract()) { + 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and + // wrap all references to it in the super/this to a call to this method. + + Statement nullCheck = generateNullCheck(arg, ast); + + if (nullCheck == null) { + // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning. + annotationNode.addWarning("@NonNull is meaningless on a primitive."); + return; + } + + if (declaration.statements == null) { + declaration.statements = new Statement[] {nullCheck}; + } else { + char[] expectedName = arg.name; + /* Abort if the null check is already there, delving into try and synchronized statements */ { + Statement[] stats = declaration.statements; + int idx = 0; + while (stats != null && stats.length > idx) { + Statement stat = stats[idx++]; + if (stat instanceof TryStatement) { + stats = ((TryStatement) stat).tryBlock.statements; + idx = 0; + continue; + } + if (stat instanceof SynchronizedStatement) { + stats = ((SynchronizedStatement) stat).block.statements; + idx = 0; + continue; + } + char[] varNameOfNullCheck = returnVarNameIfNullCheck(stat); + if (varNameOfNullCheck == null) break; + if (Arrays.equals(varNameOfNullCheck, expectedName)) return; + } + } + + Statement[] newStatements = new Statement[declaration.statements.length + 1]; + int skipOver = 0; + for (Statement stat : declaration.statements) { + if (isGenerated(stat) && isNullCheck(stat)) skipOver++; + else break; + } + System.arraycopy(declaration.statements, 0, newStatements, 0, skipOver); + System.arraycopy(declaration.statements, skipOver, newStatements, skipOver + 1, declaration.statements.length - skipOver); + newStatements[skipOver] = nullCheck; + declaration.statements = newStatements; + } + annotationNode.up().up().rebuild(); + } + + private boolean isNullCheck(Statement stat) { + return returnVarNameIfNullCheck(stat) != null; + } + + private char[] returnVarNameIfNullCheck(Statement stat) { + if (!(stat instanceof IfStatement)) return null; + + /* Check that the if's statement is a throw statement, possibly in a block. */ { + Statement then = ((IfStatement) stat).thenStatement; + if (then instanceof Block) { + Statement[] blockStatements = ((Block) then).statements; + if (blockStatements == null || blockStatements.length == 0) return null; + then = blockStatements[0]; + } + + if (!(then instanceof ThrowStatement)) return null; + } + + /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate + a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { + Expression cond = ((IfStatement) stat).condition; + if (!(cond instanceof EqualExpression)) return null; + EqualExpression bin = (EqualExpression) cond; + int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT); + if (operatorId != OperatorIds.EQUAL_EQUAL) return null; + if (!(bin.left instanceof SingleNameReference)) return null; + if (!(bin.right instanceof NullLiteral)) return null; + return ((SingleNameReference) bin.left).token; + } + } +} diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java index aa78ca3b..d3a95db8 100644 --- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java @@ -30,6 +30,7 @@ import java.util.List; import lombok.SneakyThrows; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; @@ -60,6 +61,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) @DeferUntilPostDiet +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSneakyThrows extends EclipseAnnotationHandler { private static class DeclaredException { diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index e4c58eab..f76f06ed 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java @@ -27,6 +27,7 @@ import java.lang.reflect.Modifier; import lombok.Synchronized; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.core.AST.Kind; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; @@ -52,6 +53,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) @DeferUntilPostDiet +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSynchronized extends EclipseAnnotationHandler { private static final char[] INSTANCE_LOCK_NAME = "$lock".toCharArray(); private static final char[] STATIC_LOCK_NAME = "$LOCK".toCharArray(); diff --git a/src/core/lombok/eclipse/handlers/NonNullHandler.java b/src/core/lombok/eclipse/handlers/NonNullHandler.java deleted file mode 100644 index 59fda801..00000000 --- a/src/core/lombok/eclipse/handlers/NonNullHandler.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 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 - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.eclipse.handlers; - -import java.util.Arrays; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.Argument; -import org.eclipse.jdt.internal.compiler.ast.Block; -import org.eclipse.jdt.internal.compiler.ast.EqualExpression; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.IfStatement; -import org.eclipse.jdt.internal.compiler.ast.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; -import org.mangosdk.spi.ProviderFor; - -import lombok.NonNull; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.eclipse.DeferUntilPostDiet; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import static lombok.eclipse.Eclipse.*; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -@DeferUntilPostDiet -@ProviderFor(EclipseAnnotationHandler.class) -public class NonNullHandler extends EclipseAnnotationHandler { - @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { - if (annotationNode.up().getKind() == Kind.FIELD) { - // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), - // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to - // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning - // behaviour on _OUR_ 'lombok.NonNull'. - - try { - if (isPrimitive(((AbstractVariableDeclaration) annotationNode.up().get()).type)) { - annotationNode.addWarning("@NonNull is meaningless on a primitive."); - } - } catch (Exception ignore) {} - - return; - } - - if (annotationNode.up().getKind() != Kind.ARGUMENT) return; - - Argument arg; - AbstractMethodDeclaration declaration; - - try { - arg = (Argument) annotationNode.up().get(); - declaration = (AbstractMethodDeclaration) annotationNode.up().up().get(); - } catch (Exception e) { - return; - } - - if (isGenerated(declaration)) return; - - if (declaration.isAbstract()) { - 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and - // wrap all references to it in the super/this to a call to this method. - - Statement nullCheck = generateNullCheck(arg, ast); - - if (nullCheck == null) { - // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning. - annotationNode.addWarning("@NonNull is meaningless on a primitive."); - return; - } - - if (declaration.statements == null) { - declaration.statements = new Statement[] {nullCheck}; - } else { - char[] expectedName = arg.name; - for (Statement stat : declaration.statements) { - char[] varNameOfNullCheck = returnVarNameIfNullCheck(stat); - if (varNameOfNullCheck == null) break; - if (Arrays.equals(expectedName, varNameOfNullCheck)) return; - } - - Statement[] newStatements = new Statement[declaration.statements.length + 1]; - int skipOver = 0; - for (Statement stat : declaration.statements) { - if (isGenerated(stat)) skipOver++; - else break; - } - System.arraycopy(declaration.statements, 0, newStatements, 0, skipOver); - System.arraycopy(declaration.statements, skipOver, newStatements, skipOver + 1, declaration.statements.length - skipOver); - newStatements[skipOver] = nullCheck; - declaration.statements = newStatements; - } - annotationNode.up().up().rebuild(); - } - - private char[] returnVarNameIfNullCheck(Statement stat) { - if (!(stat instanceof IfStatement)) return null; - - /* Check that the if's statement is a throw statement, possibly in a block. */ { - Statement then = ((IfStatement) stat).thenStatement; - if (then instanceof Block) { - Statement[] blockStatements = ((Block) then).statements; - if (blockStatements == null || blockStatements.length == 0) return null; - then = blockStatements[0]; - } - - if (!(then instanceof ThrowStatement)) return null; - } - - /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate - a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { - Expression cond = ((IfStatement) stat).condition; - if (!(cond instanceof EqualExpression)) return null; - EqualExpression bin = (EqualExpression) cond; - int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT); - if (operatorId != OperatorIds.EQUAL_EQUAL) return null; - if (!(bin.left instanceof SingleNameReference)) return null; - if (!(bin.right instanceof NullLiteral)) return null; - return ((SingleNameReference) bin.left).token; - } - } -} diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java new file mode 100644 index 00000000..21611a39 --- /dev/null +++ b/src/core/lombok/javac/handlers/HandleNonNull.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac.handlers; + +import static lombok.javac.Javac.*; +import static lombok.javac.handlers.JavacHandlerUtil.*; + +import org.mangosdk.spi.ProviderFor; + +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCBinary; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCIf; +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) +@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. +public class HandleNonNull extends JavacAnnotationHandler { + @Override public void handle(AnnotationValues 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), + // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to + // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning + // behaviour on _OUR_ 'lombok.NonNull'. + + try { + if (isPrimitive(((JCVariableDecl) annotationNode.up().get()).vartype)) { + annotationNode.addWarning("@NonNull is meaningless on a primitive."); + } + } catch (Exception ignore) {} + + return; + } + + if (annotationNode.up().getKind() != Kind.ARGUMENT) return; + + JCMethodDecl declaration; + + try { + declaration = (JCMethodDecl) annotationNode.up().up().get(); + } catch (Exception e) { + 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and + // wrap all references to it in the super/this to a call to this method. + + JCStatement nullCheck = recursiveSetGeneratedBy(generateNullCheck(annotationNode.getTreeMaker(), annotationNode.up()), ast); + + if (nullCheck == null) { + // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning. + annotationNode.addWarning("@NonNull is meaningless on a primitive."); + return; + } + + List statements = declaration.body.stats; + + String expectedName = annotationNode.up().getName(); + + /* Abort if the null check is already there, delving into try and synchronized statements */ { + List 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 tail = statements; + List head = List.nil(); + for (JCStatement stat : statements) { + if (JavacHandlerUtil.isConstructorCall(stat) || (JavacHandlerUtil.isGenerated(stat) && isNullCheck(stat))) { + tail = tail.tail; + head = head.prepend(stat); + continue; + } + break; + } + + List newList = tail.prepend(nullCheck); + for (JCStatement stat : head) newList = newList.prepend(stat); + 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". + * If it is not of this form, returns null. + */ + private String returnVarNameIfNullCheck(JCStatement stat) { + if (!(stat instanceof JCIf)) return null; + + /* Check that the if's statement is a throw statement, possibly in a block. */ { + JCStatement then = ((JCIf) stat).thenpart; + if (then instanceof JCBlock) { + List stats = ((JCBlock) then).stats; + if (stats.length() == 0) return null; + then = stats.get(0); + } + if (!(then instanceof JCThrow)) return null; + } + + /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate + a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { + JCExpression cond = ((JCIf) stat).cond; + while (cond instanceof JCParens) cond = ((JCParens) cond).expr; + if (!(cond instanceof JCBinary)) return null; + JCBinary bin = (JCBinary) cond; + if (!CTC_EQUAL.equals(treeTag(bin))) return null; + if (!(bin.lhs instanceof JCIdent)) return null; + if (!(bin.rhs instanceof JCLiteral)) 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/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index 69d2b45d..b41277c3 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -29,6 +29,7 @@ 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; @@ -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 { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { deleteAnnotationIfNeccessary(annotationNode, SneakyThrows.class); diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index b173f8fb..661a7c2a 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -26,6 +26,7 @@ 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; @@ -46,6 +47,7 @@ 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 { private static final String INSTANCE_LOCK_NAME = "$lock"; private static final String STATIC_LOCK_NAME = "$LOCK"; diff --git a/src/core/lombok/javac/handlers/NonNullHandler.java b/src/core/lombok/javac/handlers/NonNullHandler.java deleted file mode 100644 index acf1588e..00000000 --- a/src/core/lombok/javac/handlers/NonNullHandler.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 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 - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.javac.handlers; - -import static lombok.javac.Javac.*; -import static lombok.javac.handlers.JavacHandlerUtil.*; - -import org.mangosdk.spi.ProviderFor; - -import com.sun.tools.javac.tree.JCTree.JCAnnotation; -import com.sun.tools.javac.tree.JCTree.JCBinary; -import com.sun.tools.javac.tree.JCTree.JCBlock; -import com.sun.tools.javac.tree.JCTree.JCExpression; -import com.sun.tools.javac.tree.JCTree.JCIdent; -import com.sun.tools.javac.tree.JCTree.JCIf; -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.JCThrow; -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.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 { - @Override public void handle(AnnotationValues 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), - // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to - // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning - // behaviour on _OUR_ 'lombok.NonNull'. - - try { - if (isPrimitive(((JCVariableDecl) annotationNode.up().get()).vartype)) { - annotationNode.addWarning("@NonNull is meaningless on a primitive."); - } - } catch (Exception ignore) {} - - return; - } - - if (annotationNode.up().getKind() != Kind.ARGUMENT) return; - - JCMethodDecl declaration; - - try { - declaration = (JCMethodDecl) annotationNode.up().up().get(); - } catch (Exception e) { - 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 lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and - // wrap all references to it in the super/this to a call to this method. - - JCStatement nullCheck = recursiveSetGeneratedBy(generateNullCheck(annotationNode.getTreeMaker(), annotationNode.up()), ast); - - if (nullCheck == null) { - // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning. - annotationNode.addWarning("@NonNull is meaningless on a primitive."); - return; - } - - List 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; - } - - List tail = statements; - List head = List.nil(); - for (JCStatement stat : statements) { - if (JavacHandlerUtil.isConstructorCall(stat) || JavacHandlerUtil.isGenerated(stat)) { - tail = tail.tail; - head = head.prepend(stat); - continue; - } - break; - } - - List newList = tail.prepend(nullCheck); - for (JCStatement stat : head) newList = newList.prepend(stat); - declaration.body.stats = newList; - } - - /** - * 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". - * If it is not of this form, returns null. - */ - private String returnVarNameIfNullCheck(JCStatement stat) { - if (!(stat instanceof JCIf)) return null; - - /* Check that the if's statement is a throw statement, possibly in a block. */ { - JCStatement then = ((JCIf) stat).thenpart; - if (then instanceof JCBlock) { - List stats = ((JCBlock) then).stats; - if (stats.length() == 0) return null; - then = stats.get(0); - } - if (!(then instanceof JCThrow)) return null; - } - - /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate - a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { - JCExpression cond = ((JCIf) stat).cond; - while (cond instanceof JCParens) cond = ((JCParens) cond).expr; - if (!(cond instanceof JCBinary)) return null; - JCBinary bin = (JCBinary) cond; - if (!CTC_EQUAL.equals(treeTag(bin))) return null; - if (!(bin.lhs instanceof JCIdent)) return null; - if (!(bin.rhs instanceof JCLiteral)) return null; - if (!CTC_BOT.equals(typeTag(bin.rhs))) return null; - return ((JCIdent) bin.lhs).name.toString(); - } - } -} diff --git a/test/transform/resource/after-delombok/NonNullWithSneakyThrows.java b/test/transform/resource/after-delombok/NonNullWithSneakyThrows.java new file mode 100644 index 00000000..91646468 --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullWithSneakyThrows.java @@ -0,0 +1,12 @@ +class NonNullWithSneakyThrows { + void test(@lombok.NonNull String in) { + try { + if (in == null) { + throw new java.lang.NullPointerException("in"); + } + System.out.println(in); + } catch (final java.lang.Throwable $ex) { + throw lombok.Lombok.sneakyThrow($ex); + } + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/InjectField.java b/test/transform/resource/after-ecj/InjectField.java index 83d9e5fa..f9ea9142 100644 --- a/test/transform/resource/after-ecj/InjectField.java +++ b/test/transform/resource/after-ecj/InjectField.java @@ -4,9 +4,9 @@ import lombok.Synchronized; @Log enum InjectField1 { A(), B(), + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(InjectField1.class.getName()); private final java.lang.Object $lock = new java.lang.Object[0]; private static final java.lang.Object $LOCK = new java.lang.Object[0]; - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(InjectField1.class.getName()); private static final String LOG_MESSAGE = "static initializer"; private String fieldA; static { @@ -32,8 +32,8 @@ import lombok.Synchronized; } } @Log class InjectField2 { - private final java.lang.Object $lock = new java.lang.Object[0]; private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(InjectField2.class.getName()); + private final java.lang.Object $lock = new java.lang.Object[0]; private static final String LOG_MESSAGE = "static initializer"; static { log.log(Level.FINE, LOG_MESSAGE); diff --git a/test/transform/resource/after-ecj/NonNullWithSneakyThrows.java b/test/transform/resource/after-ecj/NonNullWithSneakyThrows.java new file mode 100644 index 00000000..fac8dcdd --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullWithSneakyThrows.java @@ -0,0 +1,18 @@ +class NonNullWithSneakyThrows { + NonNullWithSneakyThrows() { + super(); + } + @lombok.SneakyThrows void test(@lombok.NonNull String in) { + try + { + if ((in == null)) + { + throw new java.lang.NullPointerException("in"); + } + System.out.println(in); + } + catch (final java.lang.Throwable $ex) { + throw lombok.Lombok.sneakyThrow($ex); + } + } +} \ No newline at end of file diff --git a/test/transform/resource/before/NonNullWithSneakyThrows.java b/test/transform/resource/before/NonNullWithSneakyThrows.java new file mode 100644 index 00000000..35f78a7f --- /dev/null +++ b/test/transform/resource/before/NonNullWithSneakyThrows.java @@ -0,0 +1,5 @@ +class NonNullWithSneakyThrows { + @lombok.SneakyThrows void test(@lombok.NonNull String in) { + System.out.println(in); + } +} -- cgit From e68c8d4fd4a0d6418b24cab4f4f8f3abaeca96fb Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 10 Oct 2013 20:11:18 +0200 Subject: pre-release version bump --- src/core/lombok/core/Version.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 318075d3..cfdcf575 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -28,8 +28,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "0.12.1"; - private static final String RELEASE_NAME = "Edgy Guinea Pig"; + private static final String VERSION = "1.12.2"; +// private static final String RELEASE_NAME = "Edgy Guinea Pig"; + private static final String RELEASE_NAME = "Angry Butterfly"; private Version() { //Prevent instantiation -- cgit From 601cd66babeaec0963b8cadf2190fd48708d0d33 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 10 Oct 2013 23:53:56 +0200 Subject: Post release version bump --- src/core/lombok/core/Version.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index cfdcf575..bf2e199b 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -28,9 +28,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.12.2"; -// private static final String RELEASE_NAME = "Edgy Guinea Pig"; - private static final String RELEASE_NAME = "Angry Butterfly"; + private static final String VERSION = "1.12.3"; + private static final String RELEASE_NAME = "Edgy Guinea Pig"; +// private static final String RELEASE_NAME = "Angry Butterfly"; private Version() { //Prevent instantiation -- cgit