/*
* 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.Field;
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.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;
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.TreeInfo;
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 TreeMaker getUnderlyingTreeMaker() {
return tm;
}
public JavacTreeMaker at(int pos) {
tm.at(pos);
return this;
}
private static class MethodId<J> {
private final Class<?> owner;
private final String name;
private final Class<J> returnType;
private final Class<?>[] paramTypes;
MethodId(Class<?> owner, String name, Class<J> returnType, Class<?>... types) {
this.owner = owner;
this.name = name;
this.paramTypes = types;
this.returnType = returnType;
}
@Override public String toString() {
StringBuilder out = new StringBuilder();
out.append(returnType.getName()).append(" ").append(owner.getName()).append(".").append(name).append("(");
boolean f = true;
for (Class<?> p : paramTypes) {
if (f) f = false;
else out.append(", ");
out.append(p.getName());
}
return out.append(")").toString();
}
}
private static class SchroedingerType {
final Object value;
private SchroedingerType(Object value) {
this.value = value;
}
@Override public int hashCode() {
return value == null ? -1 : value.hashCode();
}
@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<String, Object> 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 Field NOSUCHFIELDEX_MARKER;
static {
try {
NOSUCHFIELDEX_MARKER = SchroedingerType.class.getDeclaredField("NOSUCHFIELDEX_MARKER");
} catch (NoSuchFieldException e) {
throw Javac.sneakyThrow(e);
}
}
static Object getFieldCached(ConcurrentMap<Class<?>, Field> cache, Object ref, String fieldName) throws NoSuchFieldException {
Class<?> c = ref.getClass();
Field field = cache.get(c);
if (field == null) {
try {
field = c.getField(fieldName);
} catch (NoSuchFieldException e) {
cache.putIfAbsent(c, NOSUCHFIELDEX_MARKER);
throw Javac.sneakyThrow(e);
}
field.setAccessible(true);
Field old = cache.putIfAbsent(c, field);
if (old != null) field = old;
}
if (field == NOSUCHFIELDEX_MARKER) throw new NoSuchFieldException(fieldName);
try {
return field.get(ref);
} catch (IllegalAccessException e) {
throw Javac.sneakyThrow(e);
}
}
}
public static class TypeTag extends SchroedingerType {
private static final ConcurrentMap<String, Object> TYPE_TAG_CACHE = new ConcurrentHashMap<String, Object>();
private static final ConcurrentMap<Class<?>, Field> FIELD_CACHE = new ConcurrentHashMap<Class<?>, Field>();
private static final Method TYPE_TYPETAG_METHOD;
static {
Method m = null;
try {
m = Type.class.getDeclaredMethod("getTag");
m.setAccessible(true);
} catch (NoSuchMethodException e) {}
TYPE_TYPETAG_METHOD = m;
}
private TypeTag(Object value) {
super(value);
}
public static TypeTag typeTag(JCTree o) {
try {
return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag"));
} catch (NoSuchFieldException e) {
throw Javac.sneakyThrow(e);
}
}
public static TypeTag typeTag(Type t) {
try {
return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag"));
} catch (NoSuchFieldException e) {
if (TYPE_TYPETAG_METHOD == null) throw new IllegalStateException("Type " + t.getClass() + " has neither 'tag' nor getTag()");
try {
return new TypeTag(TYPE_TYPETAG_METHOD.invoke(t));
} catch (IllegalAccessException ex) {
throw Javac.sneakyThrow(ex);
} catch (InvocationTargetException ex) {
throw Javac.sneakyThrow(ex.getCause());
}
}
}
public static TypeTag typeTag(String identifier) {
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 extends SchroedingerType {
private static final ConcurrentMap<String, Object> TREE_TAG_CACHE = new ConcurrentHashMap<String, Object>();
private static final Field TAG_FIELD;
private static final Method TAG_METHOD;
private static final MethodId<Integer> 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) {
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 <J> MethodId<J> MethodId(Class<?> owner, String name, Class<J> returnType, Class<?>... types) {
return new MethodId<J>(owner, name, returnType, types);
}
/**
* 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 <J> MethodId<J> MethodId(String name, Class<J> returnType, Class<?>... types) {
return new MethodId<J>(TreeMaker.class, 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 <J> MethodId<J> MethodId(String name) {
for (Method m : JavacTreeMaker.class.getDeclaredMethods()) {
if (m.getName().equals(name)) {
@SuppressWarnings("unchecked") Class<J> r = (Class<J>) m.getReturnType();
Class<?>[] p = m.getParameterTypes();
return new MethodId<J>(TreeMaker.class, name, r, p);
}
}
throw new InternalError("Not found: " + name);
}
private static final ConcurrentHashMap<MethodId<?>, Method> METHOD_CACHE = new ConcurrentHashMap<MethodId<?>, Method>();
private <J> J invoke(MethodId<J> m, Object... args) {
return invokeAny(tm, m, args);
}
@SuppressWarnings("unchecked") private static <J> J invokeAny(Object owner, MethodId<J> m, Object... args) {
Method method = METHOD_CACHE.get(m);
if (method == null) method = addToCache(m);
try {
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);
}
}
private static Method addToCache(MethodId<?> m) {
Method found = null;
outer:
for (Method method : m.owner.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 frontend 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<JCCompilationUnit> TopLevel = MethodId("TopLevel");
public JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations, JCExpression pid, List<JCTree> defs) {
return invoke(TopLevel, packageAnnotations, pid, defs);
}
//javac versions: 6-8
private static final MethodId<JCImport> Import = MethodId("Import");
public JCImport Import(JCTree qualid, boolean staticImport) {
return invoke(Import, qualid, staticImport);
}
//javac versions: 6-8
private static final MethodId<JCClassDecl> ClassDef = MethodId("ClassDef");
public JCClassDecl ClassDef(JCModifiers mods, Name name, List<JCTypeParameter> typarams, JCExpression extending, List<JCExpression> implementing, List<JCTree> defs) {
return invoke(ClassDef, mods, name, typarams, extending, implementing, defs);
}
//javac versions: 6-8
private static final MethodId<JCMethodDecl> 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<JCTypeParameter> typarams, List<JCVariableDecl> params, List<JCExpression> thrown, JCBlock body, JCExpression defaultValue) {
return invoke(MethodDef, mods, name, resType, typarams, params, thrown, body, defaultValue);
}
//javac versions: 8
private static final MethodId<JCMethodDecl> 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<JCTypeParameter> typarams, JCVariableDecl recvparam, List<JCVariableDecl> params, List<JCExpression> 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<JCVariableDecl> 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<JCVariableDecl> 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<JCSkip> Skip = MethodId("Skip");
public JCSkip Skip() {
return invoke(Skip);
}
//javac versions: 6-8
private static final MethodId<JCBlock> Block = MethodId("Block");
public JCBlock Block(long flags, List<JCStatement> stats) {
return invoke(Block, flags, stats);
}
//javac versions: 6-8
private static final MethodId<JCDoWhileLoop> DoLoop = MethodId("DoLoop");
public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
return invoke(DoLoop, body, cond);
}
//javac versions: 6-8
private static final MethodId<JCWhileLoop> WhileLoop = MethodId("WhileLoop");
public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
return invoke(WhileLoop, cond, body);
}
//javac versions: 6-8
private static final MethodId<JCForLoop> ForLoop = MethodId("ForLoop");
public JCForLoop ForLoop(List<JCStatement> init, JCExpression cond, List<JCExpressionStatement> step, JCStatement body) {
return invoke(ForLoop, init, cond, step, body);
}
//javac versions: 6-8
private static final MethodId<JCEnhancedForLoop> 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<JCLabeledStatement> Labelled = MethodId("Labelled");
public JCLabeledStatement Labelled(Name label, JCStatement body) {
return invoke(Labelled, label, body);
}
//javac versions: 6-8
private static final MethodId<JCSwitch> Switch = MethodId("Switch");
public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
return invoke(Switch, selector, cases);
}
//javac versions: 6-8
private static final MethodId<JCCase> Case = MethodId("Case");
public JCCase Case(JCExpression pat, List<JCStatement> stats) {
return invoke(Case, pat, stats);
}
//javac versions: 6-8
private static final MethodId<JCSynchronized> Synchronized = MethodId("Synchronized");
public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
return invoke(Synchronized, lock, body);
}
//javac versions: 6-8
private static final MethodId<JCTry> Try = MethodId("Try", JCTry.class, JCBlock.class, List.class, JCBlock.class);
public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
return invoke(Try, body, catchers, finalizer);
}
//javac versions: 7-8
private static final MethodId<JCTry> TryWithResources = MethodId("Try", JCTry.class, List.class, JCBlock.class, List.class, JCBlock.class);
public JCTry Try(List<JCTree> resources, JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
return invoke(TryWithResources, resources, body, catchers, finalizer);
}
//javac versions: 6-8
private static final MethodId<JCCatch> Catch = MethodId("Catch");
public JCCatch Catch(JCVariableDecl param, JCBlock body) {
return invoke(Catch, param, body);
}
//javac versions: 6-8
private static final MethodId<JCConditional> 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<JCIf> 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<JCExpressionStatement> Exec = MethodId("Exec");
public JCExpressionStatement Exec(JCExpression expr) {
return invoke(Exec, expr);
}
//javac versions: 6-8
private static final MethodId<JCBreak> Break = MethodId("Break");
public JCBreak Break(Name label) {
return invoke(Break, label);
}
//javac versions: 6-8
private static final MethodId<JCContinue> Continue = MethodId("Continue");
public JCContinue Continue(Name label) {
return invoke(Continue, label);
}
//javac versions: 6-8
private static final MethodId<JCReturn> Return = MethodId("Return");
public JCReturn Return(JCExpression expr) {
return invoke(Return, expr);
}
//javac versions: 6-8
private static final MethodId<JCThrow> Throw = MethodId("Throw");
public JCThrow Throw(JCExpression expr) {
return invoke(Throw, expr);
}
//javac versions: 6-8
private static final MethodId<JCAssert> Assert = MethodId("Assert");
public JCAssert Assert(JCExpression cond, JCExpression detail) {
return invoke(Assert, cond, detail);
}
//javac versions: 6-8
private static final MethodId<JCMethodInvocation> Apply = MethodId("Apply");
public JCMethodInvocation Apply(List<JCExpression> typeargs, JCExpression fn, List<JCExpression> args) {
return invoke(Apply, typeargs, fn, args);
}
//javac versions: 6-8
private static final MethodId<JCNewClass> NewClass = MethodId("NewClass");
public JCNewClass NewClass(JCExpression encl, List<JCExpression> typeargs, JCExpression clazz, List<JCExpression> args, JCClassDecl def) {
return invoke(NewClass, encl, typeargs, clazz, args, def);
}
//javac versions: 6-8
private static final MethodId<JCNewArray> NewArray = MethodId("NewArray");
public JCNewArray NewArray(JCExpression elemtype, List<JCExpression> dims, List<JCExpression> elems) {
return invoke(NewArray, elemtype, dims, elems);
}
//javac versions: 8
// private static final MethodId<JCLambda> Lambda = MethodId("Lambda");
// public JCLambda Lambda(List<JCVariableDecl> params, JCTree body) {
// return invoke(Lambda, params, body);
// }
//javac versions: 6-8
private static final MethodId<JCParens> Parens = MethodId("Parens");
public JCParens Parens(JCExpression expr) {
return invoke(Parens, expr);
}
//javac versions: 6-8
private static final MethodId<JCAssign> 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<JCAssignOp> 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<JCUnary> 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<JCBinary> 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<JCTypeCast> TypeCast = MethodId("TypeCast");
public JCTypeCast TypeCast(JCTree expr, JCExpression type) {
return invoke(TypeCast, expr, type);
}
//javac versions: 6-8
private static final MethodId<JCInstanceOf> TypeTest = MethodId("TypeTest");
public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
return invoke(TypeTest, expr, clazz);
}
//javac versions: 6-8
private static final MethodId<JCArrayAccess> Indexed = MethodId("Indexed");
public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
return invoke(Indexed, indexed, index);
}
//javac versions: 6-8
private static final MethodId<JCFieldAccess> Select = MethodId("Select");
public JCFieldAccess Select(JCExpression selected, Name selector) {
return invoke(Select, selected, selector);
}
//javac versions: 8
// private static final MethodId<JCMemberReference> Reference = MethodId("Reference");
// public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) {
// return invoke(Reference, mode, name, expr, typeargs);
// }
//javac versions: 6-8
private static final MethodId<JCIdent> 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<JCLiteral> 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<JCPrimitiveTypeTree> TypeIdent = MethodId("TypeIdent");
public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) {
return invoke(TypeIdent, typetag.value);
}
//javac versions: 6-8
private static final MethodId<JCArrayTypeTree> TypeArray = MethodId("TypeArray");
public JCArrayTypeTree TypeArray(JCExpression elemtype) {
return invoke(TypeArray, elemtype);
}
//javac versions: 6-8
private static final MethodId<JCTypeApply> TypeApply = MethodId("TypeApply");
public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
return invoke(TypeApply, clazz, arguments);
}
//javac versions: 7-8
// private static final MethodId<JCTypeUnion> TypeUnion = MethodId("TypeUnion");
// public JCTypeUnion TypeUnion(List<JCExpression> components) {
// return invoke(TypeUnion, compoonents);
// }
//javac versions: 8
// private static final MethodId<JCTypeIntersection> TypeIntersection = MethodId("TypeIntersection");
// public JCTypeIntersection TypeIntersection(List<JCExpression> components) {
// return invoke(TypeIntersection, components);
// }
//javac versions: 6-8
private static final MethodId<JCTypeParameter> TypeParameter = MethodId("TypeParameter", JCTypeParameter.class, Name.class, List.class);
public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
return invoke(TypeParameter, name, bounds);
}
//javac versions: 8
private static final MethodId<JCTypeParameter> TypeParameterWithAnnos = MethodId("TypeParameter", JCTypeParameter.class, Name.class, List.class, List.class);
public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) {
return invoke(TypeParameterWithAnnos, name, bounds, annos);
}
//javac versions: 6-8
private static final MethodId<JCWildcard> Wildcard = MethodId("Wildcard");
public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
return invoke(Wildcard, kind, type);
}
//javac versions: 6-8
private static final MethodId<TypeBoundKind> TypeBoundKind = MethodId("TypeBoundKind");
public TypeBoundKind TypeBoundKind(BoundKind kind) {
return invoke(TypeBoundKind, kind);
}
//javac versions: 6-8
private static final MethodId<JCAnnotation> Annotation = MethodId("Annotation", JCAnnotation.class, JCTree.class, List.class);
public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
return invoke(Annotation, annotationType, args);
}
//javac versions: 8
private static final MethodId<JCAnnotation> TypeAnnotation = MethodId("TypeAnnotation", JCAnnotation.class, JCTree.class, List.class);
public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
return invoke(TypeAnnotation, annotationType, args);
}
//javac versions: 6-8
private static final MethodId<JCModifiers> ModifiersWithAnnotations = MethodId("Modifiers", JCModifiers.class, long.class, List.class);
public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
return invoke(ModifiersWithAnnotations, flags, annotations);
}
//javac versions: 6-8
private static final MethodId<JCModifiers> Modifiers = MethodId("Modifiers", JCModifiers.class, long.class);
public JCModifiers Modifiers(long flags) {
return invoke(Modifiers, flags);
}
//javac versions: 8
// private static final MethodId<JCAnnotatedType> AnnotatedType = MethodId("AnnotatedType");
// public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
// return invoke(AnnotatedType, annotations, underlyingType);
// }
//javac versions: 6-8
private static final MethodId<JCErroneous> Erroneous = MethodId("Erroneous", JCErroneous.class);
public JCErroneous Erroneous() {
return invoke(Erroneous);
}
//javac versions: 6-8
private static final MethodId<JCErroneous> ErroneousWithErrs = MethodId("Erroneous", JCErroneous.class, List.class);
public JCErroneous Erroneous(List<? extends JCTree> errs) {
return invoke(ErroneousWithErrs, errs);
}
//javac versions: 6-8
private static final MethodId<LetExpr> LetExpr = MethodId("LetExpr", LetExpr.class, List.class, JCTree.class);
public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
return invoke(LetExpr, defs, expr);
}
//javac versions: 6-8
private static final MethodId<JCClassDecl> AnonymousClassDef = MethodId("AnonymousClassDef");
public JCClassDecl AnonymousClassDef(JCModifiers mods, List<JCTree> defs) {
return invoke(AnonymousClassDef, mods, defs);
}
//javac versions: 6-8
private static final MethodId<LetExpr> 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<JCIdent> IdentVarDecl = MethodId("Ident", JCIdent.class, JCVariableDecl.class);
public JCExpression Ident(JCVariableDecl param) {
return invoke(IdentVarDecl, param);
}
//javac versions: 6-8
private static final MethodId<List<JCExpression>> Idents = MethodId("Idents");
public List<JCExpression> Idents(List<JCVariableDecl> params) {
return invoke(Idents, params);
}
//javac versions: 6-8
private static final MethodId<JCMethodInvocation> App2 = MethodId("App", JCMethodInvocation.class, JCExpression.class, List.class);
public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
return invoke(App2, meth, args);
}
//javac versions: 6-8
private static final MethodId<JCMethodInvocation> App1 = MethodId("App", JCMethodInvocation.class, JCExpression.class);
public JCMethodInvocation App(JCExpression meth) {
return invoke(App1, meth);
}
//javac versions: 6-8
private static final MethodId<List<JCAnnotation>> Annotations = MethodId("Annotations");
public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
return invoke(Annotations, attributes);
}
//javac versions: 6-8
private static final MethodId<JCLiteral> LiteralWithValue = MethodId("Literal", JCLiteral.class, Object.class);
public JCLiteral Literal(Object value) {
return invoke(LiteralWithValue, value);
}
//javac versions: 6-8
private static final MethodId<JCAnnotation> AnnotationWithAttributeOnly = MethodId("Annotation", JCAnnotation.class, Attribute.class);
public JCAnnotation Annotation(Attribute a) {
return invoke(AnnotationWithAttributeOnly, a);
}
//javac versions: 8
private static final MethodId<JCAnnotation> TypeAnnotationWithAttributeOnly = MethodId("TypeAnnotation", JCAnnotation.class, Attribute.class);
public JCAnnotation TypeAnnotation(Attribute a) {
return invoke(TypeAnnotationWithAttributeOnly, a);
}
//javac versions: 6-8
private static final MethodId<JCStatement> Call = MethodId("Call");
public JCStatement Call(JCExpression apply) {
return invoke(Call, apply);
}
//javac versions: 6-8
private static final MethodId<JCExpression> Type = MethodId("Type");
public JCExpression Type(Type type) {
return invoke(Type, type);
}
}