aboutsummaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/lombok/javac/Javac.java237
1 files changed, 202 insertions, 35 deletions
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
+// * <code>com.sun.tools.javac.code.TypeTag enum</code> for JDK 7 and lower,
+// * this is the value of the constant within
+// * <code>com.sun.tools.javac.code.TypeTags</code>
+// *
+// * 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 <code>com.sun.tools.javac.code.TypeTag</code>
+ * for JDK 7 and lower, this is the value of the constant within <code>com.sun.tools.javac.code.TypeTags</code>
*
- * 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);
+ }
+ }
+
+
}