mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 12:15:00 +00:00
more progress. This one is less JDK8 compatible, but
it has major refactorings to make JDK6-8 support possibly with much prettier code.
This commit is contained in:
1 parent
e2af5ed0c7
commit
4dbe3802fd
10 files changed
+296
-322
No files matched your search
@@ -332,7 +332,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="setupJava6TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK6.">
|
||||
<target name="setupJavaOpenJDK6TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK6.">
|
||||
<mkdir dir="lib/openJDK6Environment" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/javac-1.6.0.18.jar" dest="lib/openJDK6Environment/javac6.jar" verbose="true" usetimestamp="true" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/rt-openjdk6.jar" dest="lib/openJDK6Environment/rt-openjdk6.jar" verbose="true" usetimestamp="true" />
|
||||
@@ -345,7 +345,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
|
||||
<antcall target="-createEclipseLaunchForTestEnvironmentIfEclipseProject" />
|
||||
</target>
|
||||
|
||||
<target name="setupJava7TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK7.">
|
||||
<target name="setupJavaOpenJDK7TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK7.">
|
||||
<mkdir dir="lib/openJDK7Environment" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/javac-1.7.0.jar" dest="lib/openJDK7Environment/javac7.jar" verbose="true" usetimestamp="true" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/rt-openjdk7.jar" dest="lib/openJDK7Environment/rt-openjdk7.jar" verbose="true" usetimestamp="true" />
|
||||
@@ -360,9 +360,11 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
|
||||
|
||||
<target name="setupJavaOracle7TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK7.">
|
||||
<mkdir dir="lib/oracleJDK7Environment" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/oracle-jdk7-tools.jar" dest="lib/oracleJDK7Environment/tools.jar" verbose="true" usetimestamp="true" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/oracle-jdk7-rt.jar" dest="lib/oracleJDK7Environment/rt.jar" verbose="true" usetimestamp="true" />
|
||||
<propertyfile file="testenvironment.properties">
|
||||
<entry key="test.location.javac" value="lib/oracleJDK7Environment/tools-jdk7.jar" />
|
||||
<entry key="test.location.bootclasspath" value="lib/oracleJDK7Environment/rt-oraclejdk7.jar" />
|
||||
<entry key="test.location.javac" value="lib/oracleJDK7Environment/tools.jar" />
|
||||
<entry key="test.location.bootclasspath" value="lib/oracleJDK7Environment/rt.jar" />
|
||||
<entry key="test.location.name" value="OracleJDK7" />
|
||||
</propertyfile>
|
||||
<echo>Tests will now run against Oracle JDK7</echo>
|
||||
@@ -371,11 +373,11 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
|
||||
|
||||
<target name="setupJavaOracle8TestEnvironment" description="Sets up the test so that 'ant test' will test against OpenJDK8.">
|
||||
<mkdir dir="lib/oracleJDK8Environment" />
|
||||
<!--get src="http://projectlombok.org/ivyrepo/langtools/javac-1.7.0.jar" dest="lib/openJDK7Environment/javac7.jar" verbose="true" usetimestamp="true" /-->
|
||||
<!--get src="http://projectlombok.org/ivyrepo/langtools/rt-openjdk7.jar" dest="lib/openJDK7Environment/rt-openjdk7.jar" verbose="true" usetimestamp="true" /-->
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/oracle-jdk8-tools.jar" dest="lib/oracleJDK8Environment/tools.jar" verbose="true" usetimestamp="true" />
|
||||
<get src="http://projectlombok.org/ivyrepo/langtools/oracle-jdk8-rt.jar" dest="lib/oracleJDK8Environment/rt.jar" verbose="true" usetimestamp="true" />
|
||||
<propertyfile file="testenvironment.properties">
|
||||
<entry key="test.location.javac" value="lib/oracleJDK8Environment/tools-jdk8.jar" />
|
||||
<entry key="test.location.bootclasspath" value="lib/oracleJDK8Environment/rt-oraclejdk8.jar" />
|
||||
<entry key="test.location.javac" value="lib/oracleJDK8Environment/tools.jar" />
|
||||
<entry key="test.location.bootclasspath" value="lib/oracleJDK8Environment/rt.jar" />
|
||||
<entry key="test.location.name" value="OracleJDK8" />
|
||||
</propertyfile>
|
||||
<echo>Tests will now run against Oracle JDK8</echo>
|
||||
@@ -390,8 +392,10 @@ Eventually, this environment concept will be extended to also include an ecj and
|
||||
|
||||
You can let this ant script set them up for you:
|
||||
|
||||
* ant setupJava6TestEnvironment
|
||||
* ant setupJava7TestEnvironment
|
||||
* ant setupJavaOpenJDK6TestEnvironment
|
||||
* ant setupJavaOpenJDK7TestEnvironment
|
||||
* ant setupJavaOracle7TestEnvironment
|
||||
* ant setupJavaOracle8TestEnvironment
|
||||
|
||||
These will set up test environments based on OpenJDK6 and OpenJDK7, and download all required files automatically. This will be a relatively large download. You can switch by running this command again; the downloads are cached so switching is fast.
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ import java.util.Queue;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.tools.DiagnosticListener;
|
||||
|
||||
import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
|
||||
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
import com.sun.tools.javac.code.Symbol.TypeSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
@@ -56,7 +58,6 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
@@ -389,7 +390,7 @@ public class JavacResolution {
|
||||
}
|
||||
|
||||
public static JCExpression createJavaLangObject(JavacAST ast) {
|
||||
TreeMaker maker = ast.getTreeMaker();
|
||||
JavacTreeMaker maker = ast.getTreeMaker();
|
||||
JCExpression out = maker.Ident(ast.toName("java"));
|
||||
out = maker.Select(out, ast.toName("lang"));
|
||||
out = maker.Select(out, ast.toName("Object"));
|
||||
@@ -416,10 +417,10 @@ public class JavacResolution {
|
||||
// NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too.
|
||||
// -- so we write our own take on that here.
|
||||
|
||||
TreeMaker maker = ast.getTreeMaker();
|
||||
JavacTreeMaker maker = ast.getTreeMaker();
|
||||
|
||||
if (Javac.compareCTC(type.tag, CTC_BOT)) return createJavaLangObject(ast);
|
||||
if (Javac.compareCTC(type.tag, CTC_VOID)) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast);
|
||||
if (CTC_BOT.equals(typeTag(type))) return createJavaLangObject(ast);
|
||||
if (CTC_VOID.equals(typeTag(type))) return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast);
|
||||
if (type.isPrimitive()) return primitiveToJCTree(type.getKind(), maker);
|
||||
if (type.isErroneous()) throw new TypeNotConvertibleException("Type cannot be resolved");
|
||||
|
||||
@@ -453,7 +454,7 @@ public class JavacResolution {
|
||||
upper = type.getUpperBound();
|
||||
}
|
||||
if (allowCompound) {
|
||||
if (lower == null || Javac.compareCTC(lower.tag, CTC_BOT)) {
|
||||
if (lower == null || CTC_BOT.equals(typeTag(lower))) {
|
||||
if (upper == null || upper.toString().equals("java.lang.Object")) {
|
||||
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
|
||||
}
|
||||
@@ -478,7 +479,7 @@ public class JavacResolution {
|
||||
String qName;
|
||||
if (symbol.isLocal()) {
|
||||
qName = symbol.getSimpleName().toString();
|
||||
} else if (symbol.type != null && symbol.type.getEnclosingType() != null && Javac.compareCTC(symbol.type.getEnclosingType().tag, Javac.getTypeTag("CLASS"))) {
|
||||
} else if (symbol.type != null && symbol.type.getEnclosingType() != null && typeTag(symbol.type.getEnclosingType()).equals(typeTag("CLASS"))) {
|
||||
replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false);
|
||||
qName = symbol.getSimpleName().toString();
|
||||
} else {
|
||||
@@ -511,26 +512,26 @@ public class JavacResolution {
|
||||
return rawTypeNode;
|
||||
}
|
||||
|
||||
private static JCExpression primitiveToJCTree(TypeKind kind, TreeMaker maker) throws TypeNotConvertibleException {
|
||||
private static JCExpression primitiveToJCTree(TypeKind kind, JavacTreeMaker maker) throws TypeNotConvertibleException {
|
||||
switch (kind) {
|
||||
case BYTE:
|
||||
return Javac.makeTypeIdent(maker, CTC_BYTE);
|
||||
return maker.TypeIdent(CTC_BYTE);
|
||||
case CHAR:
|
||||
return Javac.makeTypeIdent(maker, CTC_CHAR);
|
||||
return maker.TypeIdent( CTC_CHAR);
|
||||
case SHORT:
|
||||
return Javac.makeTypeIdent(maker, CTC_SHORT);
|
||||
return maker.TypeIdent(CTC_SHORT);
|
||||
case INT:
|
||||
return Javac.makeTypeIdent(maker, CTC_INT);
|
||||
return maker.TypeIdent(CTC_INT);
|
||||
case LONG:
|
||||
return Javac.makeTypeIdent(maker, CTC_LONG);
|
||||
return maker.TypeIdent(CTC_LONG);
|
||||
case FLOAT:
|
||||
return Javac.makeTypeIdent(maker, CTC_FLOAT);
|
||||
return maker.TypeIdent(CTC_FLOAT);
|
||||
case DOUBLE:
|
||||
return Javac.makeTypeIdent(maker, CTC_DOUBLE);
|
||||
return maker.TypeIdent(CTC_DOUBLE);
|
||||
case BOOLEAN:
|
||||
return Javac.makeTypeIdent(maker, CTC_BOOLEAN);
|
||||
return maker.TypeIdent(CTC_BOOLEAN);
|
||||
case VOID:
|
||||
return Javac.makeTypeIdent(maker, CTC_VOID);
|
||||
return maker.TypeIdent(CTC_VOID);
|
||||
case NULL:
|
||||
case NONE:
|
||||
case OTHER:
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.sun.tools.javac.tree.JCTree.JCStatement;
|
||||
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
|
||||
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
@@ -53,13 +52,14 @@ import lombok.core.HandlerPriority;
|
||||
import lombok.core.TransformationsUtil;
|
||||
import lombok.experimental.Builder;
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacNode;
|
||||
import lombok.javac.JavacTreeMaker;
|
||||
import lombok.javac.handlers.HandleConstructor.SkipIfConstructorExists;
|
||||
import static lombok.core.handlers.HandlerUtil.*;
|
||||
import static lombok.javac.handlers.JavacHandlerUtil.*;
|
||||
import static lombok.javac.Javac.*;
|
||||
import static lombok.javac.JavacTreeMaker.TypeTag.*;
|
||||
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
@HandlerPriority(-1024) //-2^10; to ensure we've picked up @FieldDefault's changes (-2048) but @Value hasn't removed itself yet (-512), so that we can error on presence of it on the builder classes.
|
||||
@@ -240,7 +240,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
|
||||
JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName);
|
||||
call = maker.Apply(typeParams.toList(), fn, args.toList());
|
||||
if (returnType instanceof JCPrimitiveTypeTree && compareCTC(Javac.getTypeTag((JCPrimitiveTypeTree) returnType), CTC_VOID)) {
|
||||
if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) {
|
||||
statement = maker.Exec(call);
|
||||
} else {
|
||||
statement = maker.Return(call);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package lombok.javac.handlers;
|
||||
|
||||
import static lombok.javac.Javac.*;
|
||||
import static lombok.javac.JavacTreeMaker.TypeTag.*;
|
||||
import static lombok.javac.handlers.JavacHandlerUtil.*;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -35,10 +36,10 @@ import lombok.Getter;
|
||||
import lombok.core.AST.Kind;
|
||||
import lombok.core.AnnotationValues;
|
||||
import lombok.core.TransformationsUtil;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacNode;
|
||||
import lombok.javac.JavacTreeMaker;
|
||||
import lombok.javac.JavacTreeMaker.TypeTag;
|
||||
import lombok.javac.handlers.JavacHandlerUtil.FieldAccess;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
@@ -289,9 +290,9 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
|
||||
private static final String JLO = "java.lang.Object";
|
||||
private static final List<JCExpression> NIL_EXPRESSION = List.nil();
|
||||
|
||||
private static final java.util.Map<Object, String> TYPE_MAP;
|
||||
private static final java.util.Map<TypeTag, String> TYPE_MAP;
|
||||
static {
|
||||
Map<Object, String> m = new HashMap<Object, String>();
|
||||
Map<TypeTag, String> m = new HashMap<TypeTag, String>();
|
||||
m.put(CTC_INT, "java.lang.Integer");
|
||||
m.put(CTC_DOUBLE, "java.lang.Double");
|
||||
m.put(CTC_FLOAT, "java.lang.Float");
|
||||
@@ -335,7 +336,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
|
||||
field.type = null;
|
||||
boolean isPrimitive = false;
|
||||
if (field.vartype instanceof JCPrimitiveTypeTree) {
|
||||
String boxed = TYPE_MAP.get(((JCPrimitiveTypeTree)field.vartype).typetag);
|
||||
String boxed = TYPE_MAP.get(typeTag(field.vartype));
|
||||
if (boxed != null) {
|
||||
isPrimitive = true;
|
||||
field.vartype = chainDotsString(fieldNode, boxed);
|
||||
|
||||
@@ -1277,17 +1277,17 @@ public class JavacHandlerUtil {
|
||||
*/
|
||||
public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) {
|
||||
if (copyMode == null) copyMode = CopyJavadoc.VERBATIM;
|
||||
// try {
|
||||
// JCCompilationUnit cu = ((JCCompilationUnit) from.top().get());
|
||||
// if (cu.docComments != null) {
|
||||
// String javadoc = cu.docComments.get(from.get());
|
||||
//
|
||||
// if (javadoc != null) {
|
||||
// String[] filtered = copyMode.split(javadoc);
|
||||
// cu.docComments.put(to, filtered[0]);
|
||||
// cu.docComments.put(from.get(), filtered[1]);
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception ignore) {}
|
||||
try {
|
||||
JCCompilationUnit cu = ((JCCompilationUnit) from.top().get());
|
||||
if (cu.docComments != null) {
|
||||
String javadoc = cu.docComments.get(from.get());
|
||||
|
||||
if (javadoc != null) {
|
||||
String[] filtered = copyMode.split(javadoc);
|
||||
cu.docComments.put(to, filtered[0]);
|
||||
cu.docComments.put(from.get(), filtered[1]);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,9 @@ import lombok.core.AST.Kind;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacNode;
|
||||
|
||||
import static lombok.javac.JavacTreeMaker.TypeTag.*;
|
||||
import static lombok.javac.JavacTreeMaker.TreeTag.*;
|
||||
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class NonNullHandler extends JavacAnnotationHandler<NonNull> {
|
||||
@Override public void handle(AnnotationValues<NonNull> annotation, JCAnnotation ast, JavacNode annotationNode) {
|
||||
@@ -138,10 +141,10 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> {
|
||||
while (cond instanceof JCParens) cond = ((JCParens) cond).expr;
|
||||
if (!(cond instanceof JCBinary)) return null;
|
||||
JCBinary bin = (JCBinary) cond;
|
||||
if (compareCTC(getTag(bin), CTC_EQUAL)) return null;
|
||||
if (!CTC_EQUAL.equals(treeTag(bin))) return null;
|
||||
if (!(bin.lhs instanceof JCIdent)) return null;
|
||||
if (!(bin.rhs instanceof JCLiteral)) return null;
|
||||
if (compareCTC(getTypeTag((JCLiteral) bin.rhs), CTC_BOT)) return null;
|
||||
if (!CTC_BOT.equals(typeTag(bin.rhs))) return null;
|
||||
return ((JCIdent) bin.lhs).name.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,13 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.javac.CommentInfo;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.CommentInfo.EndConnection;
|
||||
import lombok.javac.CommentInfo.StartConnection;
|
||||
import lombok.javac.JavacTreeMaker.TreeTag;
|
||||
import lombok.javac.JavacTreeMaker.TypeTag;
|
||||
import static lombok.javac.Javac.*;
|
||||
import static lombok.javac.JavacTreeMaker.TreeTag.treeTag;
|
||||
import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
|
||||
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
@@ -123,88 +127,48 @@ import com.sun.tools.javac.util.Position;
|
||||
*/
|
||||
@SuppressWarnings("all") // Mainly sun code that has other warning settings
|
||||
public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
private static final TreeTag PARENS = treeTag("PARENS");
|
||||
private static final TreeTag IMPORT = treeTag("IMPORT");
|
||||
private static final TreeTag VARDEF = treeTag("VARDEF");
|
||||
private static final TreeTag SELECT = treeTag("SELECT");
|
||||
|
||||
private static final Method GET_TAG_METHOD;
|
||||
private static final Field TAG_FIELD;
|
||||
|
||||
private static final Object PARENS = Javac.getTreeTag("PARENS");
|
||||
private static final Object IMPORT = Javac.getTreeTag("IMPORT");
|
||||
private static final Object VARDEF = Javac.getTreeTag("VARDEF");
|
||||
private static final Object SELECT = Javac.getTreeTag("SELECT");
|
||||
|
||||
private static final Map<Object, String> OPERATORS;
|
||||
private static final Map<TreeTag, String> OPERATORS;
|
||||
|
||||
static {
|
||||
Method m = null;
|
||||
Field f = null;
|
||||
try {
|
||||
m = JCTree.class.getDeclaredMethod("getTag");
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
try {
|
||||
f = JCTree.class.getDeclaredField("tag");
|
||||
}
|
||||
catch (NoSuchFieldException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
GET_TAG_METHOD = m;
|
||||
TAG_FIELD = f;
|
||||
Map<TreeTag, String> map = new HashMap<TreeTag, String>();
|
||||
|
||||
Map<Object, String> map = new HashMap<Object, String>();
|
||||
|
||||
map.put(Javac.getTreeTag("POS"), "+");
|
||||
map.put(Javac.getTreeTag("NEG"), "-");
|
||||
map.put(Javac.getTreeTag("NOT"), "!");
|
||||
map.put(Javac.getTreeTag("COMPL"), "~");
|
||||
map.put(Javac.getTreeTag("PREINC"), "++");
|
||||
map.put(Javac.getTreeTag("PREDEC"), "--");
|
||||
map.put(Javac.getTreeTag("POSTINC"), "++");
|
||||
map.put(Javac.getTreeTag("POSTDEC"), "--");
|
||||
map.put(Javac.getTreeTag("NULLCHK"), "<*nullchk*>");
|
||||
map.put(Javac.getTreeTag("OR"), "||");
|
||||
map.put(Javac.getTreeTag("AND"), "&&");
|
||||
map.put(Javac.getTreeTag("EQ"), "==");
|
||||
map.put(Javac.getTreeTag("NE"), "!=");
|
||||
map.put(Javac.getTreeTag("LT"), "<");
|
||||
map.put(Javac.getTreeTag("GT"), ">");
|
||||
map.put(Javac.getTreeTag("LE"), "<=");
|
||||
map.put(Javac.getTreeTag("GE"), ">=");
|
||||
map.put(Javac.getTreeTag("BITOR"), "|");
|
||||
map.put(Javac.getTreeTag("BITXOR"), "^");
|
||||
map.put(Javac.getTreeTag("BITAND"), "&");
|
||||
map.put(Javac.getTreeTag("SL"), "<<");
|
||||
map.put(Javac.getTreeTag("SR"), ">>");
|
||||
map.put(Javac.getTreeTag("USR"), ">>>");
|
||||
map.put(Javac.getTreeTag("PLUS"), "+");
|
||||
map.put(Javac.getTreeTag("MINUS"), "-");
|
||||
map.put(Javac.getTreeTag("MUL"), "*");
|
||||
map.put(Javac.getTreeTag("DIV"), "/");
|
||||
map.put(Javac.getTreeTag("MOD"), "%");
|
||||
map.put(treeTag("POS"), "+");
|
||||
map.put(treeTag("NEG"), "-");
|
||||
map.put(treeTag("NOT"), "!");
|
||||
map.put(treeTag("COMPL"), "~");
|
||||
map.put(treeTag("PREINC"), "++");
|
||||
map.put(treeTag("PREDEC"), "--");
|
||||
map.put(treeTag("POSTINC"), "++");
|
||||
map.put(treeTag("POSTDEC"), "--");
|
||||
map.put(treeTag("NULLCHK"), "<*nullchk*>");
|
||||
map.put(treeTag("OR"), "||");
|
||||
map.put(treeTag("AND"), "&&");
|
||||
map.put(treeTag("EQ"), "==");
|
||||
map.put(treeTag("NE"), "!=");
|
||||
map.put(treeTag("LT"), "<");
|
||||
map.put(treeTag("GT"), ">");
|
||||
map.put(treeTag("LE"), "<=");
|
||||
map.put(treeTag("GE"), ">=");
|
||||
map.put(treeTag("BITOR"), "|");
|
||||
map.put(treeTag("BITXOR"), "^");
|
||||
map.put(treeTag("BITAND"), "&");
|
||||
map.put(treeTag("SL"), "<<");
|
||||
map.put(treeTag("SR"), ">>");
|
||||
map.put(treeTag("USR"), ">>>");
|
||||
map.put(treeTag("PLUS"), "+");
|
||||
map.put(treeTag("MINUS"), "-");
|
||||
map.put(treeTag("MUL"), "*");
|
||||
map.put(treeTag("DIV"), "/");
|
||||
map.put(treeTag("MOD"), "%");
|
||||
|
||||
OPERATORS = map;
|
||||
}
|
||||
|
||||
static Object getTag(JCTree tree) {
|
||||
if (GET_TAG_METHOD != null) {
|
||||
try {
|
||||
return GET_TAG_METHOD.invoke(tree);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e.getCause());
|
||||
}
|
||||
}
|
||||
try {
|
||||
return TAG_FIELD.get(tree);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<CommentInfo> comments;
|
||||
private final JCCompilationUnit cu;
|
||||
private boolean onNewLine = true;
|
||||
@@ -634,7 +598,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
|
||||
/** Is the given tree an enumerator definition? */
|
||||
boolean isEnumerator(JCTree t) {
|
||||
return Javac.compareCTC(getTag(t), VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
|
||||
return VARDEF.equals(treeTag(t)) && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
|
||||
}
|
||||
|
||||
/** Print unit consisting of package clause and import statements in toplevel,
|
||||
@@ -645,7 +609,8 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
* toplevel tree.
|
||||
*/
|
||||
public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException {
|
||||
docComments = tree.docComments;
|
||||
Object dc = getDocComments(tree);
|
||||
if (dc instanceof Map) this.docComments = (Map) dc;
|
||||
printDocComment(tree);
|
||||
if (tree.pid != null) {
|
||||
consumeComments(tree.pos, tree);
|
||||
@@ -656,9 +621,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
}
|
||||
boolean firstImport = true;
|
||||
for (List<JCTree> l = tree.defs;
|
||||
l.nonEmpty() && (cdef == null || getTag(l.head) == IMPORT);
|
||||
l.nonEmpty() && (cdef == null || IMPORT.equals(treeTag(l.head)));
|
||||
l = l.tail) {
|
||||
if (Javac.compareCTC(getTag(l.head), IMPORT)) {
|
||||
if (IMPORT.equals(treeTag(l.head))) {
|
||||
JCImport imp = (JCImport)l.head;
|
||||
Name name = TreeInfo.name(imp.qualid);
|
||||
if (name == name.table.fromChars(new char[] {'*'}, 0, 1) ||
|
||||
@@ -742,9 +707,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
else
|
||||
print("class " + tree.name);
|
||||
printTypeParameters(tree.typarams);
|
||||
if (Javac.getExtendsClause(tree) != null) {
|
||||
if (getExtendsClause(tree) != null) {
|
||||
print(" extends ");
|
||||
printExpr(Javac.getExtendsClause(tree));
|
||||
printExpr(getExtendsClause(tree));
|
||||
}
|
||||
if (tree.implementing.nonEmpty()) {
|
||||
print(" implements ");
|
||||
@@ -877,7 +842,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
printStat(tree.body);
|
||||
align();
|
||||
print(" while ");
|
||||
if (Javac.compareCTC(getTag(tree.cond), PARENS)) {
|
||||
if (PARENS.equals(treeTag(tree.cond))) {
|
||||
printExpr(tree.cond);
|
||||
} else {
|
||||
print("(");
|
||||
@@ -893,7 +858,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitWhileLoop(JCWhileLoop tree) {
|
||||
try {
|
||||
print("while ");
|
||||
if (Javac.compareCTC(getTag(tree.cond), PARENS)) {
|
||||
if (PARENS.equals(treeTag(tree.cond))) {
|
||||
printExpr(tree.cond);
|
||||
} else {
|
||||
print("(");
|
||||
@@ -911,7 +876,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
try {
|
||||
print("for (");
|
||||
if (tree.init.nonEmpty()) {
|
||||
if (Javac.compareCTC(getTag(tree.init.head), VARDEF)) {
|
||||
if (VARDEF.equals(treeTag(tree.init.head))) {
|
||||
printExpr(tree.init.head);
|
||||
for (List<JCStatement> l = tree.init.tail; l.nonEmpty(); l = l.tail) {
|
||||
JCVariableDecl vdef = (JCVariableDecl)l.head;
|
||||
@@ -958,7 +923,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitSwitch(JCSwitch tree) {
|
||||
try {
|
||||
print("switch ");
|
||||
if (Javac.compareCTC(getTag(tree.selector), PARENS)) {
|
||||
if (PARENS.equals(treeTag(tree.selector))) {
|
||||
printExpr(tree.selector);
|
||||
} else {
|
||||
print("(");
|
||||
@@ -997,7 +962,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitSynchronized(JCSynchronized tree) {
|
||||
try {
|
||||
print("synchronized ");
|
||||
if (Javac.compareCTC(getTag(tree.lock), PARENS)) {
|
||||
if (PARENS.equals(treeTag(tree.lock))) {
|
||||
printExpr(tree.lock);
|
||||
} else {
|
||||
print("(");
|
||||
@@ -1078,7 +1043,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitIf(JCIf tree) {
|
||||
try {
|
||||
print("if ");
|
||||
if (Javac.compareCTC(getTag(tree.cond), PARENS)) {
|
||||
if (PARENS.equals(treeTag(tree.cond))) {
|
||||
printExpr(tree.cond);
|
||||
} else {
|
||||
print("(");
|
||||
@@ -1174,7 +1139,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitApply(JCMethodInvocation tree) {
|
||||
try {
|
||||
if (!tree.typeargs.isEmpty()) {
|
||||
if (Javac.compareCTC(getTag(tree.meth), SELECT)) {
|
||||
if (SELECT.equals(treeTag(tree.meth))) {
|
||||
JCFieldAccess left = (JCFieldAccess)tree.meth;
|
||||
printExpr(left.selected);
|
||||
print(".<");
|
||||
@@ -1278,7 +1243,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
public String operatorName(Object tag) {
|
||||
public String operatorName(TreeTag tag) {
|
||||
String result = OPERATORS.get(tag);
|
||||
if (result == null) throw new Error();
|
||||
return result;
|
||||
@@ -1300,9 +1265,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
public void visitUnary(JCUnary tree) {
|
||||
try {
|
||||
int ownprec = isOwnPrec(tree);
|
||||
String opname = operatorName(getTag(tree));
|
||||
String opname = operatorName(treeTag(tree));
|
||||
open(prec, ownprec);
|
||||
if (isPostUnary(tree)) {
|
||||
if (isPrefixUnary(tree)) {
|
||||
print(opname);
|
||||
printExpr(tree.arg, ownprec);
|
||||
} else {
|
||||
@@ -1315,63 +1280,18 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
private String assignOpName(JCExpression tree) {
|
||||
try {
|
||||
Object tag = getTag(tree);
|
||||
if (JavaCompiler.version().startsWith("1.8")) {
|
||||
return operatorName(tag.getClass().getMethod("noAssignOp").invoke(tree));
|
||||
} else {
|
||||
return operatorName((Integer)((Integer)tag - (Integer)JCTree.class.getField("ASGOffset").get(null)));
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) throw (RuntimeException) e;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int isOwnPrec(JCExpression tree) {
|
||||
try {
|
||||
if (JavaCompiler.version().startsWith("1.8")) {
|
||||
return (Integer)TreeInfo.class.getMethod("opPrec", Class.forName("com.sun.tools.javac.code.TypeTag")).invoke(null, getTag(tree));
|
||||
} else {
|
||||
return (Integer)TreeInfo.class.getMethod("opPrec", Integer.TYPE).invoke(null, getTag(tree));
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) throw (RuntimeException) e;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return treeTag(tree).getOperatorPrecedenceLevel();
|
||||
}
|
||||
|
||||
private boolean isPrefixUnary(JCUnary tree) {
|
||||
return treeTag(tree).isPrefixUnaryOp();
|
||||
}
|
||||
|
||||
private boolean isPostUnary(JCUnary tree) {
|
||||
try {
|
||||
Object tag = getTag(tree);
|
||||
if (JavaCompiler.version().startsWith("1.8")) {
|
||||
return (Boolean) tag.getClass().getMethod("isPostUnaryOp").invoke(tree);
|
||||
} else {
|
||||
return ((Integer) tag) <= ((Integer) Javac.getTreeTag("PREDEC"));
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) throw (RuntimeException) e;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitBinary(JCBinary tree) {
|
||||
try {
|
||||
int ownprec = isOwnPrec(tree);
|
||||
String opname = operatorName(getTag(tree));
|
||||
String opname = operatorName(treeTag(tree));
|
||||
open(prec, ownprec);
|
||||
printExpr(tree.lhs, ownprec);
|
||||
print(" " + opname + " ");
|
||||
@@ -1436,19 +1356,17 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
public void visitLiteral(JCLiteral tree) {
|
||||
TypeTag typeTag = typeTag(tree);
|
||||
try {
|
||||
if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_INT)) print(tree.value.toString());
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_LONG)) print(tree.value + "L");
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_FLOAT)) print(tree.value + "F");
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_DOUBLE)) print(tree.value.toString());
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_CHAR)) {
|
||||
print("\'" +
|
||||
Convert.quote(
|
||||
String.valueOf((char)((Number)tree.value).intValue()))+
|
||||
"\'");
|
||||
if (CTC_INT.equals(typeTag)) print(tree.value.toString());
|
||||
else if (CTC_LONG.equals(typeTag)) print(tree.value + "L");
|
||||
else if (CTC_FLOAT.equals(typeTag)) print(tree.value + "F");
|
||||
else if (CTC_DOUBLE.equals(typeTag)) print(tree.value.toString());
|
||||
else if (CTC_CHAR.equals(typeTag)) {
|
||||
print("\'" + Convert.quote(String.valueOf((char)((Number)tree.value).intValue())) + "\'");
|
||||
}
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOOLEAN)) print(((Number)tree.value).intValue() == 1 ? "true" : "false");
|
||||
else if (Javac.compareCTC(Javac.getTreeTypeTag(tree), Javac.CTC_BOT)) print("null");
|
||||
else if (CTC_BOOLEAN.equals(typeTag)) print(((Number)tree.value).intValue() == 1 ? "true" : "false");
|
||||
else if (CTC_BOT.equals(typeTag)) print("null");
|
||||
else print("\"" + Convert.quote(tree.value.toString()) + "\"");
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
@@ -1456,17 +1374,17 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
public void visitTypeIdent(JCPrimitiveTypeTree tree) {
|
||||
Object typetag = Javac.getTreeTypeTag(tree);
|
||||
TypeTag typetag = typeTag(tree);
|
||||
try {
|
||||
if (Javac.compareCTC(typetag, Javac.CTC_BYTE)) print("byte");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_CHAR)) print("char");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_SHORT)) print("short");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_INT)) print("int");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_LONG)) print("long");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_FLOAT)) print("float");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_DOUBLE)) print("double");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_BOOLEAN)) print("boolean");
|
||||
else if (Javac.compareCTC(typetag, Javac.CTC_VOID)) print("void");
|
||||
if (CTC_BYTE.equals(typetag)) print ("byte");
|
||||
else if (CTC_CHAR.equals(typetag)) print ("char");
|
||||
else if (CTC_SHORT.equals(typetag)) print ("short");
|
||||
else if (CTC_INT.equals(typetag)) print ("int");
|
||||
else if (CTC_LONG.equals(typetag)) print ("long");
|
||||
else if (CTC_FLOAT.equals(typetag)) print ("float");
|
||||
else if (CTC_DOUBLE.equals(typetag)) print ("double");
|
||||
else if (CTC_BOOLEAN.equals(typetag)) print ("boolean");
|
||||
else if (CTC_VOID.equals(typetag)) print ("void");
|
||||
else print("error");
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
|
||||
@@ -47,7 +47,6 @@ import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
|
||||
import com.sun.tools.javac.tree.JCTree.JCIdent;
|
||||
import com.sun.tools.javac.tree.JCTree.JCLiteral;
|
||||
import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
@@ -133,34 +132,17 @@ public class Javac {
|
||||
public static final TypeTag CTC_CLASS = typeTag("CLASS");
|
||||
|
||||
public static final TreeTag CTC_NOT_EQUAL = treeTag("NE");
|
||||
public static final TreeTag CTC_POS = treeTag("POS");
|
||||
public static final TreeTag CTC_NEG = treeTag("NEG");
|
||||
public static final TreeTag CTC_NOT = treeTag("NOT");
|
||||
public static final TreeTag CTC_COMPL = treeTag("COMPL");
|
||||
public static final TreeTag CTC_BITXOR = treeTag("BITXOR");
|
||||
public static final TreeTag CTC_UNSIGNED_SHIFT_RIGHT = treeTag("USR");
|
||||
public static final TreeTag CTC_MUL = treeTag("MUL");
|
||||
public static final TreeTag CTC_PLUS = treeTag("PLUS");
|
||||
public static final TreeTag CTC_EQUAL = treeTag("EQ");
|
||||
|
||||
public static boolean compareCTC(TreeTag ctc1, TreeTag ctc2) {
|
||||
boolean ctc1IsNull = ctc1 == null || ctc1.value == null;
|
||||
boolean ctc2IsNull = ctc2 == null || ctc2.value == null;
|
||||
if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull;
|
||||
return ctc1.value.equals(ctc2.value);
|
||||
}
|
||||
|
||||
public static boolean compareCTC(TypeTag ctc1, TypeTag ctc2) {
|
||||
boolean ctc1IsNull = ctc1 == null || ctc1.value == null;
|
||||
boolean ctc2IsNull = ctc2 == null || ctc2.value == null;
|
||||
if (ctc1IsNull || ctc2IsNull) return ctc1IsNull && ctc2IsNull;
|
||||
return ctc1.value.equals(ctc2.value);
|
||||
}
|
||||
|
||||
public static Object getTreeTypeTag(JCPrimitiveTypeTree tree) {
|
||||
return tree.typetag;
|
||||
}
|
||||
|
||||
public static Object getTreeTypeTag(JCLiteral tree) {
|
||||
return tree.typetag;
|
||||
}
|
||||
public static final TreeTag CTC_PREINC = treeTag("PREINC");
|
||||
public static final TreeTag CTC_PREDEC = treeTag("PREDEC");
|
||||
|
||||
private static final Method getExtendsClause, getEndPosition;
|
||||
|
||||
@@ -245,7 +227,7 @@ public class Javac {
|
||||
return new JCNoType(((Integer) tag.value).intValue());
|
||||
} else {
|
||||
try {
|
||||
if (compareCTC(tag, CTC_VOID)) {
|
||||
if (CTC_VOID.equals(tag)) {
|
||||
return (Type) JC_VOID_TYPE.newInstance();
|
||||
} else {
|
||||
return (Type) JC_NO_TYPE.newInstance();
|
||||
@@ -276,28 +258,9 @@ public class Javac {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Field JCTREE_TAG, JCLITERAL_TYPETAG, JCPRIMITIVETYPETREE_TYPETAG, JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS;
|
||||
private static final Method JCTREE_GETTAG;
|
||||
private static final Field JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS;
|
||||
static {
|
||||
Field f = null;
|
||||
try {
|
||||
f = JCTree.class.getDeclaredField("tag");
|
||||
} catch (NoSuchFieldException e) {}
|
||||
JCTREE_TAG = f;
|
||||
|
||||
f = null;
|
||||
try {
|
||||
f = JCLiteral.class.getDeclaredField("typetag");
|
||||
} catch (NoSuchFieldException e) {}
|
||||
JCLITERAL_TYPETAG = f;
|
||||
|
||||
f = null;
|
||||
try {
|
||||
f = JCPrimitiveTypeTree.class.getDeclaredField("typetag");
|
||||
} catch (NoSuchFieldException e) {}
|
||||
JCPRIMITIVETYPETREE_TYPETAG = f;
|
||||
|
||||
f = null;
|
||||
try {
|
||||
f = JCCompilationUnit.class.getDeclaredField("endPositions");
|
||||
} catch (NoSuchFieldException e) {}
|
||||
@@ -308,41 +271,6 @@ public class Javac {
|
||||
f = JCCompilationUnit.class.getDeclaredField("docComments");
|
||||
} catch (NoSuchFieldException e) {}
|
||||
JCCOMPILATIONUNIT_DOCCOMMENTS = f;
|
||||
|
||||
Method m = null;
|
||||
try {
|
||||
m = JCTree.class.getDeclaredMethod("getTag");
|
||||
} catch (NoSuchMethodException e) {}
|
||||
JCTREE_GETTAG = m;
|
||||
}
|
||||
|
||||
public static Object getTag(JCTree node) {
|
||||
if (JCTREE_GETTAG != null) {
|
||||
try {
|
||||
return JCTREE_GETTAG.invoke(node);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
try {
|
||||
return JCTREE_TAG.get(node);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Can't get node tag");
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getTypeTag(JCLiteral node) {
|
||||
try {
|
||||
return JCLITERAL_TYPETAG.get(node);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Can't get JCLiteral typetag");
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getTypeTag(JCPrimitiveTypeTree node) {
|
||||
try {
|
||||
return JCPRIMITIVETYPETREE_TYPETAG.get(node);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Can't get JCPrimitiveTypeTree typetag");
|
||||
}
|
||||
}
|
||||
|
||||
static RuntimeException sneakyThrow(Throwable t) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
cache.putIfAbsent(fieldName, value);
|
||||
return 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user