aboutsummaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/lombok/javac/Javac.java86
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java178
-rw-r--r--src/utils/lombok/javac/TreeMirrorMaker.java5
3 files changed, 158 insertions, 111 deletions
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,29 +258,10 @@ 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) {}
JCCOMPILATIONUNIT_ENDPOSITIONS = f;
@@ -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<J> {
+ private final Class<?> owner;
private final String name;
private final Class<J> returnType;
private final Class<?>[] paramTypes;
- MethodId(String name, Class<J> returnType, Class<?>... types) {
+ MethodId(Class<?> owner, String name, Class<J> returnType, Class<?>... types) {
+ this.owner = owner;
this.name = name;
this.paramTypes = types;
this.returnType = returnType;
}
-
}
- private 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);
+ 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<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;
+ }
+
+ static Object getFieldCached(ConcurrentMap<Class<?>, 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<String, Object> TYPE_TAG_CACHE = new ConcurrentHashMap<String, Object>();
- public final Object value;
+ private static final ConcurrentMap<Class<?>, Field> FIELD_CACHE = new ConcurrentHashMap<Class<?>, 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<String, Object> TREE_TAG_CACHE = new ConcurrentHashMap<String, Object>();
- public final Object value;
+ 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) {
- 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 <J> MethodId<J> MethodId(Class<?> owner, String name, Class<J> returnType, Class<?>... types) {
+ return new MethodId<J>(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 <J extends JCTree> MethodId<J> MethodId(String name, Class<J> returnType, Class<?>... types) {
- return new MethodId<J>(name, returnType, types);
+ static <J> MethodId<J> MethodId(String name, Class<J> returnType, Class<?>... types) {
+ return new MethodId<J>(TreeMaker.class, name, returnType, types);
}
/**
@@ -176,7 +277,7 @@ public class JavacTreeMaker {
if (m.getName().equals(name)) {
@SuppressWarnings("unchecked") Class<J> r = (Class<J>) m.getReturnType();
Class<?>[] p = m.getParameterTypes();
- return new MethodId<J>(name, r, p);
+ return new MethodId<J>(TreeMaker.class, name, r, p);
}
}
@@ -185,14 +286,27 @@ public class JavacTreeMaker {
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 {
- 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<JCExpression> 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<Void> {
private final IdentityHashMap<JCTree, JCTree> originalToCopy = new IdentityHashMap<JCTree, JCTree>();
- public TreeMirrorMaker(TreeMaker maker) {
- super(maker);
+ public TreeMirrorMaker(JavacTreeMaker maker) {
+ super(maker.getUnderlyingTreeMaker());
}
@Override public <T extends JCTree> T copy(T original) {