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/utils/lombok/javac/Javac.java | 237 ++++++++++++++++++++++++++++++++------ 1 file changed, 202 insertions(+), 35 deletions(-) (limited to 'src/utils/lombok/javac/Javac.java') 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 172202add2d0cb63e5b0780e7e3fc6000e43a3d9 Mon Sep 17 00:00:00 2001 From: Robbert Jan Grootjans Date: Fri, 5 Apr 2013 14:37:11 +0200 Subject: Some small fixes for Java 7 --- .../lombok/delombok/PrettyCommentsPrinter.java | 4 ++-- src/utils/lombok/javac/Javac.java | 22 +++++++++------------- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'src/utils/lombok/javac/Javac.java') diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index d0f38a62..745aea79 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -1281,9 +1281,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { 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)); + 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(tree, getTag(tree)); + return (Integer)TreeInfo.class.getMethod("opPrec", Integer.TYPE).invoke(null, getTag(tree)); } } catch (NoSuchMethodException e) { throw new RuntimeException(e); diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index cbbd6730..b766630f 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -22,6 +22,7 @@ package lombok.javac; import java.lang.reflect.Method; +import java.util.Objects; import java.util.regex.Pattern; import com.sun.tools.javac.main.JavaCompiler; @@ -31,6 +32,7 @@ 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.tree.JCTree.JCUnary; import com.sun.tools.javac.tree.TreeMaker; @@ -137,7 +139,7 @@ public class Javac { public static boolean compareCTC(Object ctc1, Object ctc2) { - return ctc1.equals(ctc2); + return Objects.equals(ctc1, ctc2); } /** @@ -187,20 +189,14 @@ public class Javac { } } - - 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 Object getTreeTypeTag(JCPrimitiveTypeTree tree) { + return tree.typetag; } + public static Object getTreeTypeTag(JCLiteral tree) { + return tree.typetag; + } + public static JCExpression makeTypeIdent(TreeMaker maker, Object ctc) { try { Method createIdent; -- cgit From 4c03e3d220900431085897878d4888bf530b31ec Mon Sep 17 00:00:00 2001 From: Robbert Jan Grootjans Date: Fri, 5 Apr 2013 17:28:44 +0200 Subject: Type fixes for JDK7 --- .../lombok/delombok/PrettyCommentsPrinter.java | 18 +++++------ src/utils/lombok/javac/JCNoTypeFactory.java | 11 +++++++ src/utils/lombok/javac/Javac.java | 37 ---------------------- 3 files changed, 20 insertions(+), 46 deletions(-) create mode 100644 src/utils/lombok/javac/JCNoTypeFactory.java (limited to 'src/utils/lombok/javac/Javac.java') diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 745aea79..9817f050 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -602,7 +602,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { /** Is the given tree an enumerator definition? */ boolean isEnumerator(JCTree t) { - return getTag(t) == VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0; + return Javac.compareCTC(getTag(t), VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0; } /** Print unit consisting of package clause and import statements in toplevel, @@ -626,7 +626,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { for (List l = tree.defs; l.nonEmpty() && (cdef == null || getTag(l.head) == IMPORT); l = l.tail) { - if (getTag(l.head) == IMPORT) { + if (Javac.compareCTC(getTag(l.head), IMPORT)) { JCImport imp = (JCImport)l.head; Name name = TreeInfo.name(imp.qualid); if (name == name.table.fromChars(new char[] {'*'}, 0, 1) || @@ -845,7 +845,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { printStat(tree.body); align(); print(" while "); - if (getTag(tree.cond) == PARENS) { + if (Javac.compareCTC(getTag(tree.cond), PARENS)) { printExpr(tree.cond); } else { print("("); @@ -861,7 +861,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitWhileLoop(JCWhileLoop tree) { try { print("while "); - if (getTag(tree.cond) == PARENS) { + if (Javac.compareCTC(getTag(tree.cond), PARENS)) { printExpr(tree.cond); } else { print("("); @@ -879,7 +879,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { try { print("for ("); if (tree.init.nonEmpty()) { - if (getTag(tree.init.head) == VARDEF) { + if (Javac.compareCTC(getTag(tree.init.head), VARDEF)) { printExpr(tree.init.head); for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) { JCVariableDecl vdef = (JCVariableDecl)l.head; @@ -926,7 +926,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitSwitch(JCSwitch tree) { try { print("switch "); - if (getTag(tree.selector) == PARENS) { + if (Javac.compareCTC(getTag(tree.selector), PARENS)) { printExpr(tree.selector); } else { print("("); @@ -965,7 +965,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitSynchronized(JCSynchronized tree) { try { print("synchronized "); - if (getTag(tree.lock) == PARENS) { + if (Javac.compareCTC(getTag(tree.lock), PARENS)) { printExpr(tree.lock); } else { print("("); @@ -1023,7 +1023,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitIf(JCIf tree) { try { print("if "); - if (getTag(tree.cond) == PARENS) { + if (Javac.compareCTC(getTag(tree.cond), PARENS)) { printExpr(tree.cond); } else { print("("); @@ -1119,7 +1119,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitApply(JCMethodInvocation tree) { try { if (!tree.typeargs.isEmpty()) { - if (getTag(tree.meth) == SELECT) { + if (Javac.compareCTC(getTag(tree.meth), SELECT)) { JCFieldAccess left = (JCFieldAccess)tree.meth; printExpr(left.selected); print(".<"); diff --git a/src/utils/lombok/javac/JCNoTypeFactory.java b/src/utils/lombok/javac/JCNoTypeFactory.java new file mode 100644 index 00000000..e7be7665 --- /dev/null +++ b/src/utils/lombok/javac/JCNoTypeFactory.java @@ -0,0 +1,11 @@ +package lombok.javac; + +import com.sun.tools.javac.code.Symbol.TypeSymbol; +import com.sun.tools.javac.code.Type; + + +public class JCNoTypeFactory { + public static final Type getJCNotType(Object typeTag, TypeSymbol tsym) { + + } +} diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index b766630f..9f2936a8 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -26,7 +26,6 @@ import java.util.Objects; import java.util.regex.Pattern; 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; @@ -102,42 +101,6 @@ public class Javac { 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 Objects.equals(ctc1, ctc2); } -- 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/utils/lombok/javac/Javac.java') 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/utils/lombok/javac/Javac.java') 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/utils/lombok/javac/Javac.java') 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 3619f889f5088ccb08245c2c3d7bc6e4459337d5 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 5 Aug 2013 22:07:45 +0200 Subject: To quote Reinier paraphrasing the compiler: "If the loading doesn't work, I don't want it!" --- src/utils/lombok/javac/Javac.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/utils/lombok/javac/Javac.java') diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 014007d4..c90b8611 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -213,12 +213,12 @@ public class Javac { Class c = null; try { c = Class.forName("com.sun.tools.javac.code.Type$JCVoidType"); - } catch (Exception ignore) {} + } catch (Throwable ignore) {} JC_VOID_TYPE = c; c = null; try { c = Class.forName("com.sun.tools.javac.code.Type$JCNoType"); - } catch (Exception ignore) {} + } catch (Throwable ignore) {} JC_NO_TYPE = c; } -- cgit From 6a02cb40137788e6f77919c762b72b3d5880d2da Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 9 Sep 2013 23:54:28 +0200 Subject: [jdk8support] We now handle doc comments internally, alleviating the need to try and keep up with the complete rewrites of the doc comment parser from java6 to java7 to java8. Still doesn't actually work in jdk8, but only because of a last-mile issue. (we communicate the doc comment via compilationUnit.docComments but that changed types in jdk8, we just need to make a wrapper to make that work). --- src/delombok/lombok/delombok/Delombok.java | 4 + .../lombok/delombok/DocCommentIntegrator.java | 97 ++++++++++++++++++++++ .../lombok/delombok/PrettyCommentsPrinter.java | 42 ++-------- src/utils/lombok/javac/CommentCatcher.java | 13 ++- src/utils/lombok/javac/Javac.java | 11 +++ .../after-delombok/GetterSetterJavadoc.java | 12 +-- .../resource/before/GetterSetterJavadoc.java | 12 +-- 7 files changed, 143 insertions(+), 48 deletions(-) create mode 100644 src/delombok/lombok/delombok/DocCommentIntegrator.java (limited to 'src/utils/lombok/javac/Javac.java') diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 1fae4560..0128e44f 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -383,6 +383,10 @@ public class Delombok { return false; } + for (JCCompilationUnit unit : roots) { + catcher.setComments(unit, new DocCommentIntegrator().integrate(catcher.getComments(unit), unit)); + } + com.sun.tools.javac.util.List trees = compiler.enterTrees(toJavacList(roots)); JavaCompiler delegate = compiler.processAnnotations(trees); diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java new file mode 100644 index 00000000..80aec16a --- /dev/null +++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java @@ -0,0 +1,97 @@ +package lombok.delombok; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import lombok.javac.CommentInfo; +import lombok.javac.Javac; + +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; + +public class DocCommentIntegrator { + /** + * Returns the same comment list as when this integrator was created, minus all doc comments that have been successfully integrated into the compilation unit. + */ + public List integrate(List comments, JCCompilationUnit unit) { + List out = new ArrayList(); + CommentInfo lastExcisedComment = null; + JCTree lastNode = null; + + for (CommentInfo cmt : comments) { + if (!cmt.isJavadoc()) { + out.add(cmt); + continue; + } + + JCTree node = findJavadocableNodeOnOrAfter(unit, cmt.endPos); + if (node == null) { + out.add(cmt); + continue; + } + + if (node == lastNode) { + out.add(lastExcisedComment); + } + if (!attach(unit, node, cmt)) { + out.add(cmt); + } else { + lastNode = node; + lastExcisedComment = cmt; + } + } + return out; + } + + private static final Pattern CONTENT_STRIPPER = Pattern.compile("^(?:\\s*\\*)?[ \\t]*(.*?)$", Pattern.MULTILINE); + @SuppressWarnings("unchecked") private boolean attach(JCCompilationUnit top, 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); + docCommentContent = CONTENT_STRIPPER.matcher(docCommentContent).replaceAll("$1"); + docCommentContent = docCommentContent.trim(); + + if (Javac.getDocComments(top) == null) Javac.initDocComments(top); + + Object map_ = Javac.getDocComments(top); + if (map_ instanceof Map) { + ((Map) map_).put(node, docCommentContent); + return true; + } + + return false; + } + + private JCTree findJavadocableNodeOnOrAfter(JCCompilationUnit unit, int endPos) { + if (unit.pid != null && endPos <= unit.pid.pos) return null; + Iterator it = unit.defs.iterator(); + + while (it.hasNext()) { + JCTree node = it.next(); + if (node.pos < endPos) { + if (node instanceof JCClassDecl) { + com.sun.tools.javac.util.List defs = ((JCClassDecl) node).defs; + if (!defs.isEmpty()) while (!defs.tail.isEmpty()) defs = defs.tail; + if (defs.head != null && defs.head.pos >= endPos) { + // The associated node is IN this class declaration, so, replace the iterator. + // There's no point looking beyond this member in the current iteration 'context' + // so we don't need to save the old ref. Just start over inside this type declaration. + it = ((JCClassDecl) node).defs.iterator(); + } + } + continue; + } + + if (node instanceof JCMethodDecl || node instanceof JCClassDecl || node instanceof JCVariableDecl) return node; + return null; + } + + return null; + } +} diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 9978a681..525773f4 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -29,18 +29,14 @@ */ package lombok.delombok; -import static com.sun.tools.javac.code.Flags.ANNOTATION; -import static com.sun.tools.javac.code.Flags.ENUM; -import static com.sun.tools.javac.code.Flags.INTERFACE; -import static com.sun.tools.javac.code.Flags.SYNTHETIC; -import static com.sun.tools.javac.code.Flags.StandardFlags; -import static com.sun.tools.javac.code.Flags.VARARGS; +import static com.sun.tools.javac.code.Flags.*; +import static lombok.javac.Javac.*; +import static lombok.javac.JavacTreeMaker.TreeTag.treeTag; +import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -49,19 +45,11 @@ 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; 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.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeInfo; -import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCArrayAccess; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; @@ -113,10 +101,13 @@ 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.TreeScanner; import com.sun.tools.javac.util.Convert; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Position; +//import com.sun.tools.javac.code.TypeTags; /** Prints out a tree as an indented Java source program. * @@ -198,13 +189,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { 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); - } + printComment(head); comments = comments.tail; head = comments.head; } @@ -213,17 +198,6 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - 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; - } - private void consumeTrailingComments(int from) throws IOException { boolean prevNewLine = onNewLine; CommentInfo head = comments.head; diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java index 48dd7e75..36d90e30 100644 --- a/src/utils/lombok/javac/CommentCatcher.java +++ b/src/utils/lombok/javac/CommentCatcher.java @@ -22,13 +22,14 @@ package lombok.javac; import java.lang.reflect.InvocationTargetException; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.WeakHashMap; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.List; public class CommentCatcher { private final JavaCompiler compiler; @@ -56,9 +57,17 @@ public class CommentCatcher { return compiler; } + public void setComments(JCCompilationUnit ast, List comments) { + if (comments != null) { + commentsMap.put(ast, comments); + } else { + commentsMap.remove(ast); + } + } + public List getComments(JCCompilationUnit ast) { List list = commentsMap.get(ast); - return list == null ? List.nil() : list; + return list == null ? Collections.emptyList() : list; } private static void registerCommentsCollectingScannerFactory(Context context) { diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index c90b8611..2f3c9be4 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -27,6 +27,7 @@ import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -196,6 +197,16 @@ public class Javac { } } + public static void initDocComments(JCCompilationUnit cu) { + try { + JCCOMPILATIONUNIT_DOCCOMMENTS.set(cu, new HashMap()); + } catch (IllegalArgumentException e) { + // That's fine - we're on JDK8, we'll fix that later. + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } + } + public static int getEndPosition(DiagnosticPosition pos, JCCompilationUnit top) { try { Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top); diff --git a/test/transform/resource/after-delombok/GetterSetterJavadoc.java b/test/transform/resource/after-delombok/GetterSetterJavadoc.java index 7bf92d1f..af9cbb5e 100644 --- a/test/transform/resource/after-delombok/GetterSetterJavadoc.java +++ b/test/transform/resource/after-delombok/GetterSetterJavadoc.java @@ -9,7 +9,7 @@ class GetterSetterJavadoc1 { /** * Getter section * - * @return Sky is blue + * @return Sky is blue1 */ @java.lang.SuppressWarnings("all") public int getFieldName() { @@ -18,7 +18,7 @@ class GetterSetterJavadoc1 { /** * Some text * - * @param fieldName Hello, World + * @param fieldName Hello, World1 */ @java.lang.SuppressWarnings("all") public void setFieldName(final int fieldName) { @@ -60,7 +60,7 @@ class GetterSetterJavadoc2 { /** * Some text * - * @return Sky is blue + * @return Sky is blue2 */ @java.lang.SuppressWarnings("all") public int getFieldName() { @@ -69,7 +69,7 @@ class GetterSetterJavadoc2 { /** * Some text * - * @param fieldName Hello, World + * @param fieldName Hello, World2 */ @java.lang.SuppressWarnings("all") public void setFieldName(final int fieldName) { @@ -83,7 +83,7 @@ class GetterSetterJavadoc3 { private int fieldName; /** * Getter section - * @return Sky is blue + * @return Sky is blue3 */ @java.lang.SuppressWarnings("all") public int getFieldName() { @@ -91,7 +91,7 @@ class GetterSetterJavadoc3 { } /** * Setter section - * @param fieldName Hello, World + * @param fieldName Hello, World3 */ @java.lang.SuppressWarnings("all") public void setFieldName(final int fieldName) { diff --git a/test/transform/resource/before/GetterSetterJavadoc.java b/test/transform/resource/before/GetterSetterJavadoc.java index e3ae0aac..0dc64092 100644 --- a/test/transform/resource/before/GetterSetterJavadoc.java +++ b/test/transform/resource/before/GetterSetterJavadoc.java @@ -3,11 +3,11 @@ class GetterSetterJavadoc1 { /** * Some text * - * @param fieldName Hello, World + * @param fieldName Hello, World1 * --- GETTER --- * Getter section * - * @return Sky is blue + * @return Sky is blue1 */ private int fieldName; } @@ -16,8 +16,8 @@ class GetterSetterJavadoc2 { /** * Some text * - * @param fieldName Hello, World - * @return Sky is blue + * @param fieldName Hello, World2 + * @return Sky is blue2 */ @lombok.Getter @lombok.Setter private int fieldName; } @@ -28,10 +28,10 @@ class GetterSetterJavadoc3 { * * **SETTER** * Setter section - * @param fieldName Hello, World + * @param fieldName Hello, World3 * **GETTER** * Getter section - * @return Sky is blue + * @return Sky is blue3 */ @lombok.Getter @lombok.Setter private int fieldName; } -- 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/utils/lombok/javac/Javac.java') 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 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/utils/lombok/javac/Javac.java') 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