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/utils/lombok/javac/Javac.java | 231 ++-------- src/utils/lombok/javac/JavacTreeMaker.java | 662 +++++++++++++++++++++++++++++ 2 files changed, 704 insertions(+), 189 deletions(-) create mode 100644 src/utils/lombok/javac/JavacTreeMaker.java (limited to 'src/utils/lombok') 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