aboutsummaryrefslogtreecommitdiff
path: root/src/utils/lombok/javac
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/lombok/javac')
-rw-r--r--src/utils/lombok/javac/CommentCatcher.java52
-rw-r--r--src/utils/lombok/javac/Javac.java311
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java830
-rw-r--r--src/utils/lombok/javac/TreeMirrorMaker.java5
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingParser.java21
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingParserFactory.java21
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingScanner.java7
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java2
-rw-r--r--src/utils/lombok/javac/java6/DocCommentScanner.java461
-rw-r--r--src/utils/lombok/javac/java7/CommentCollectingParser.java21
-rw-r--r--src/utils/lombok/javac/java7/CommentCollectingParserFactory.java21
-rw-r--r--src/utils/lombok/javac/java7/CommentCollectingScanner.java8
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParser.java53
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParserFactory.java73
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScanner.java42
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java89
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingTokenizer.java129
17 files changed, 1563 insertions, 583 deletions
diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java
index 565a166d..36d90e30 100644
--- a/src/utils/lombok/javac/CommentCatcher.java
+++ b/src/utils/lombok/javac/CommentCatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Project Lombok Authors.
+ * Copyright (C) 2011-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
@@ -21,13 +21,15 @@
*/
package lombok.javac;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
public class CommentCatcher {
private final JavaCompiler compiler;
@@ -55,38 +57,54 @@ public class CommentCatcher {
return compiler;
}
+ public void setComments(JCCompilationUnit ast, List<CommentInfo> comments) {
+ if (comments != null) {
+ commentsMap.put(ast, comments);
+ } else {
+ commentsMap.remove(ast);
+ }
+ }
+
public List<CommentInfo> getComments(JCCompilationUnit ast) {
List<CommentInfo> list = commentsMap.get(ast);
- return list == null ? List.<CommentInfo>nil() : list;
+ return list == null ? Collections.<CommentInfo>emptyList() : list;
}
private static void registerCommentsCollectingScannerFactory(Context context) {
try {
- if (Javac.getJavaCompilerVersion() <= 6) {
- Class.forName("lombok.javac.java6.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context);
+ Class<?> scannerFactory;
+ int javaCompilerVersion = Javac.getJavaCompilerVersion();
+ if (javaCompilerVersion <= 6) {
+ scannerFactory = Class.forName("lombok.javac.java6.CommentCollectingScannerFactory");
+ } else if (javaCompilerVersion == 7) {
+ scannerFactory = Class.forName("lombok.javac.java7.CommentCollectingScannerFactory");
} else {
- Class.forName("lombok.javac.java7.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context);
+ scannerFactory = Class.forName("lombok.javac.java8.CommentCollectingScannerFactory");
}
+ scannerFactory.getMethod("preRegister", Context.class).invoke(null, context);
+ } catch (InvocationTargetException e) {
+ throw Javac.sneakyThrow(e.getCause());
} catch (Exception e) {
- if (e instanceof RuntimeException) throw (RuntimeException)e;
- throw new RuntimeException(e);
+ throw Javac.sneakyThrow(e);
}
}
private static void setInCompiler(JavaCompiler compiler, Context context, Map<JCCompilationUnit, List<CommentInfo>> commentsMap) {
-
try {
- if (Javac.getJavaCompilerVersion() <= 6) {
- Class<?> parserFactory = Class.forName("lombok.javac.java6.CommentCollectingParserFactory");
- parserFactory.getMethod("setInCompiler", JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap);
+ Class<?> parserFactory;
+ int javaCompilerVersion = Javac.getJavaCompilerVersion();
+ if (javaCompilerVersion <= 6) {
+ parserFactory = Class.forName("lombok.javac.java6.CommentCollectingParserFactory");
+ } else if (javaCompilerVersion == 7) {
+ parserFactory = Class.forName("lombok.javac.java7.CommentCollectingParserFactory");
} else {
- Class<?> parserFactory = Class.forName("lombok.javac.java7.CommentCollectingParserFactory");
- parserFactory.getMethod("setInCompiler", JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap);
+ parserFactory = Class.forName("lombok.javac.java8.CommentCollectingParserFactory");
}
+ parserFactory.getMethod("setInCompiler", JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap);
+ } catch (InvocationTargetException e) {
+ throw Javac.sneakyThrow(e.getCause());
} catch (Exception e) {
- if (e instanceof RuntimeException) throw (RuntimeException)e;
- throw new RuntimeException(e);
+ throw Javac.sneakyThrow(e);
}
}
-
}
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index 4f316d9f..bdf5e7a0 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -21,57 +21,105 @@
*/
package lombok.javac;
+import static lombok.javac.JavacTreeMaker.TreeTag.treeTag;
+import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
+
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.sun.tools.javac.code.TypeTags;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeVisitor;
+
+import lombok.javac.JavacTreeMaker.TreeTag;
+import lombok.javac.JavacTreeMaker.TypeTag;
+
+import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
-import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
/**
* 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)$");
private static final Pattern VERSION_PARSER = Pattern.compile("^(\\d{1,6})\\.(\\d{1,6}).*$");
+ private static final Pattern SOURCE_PARSER = Pattern.compile("^JDK(\\d{1,6})_(\\d{1,6}).*$");
+
+ private static final AtomicInteger compilerVersion = new AtomicInteger(-1);
/**
* Returns the version of this java compiler, i.e. the JDK that it shipped in. For example, for javac v1.7, this returns {@code 7}.
*/
public static int getJavaCompilerVersion() {
- Matcher m = VERSION_PARSER.matcher(JavaCompiler.version());
- if (m.matches()) {
- int major = Integer.parseInt(m.group(1));
- int minor = Integer.parseInt(m.group(2));
- if (major == 1) return minor;
+ int cv = compilerVersion.get();
+ if (cv != -1) return cv;
+
+ /* Main algorithm: Use JavaCompiler's intended method to do this */ {
+ Matcher m = VERSION_PARSER.matcher(JavaCompiler.version());
+ if (m.matches()) {
+ int major = Integer.parseInt(m.group(1));
+ int minor = Integer.parseInt(m.group(2));
+ if (major == 1) {
+ compilerVersion.set(minor);
+ return minor;
+ }
+ }
}
+ /* Fallback algorithm one: Check Source's values. Lets hope oracle never releases a javac that recognizes future versions for -source */ {
+ String name = Source.values()[Source.values().length - 1].name();
+ Matcher m = SOURCE_PARSER.matcher(name);
+ if (m.matches()) {
+ int major = Integer.parseInt(m.group(1));
+ int minor = Integer.parseInt(m.group(2));
+ if (major == 1) {
+ compilerVersion.set(minor);
+ return minor;
+ }
+ }
+ }
+
+ compilerVersion.set(6);
return 6;
}
+ private static final Class<?> DOCCOMMENTTABLE_CLASS;
+
+ static {
+ Class<?> c = null;
+ try {
+ c = Class.forName("com.sun.tools.javac.tree.DocCommentTable");
+ } catch (Throwable ignore) {}
+ DOCCOMMENTTABLE_CLASS = c;
+ }
+
+ public static boolean instanceOfDocCommentTable(Object o) {
+ return DOCCOMMENTTABLE_CLASS != null && DOCCOMMENTTABLE_CLASS.isInstance(o);
+ }
+
/**
- * 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();
@@ -79,15 +127,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) {
@@ -98,102 +147,176 @@ public class Javac {
if (idx > -1) x = x.substring(idx + 1);
}
return x;
- } 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");
+ } else
+ return null;
+ }
- /**
- * Retrieves a compile time constant of type int from the specified class location.
- *
- * 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.
- */
- public static int getCtcInt(Class<?> ctcLocation, String identifier) {
+ public static final TypeTag CTC_BOOLEAN = typeTag("BOOLEAN");
+ public static final TypeTag CTC_INT = typeTag("INT");
+ public static final TypeTag CTC_DOUBLE = typeTag("DOUBLE");
+ public static final TypeTag CTC_FLOAT = typeTag("FLOAT");
+ public static final TypeTag CTC_SHORT = typeTag("SHORT");
+ public static final TypeTag CTC_BYTE = typeTag("BYTE");
+ public static final TypeTag CTC_LONG = typeTag("LONG");
+ public static final TypeTag CTC_CHAR = typeTag("CHAR");
+ public static final TypeTag CTC_VOID = typeTag("VOID");
+ public static final TypeTag CTC_NONE = typeTag("NONE");
+ public static final TypeTag CTC_BOT = typeTag("BOT");
+ public static final TypeTag CTC_CLASS = typeTag("CLASS");
+
+ public static final TreeTag CTC_NOT_EQUAL = treeTag("NE");
+ public static final TreeTag CTC_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 final TreeTag CTC_PREINC = treeTag("PREINC");
+ public static final TreeTag CTC_PREDEC = treeTag("PREDEC");
+
+ private static final Method getExtendsClause, getEndPosition;
+
+ static {
+ getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class<?>[0]);
+ getExtendsClause.setAccessible(true);
+
+ if (getJavaCompilerVersion() < 8) {
+ getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", java.util.Map.class);
+ } else {
+ getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", "com.sun.tools.javac.tree.EndPosTable");
+ }
+ getEndPosition.setAccessible(true);
+ }
+
+ private static Method getMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
try {
- return (Integer)ctcLocation.getField(identifier).get(null);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
+ return clazz.getMethod(name, paramTypes);
+ } catch (NoSuchMethodException e) {
+ throw sneakyThrow(e);
}
}
- private static final Field JCTREE_TAG;
- private static final Method JCTREE_GETTAG;
- static {
- Field f = null;
+ private static Method getMethod(Class<?> clazz, String name, String... paramTypes) {
try {
- f = JCTree.class.getDeclaredField("tag");
- } catch (NoSuchFieldException e) {}
- JCTREE_TAG = f;
-
- Method m = null;
+ Class<?>[] c = new Class[paramTypes.length];
+ for (int i = 0; i < paramTypes.length; i++) c[i] = Class.forName(paramTypes[i]);
+ return clazz.getMethod(name, c);
+ } catch (NoSuchMethodException e) {
+ throw sneakyThrow(e);
+ } catch (ClassNotFoundException e) {
+ throw sneakyThrow(e);
+ }
+ }
+
+ public static JCTree getExtendsClause(JCClassDecl decl) {
try {
- m = JCTree.class.getDeclaredMethod("getTag");
- } catch (NoSuchMethodException e) {}
- JCTREE_GETTAG = m;
+ return (JCTree) getExtendsClause.invoke(decl);
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
+ } catch (InvocationTargetException e) {
+ throw sneakyThrow(e.getCause());
+ }
}
- public static int getTag(JCTree node) {
- if (JCTREE_GETTAG != null) {
- try {
- return (Integer) JCTREE_GETTAG.invoke(node);
- } catch (Exception e) {}
+ public static Object getDocComments(JCCompilationUnit cu) {
+ try {
+ return JCCOMPILATIONUNIT_DOCCOMMENTS.get(cu);
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
+ }
+ }
+
+ public static void initDocComments(JCCompilationUnit cu) {
+ try {
+ JCCOMPILATIONUNIT_DOCCOMMENTS.set(cu, new HashMap<Object, String>());
+ } catch (IllegalArgumentException e) {
+ // That's fine - we're on JDK8, we'll fix that later.
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
}
+ }
+
+ public static int getEndPosition(DiagnosticPosition pos, JCCompilationUnit top) {
try {
- return (Integer) JCTREE_TAG.get(node);
- } catch (Exception e) {
- throw new IllegalStateException("Can't get node tag");
+ Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top);
+ return (Integer) getEndPosition.invoke(pos, endPositions);
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
+ } catch (InvocationTargetException e) {
+ throw sneakyThrow(e.getCause());
}
}
- private static Method method;
+ private static final Class<?> JC_VOID_TYPE, JC_NO_TYPE;
+
+ static {
+ Class<?> c = null;
+ try {
+ c = Class.forName("com.sun.tools.javac.code.Type$JCVoidType");
+ } catch (Throwable ignore) {}
+ JC_VOID_TYPE = c;
+ c = null;
+ try {
+ c = Class.forName("com.sun.tools.javac.code.Type$JCNoType");
+ } catch (Throwable ignore) {}
+ JC_NO_TYPE = c;
+ }
- public static JCClassDecl ClassDef(TreeMaker maker, JCModifiers mods, Name name, List<JCTypeParameter> typarams, JCExpression extending, List<JCExpression> implementing, List<JCTree> defs) {
- if (method == null) try {
- method = TreeMaker.class.getDeclaredMethod("ClassDef", JCModifiers.class, Name.class, List.class, JCExpression.class, List.class, List.class);
- } catch (NoSuchMethodException ignore) {}
- if (method == null) try {
- method = TreeMaker.class.getDeclaredMethod("ClassDef", JCModifiers.class, Name.class, List.class, JCTree.class, List.class, List.class);
- } catch (NoSuchMethodException ignore) {}
+ public static Type createVoidType(JavacTreeMaker maker, TypeTag tag) {
+ if (Javac.getJavaCompilerVersion() < 8) {
+ return new JCNoType(((Integer) tag.value).intValue());
+ } else {
+ try {
+ if (CTC_VOID.equals(tag)) {
+ return (Type) JC_VOID_TYPE.newInstance();
+ } else {
+ return (Type) JC_NO_TYPE.newInstance();
+ }
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
+ } catch (InstantiationException e) {
+ throw sneakyThrow(e);
+ }
+ }
+ }
+
+ private static class JCNoType extends Type implements NoType {
+ public JCNoType(int tag) {
+ super(tag, null);
+ }
- if (method == null) throw new IllegalStateException("Lombok bug #20130617-1310: ClassDef doesn't look like anything we thought it would look like.");
- if (!Modifier.isPublic(method.getModifiers()) && !method.isAccessible()) {
- method.setAccessible(true);
+ @Override
+ public TypeKind getKind() {
+ if (tag == ((Integer) CTC_VOID.value).intValue()) return TypeKind.VOID;
+ if (tag == ((Integer) CTC_NONE.value).intValue()) return TypeKind.NONE;
+ throw new AssertionError("Unexpected tag: " + tag);
}
- try {
- return (JCClassDecl) method.invoke(maker, mods, name, typarams, extending, implementing, defs);
- } catch (InvocationTargetException e) {
- throw sneakyThrow(e.getCause());
- } catch (IllegalAccessException e) {
- throw sneakyThrow(e.getCause());
+ @Override
+ public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+ return v.visitNoType(this, p);
}
}
- private static RuntimeException sneakyThrow(Throwable t) {
+ private static final Field JCCOMPILATIONUNIT_ENDPOSITIONS, JCCOMPILATIONUNIT_DOCCOMMENTS;
+ static {
+ Field f = null;
+ try {
+ f = JCCompilationUnit.class.getDeclaredField("endPositions");
+ } catch (NoSuchFieldException e) {}
+ JCCOMPILATIONUNIT_ENDPOSITIONS = f;
+
+ f = null;
+ try {
+ f = JCCompilationUnit.class.getDeclaredField("docComments");
+ } catch (NoSuchFieldException e) {}
+ JCCOMPILATIONUNIT_DOCCOMMENTS = f;
+ }
+
+ static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
Javac.<RuntimeException>sneakyThrow0(t);
return null;
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
new file mode 100644
index 00000000..12baf5af
--- /dev/null
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -0,0 +1,830 @@
+/*
+ * 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);
+ }
+} \ 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) {
diff --git a/src/utils/lombok/javac/java6/CommentCollectingParser.java b/src/utils/lombok/javac/java6/CommentCollectingParser.java
index 94a85e55..30192b06 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingParser.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingParser.java
@@ -1,3 +1,24 @@
+/*
+ * 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.java6;
import java.util.Map;
diff --git a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
index 7e34b723..b250b898 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
@@ -1,3 +1,24 @@
+/*
+ * 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.java6;
import java.lang.reflect.Field;
diff --git a/src/utils/lombok/javac/java6/CommentCollectingScanner.java b/src/utils/lombok/javac/java6/CommentCollectingScanner.java
index b584ec16..df383b93 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingScanner.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingScanner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Project Lombok Authors.
+ * Copyright (C) 2011-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
@@ -27,11 +27,12 @@ import lombok.javac.CommentInfo;
import lombok.javac.CommentInfo.EndConnection;
import lombok.javac.CommentInfo.StartConnection;
+import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
-public class CommentCollectingScanner extends DocCommentScanner {
- private final ListBuffer<CommentInfo> comments = ListBuffer.lb();
+public class CommentCollectingScanner extends Scanner {
+ private final ListBuffer<CommentInfo> comments = new ListBuffer<CommentInfo>();
private int endComment = 0;
public CommentCollectingScanner(CommentCollectingScannerFactory factory, CharBuffer charBuffer) {
diff --git a/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java
index f3d6bd72..b7d8ed13 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java
@@ -26,7 +26,7 @@ import java.nio.CharBuffer;
import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.util.Context;
-public class CommentCollectingScannerFactory extends DocCommentScanner.Factory {
+public class CommentCollectingScannerFactory extends Scanner.Factory {
@SuppressWarnings("all")
public static void preRegister(final Context context) {
diff --git a/src/utils/lombok/javac/java6/DocCommentScanner.java b/src/utils/lombok/javac/java6/DocCommentScanner.java
deleted file mode 100644
index ff3eadd4..00000000
--- a/src/utils/lombok/javac/java6/DocCommentScanner.java
+++ /dev/null
@@ -1,461 +0,0 @@
-package lombok.javac.java6;
-
-/*
- * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import static com.sun.tools.javac.util.LayoutCharacters.*;
-
-import java.nio.CharBuffer;
-
-import com.sun.tools.javac.parser.Scanner;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Position;
-
-/** An extension to the base lexical analyzer that captures
- * and processes the contents of doc comments. It does so by
- * translating Unicode escape sequences and by stripping the
- * leading whitespace and starts from each line of the comment.
- *
- * <p><b>This is NOT part of any API supported by Sun Microsystems. If
- * you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.</b>
- */
-public class DocCommentScanner extends Scanner {
-
- /** A factory for creating scanners. */
- public static class Factory extends Scanner.Factory {
-
- @SuppressWarnings({"unchecked", "all"})
- public static void preRegister(final Context context) {
- context.put(scannerFactoryKey, new Context.Factory() {
- public Object make() {
- return new Factory(context);
- }
-
- public Object make(Context c) {
- return new Factory(c);
- }
- });
- }
-
- /** Create a new scanner factory. */
- protected Factory(Context context) {
- super(context);
- }
-
- @Override
- public Scanner newScanner(CharSequence input) {
- if (input instanceof CharBuffer) {
- return new DocCommentScanner(this, (CharBuffer)input);
- } else {
- char[] array = input.toString().toCharArray();
- return newScanner(array, array.length);
- }
- }
-
- @Override
- public Scanner newScanner(char[] input, int inputLength) {
- return new DocCommentScanner(this, input, inputLength);
- }
- }
-
-
- /** Create a scanner from the input buffer. buffer must implement
- * array() and compact(), and remaining() must be less than limit().
- */
- protected DocCommentScanner(Factory fac, CharBuffer buffer) {
- super(fac, buffer);
- }
-
- /** Create a scanner from the input array. The array must have at
- * least a single character of extra space.
- */
- protected DocCommentScanner(Factory fac, char[] input, int inputLength) {
- super(fac, input, inputLength);
- }
-
- /** Starting position of the comment in original source
- */
- private int pos;
-
- /** The comment input buffer, index of next chacter to be read,
- * index of one past last character in buffer.
- */
- private char[] buf;
- private int bp;
- private int buflen;
-
- /** The current character.
- */
- private char ch;
-
- /** The column number position of the current character.
- */
- private int col;
-
- /** The buffer index of the last converted Unicode character
- */
- private int unicodeConversionBp = 0;
-
- /**
- * Buffer for doc comment.
- */
- private char[] docCommentBuffer = new char[1024];
-
- /**
- * Number of characters in doc comment buffer.
- */
- private int docCommentCount;
-
- /**
- * Translated and stripped contents of doc comment
- */
- private String docComment = null;
-
-
- /** Unconditionally expand the comment buffer.
- */
- private void expandCommentBuffer() {
- char[] newBuffer = new char[docCommentBuffer.length * 2];
- System.arraycopy(docCommentBuffer, 0, newBuffer,
- 0, docCommentBuffer.length);
- docCommentBuffer = newBuffer;
- }
-
- /** Convert an ASCII digit from its base (8, 10, or 16)
- * to its value.
- */
- private int digit(int base) {
- char c = ch;
- int result = Character.digit(c, base);
- if (result >= 0 && c > 0x7f) {
- ch = "0123456789abcdef".charAt(result);
- }
- return result;
- }
-
- /** Convert Unicode escape; bp points to initial '\' character
- * (Spec 3.3).
- */
- private void convertUnicode() {
- if (ch == '\\' && unicodeConversionBp != bp) {
- bp++; ch = buf[bp]; col++;
- if (ch == 'u') {
- do {
- bp++; ch = buf[bp]; col++;
- } while (ch == 'u');
- int limit = bp + 3;
- if (limit < buflen) {
- int d = digit(16);
- int code = d;
- while (bp < limit && d >= 0) {
- bp++; ch = buf[bp]; col++;
- d = digit(16);
- code = (code << 4) + d;
- }
- if (d >= 0) {
- ch = (char)code;
- unicodeConversionBp = bp;
- return;
- }
- }
- // "illegal.Unicode.esc", reported by base scanner
- } else {
- bp--;
- ch = '\\';
- col--;
- }
- }
- }
-
-
- /** Read next character.
- */
- private void scanChar() {
- bp++;
- ch = buf[bp];
- switch (ch) {
- case '\r': // return
- col = 0;
- break;
- case '\n': // newline
- if (bp == 0 || buf[bp-1] != '\r') {
- col = 0;
- }
- break;
- case '\t': // tab
- col = (col / TabInc * TabInc) + TabInc;
- break;
- case '\\': // possible Unicode
- col++;
- convertUnicode();
- break;
- default:
- col++;
- break;
- }
- }
-
- /**
- * Read next character in doc comment, skipping over double '\' characters.
- * If a double '\' is skipped, put in the buffer and update buffer count.
- */
- private void scanDocCommentChar() {
- scanChar();
- if (ch == '\\') {
- if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = ch;
- bp++; col++;
- } else {
- convertUnicode();
- }
- }
- }
-
- /* Reset doc comment before reading each new token
- */
- public void nextToken() {
- docComment = null;
- super.nextToken();
- }
-
- /**
- * Returns the documentation string of the current token.
- */
- public String docComment() {
- return docComment;
- }
-
- /**
- * Process a doc comment and make the string content available.
- * Strips leading whitespace and stars.
- */
- @SuppressWarnings("fallthrough")
- protected void processComment(CommentStyle style) {
- if (style != CommentStyle.JAVADOC) {
- return;
- }
-
- pos = pos();
- buf = getRawCharacters(pos, endPos());
- buflen = buf.length;
- bp = 0;
- col = 0;
-
- docCommentCount = 0;
-
- boolean firstLine = true;
-
- // Skip over first slash
- scanDocCommentChar();
- // Skip over first star
- scanDocCommentChar();
-
- // consume any number of stars
- while (bp < buflen && ch == '*') {
- scanDocCommentChar();
- }
- // is the comment in the form /**/, /***/, /****/, etc. ?
- if (bp < buflen && ch == '/') {
- docComment = "";
- return;
- }
-
- // skip a newline on the first line of the comment.
- if (bp < buflen) {
- if (ch == LF) {
- scanDocCommentChar();
- firstLine = false;
- } else if (ch == CR) {
- scanDocCommentChar();
- if (ch == LF) {
- scanDocCommentChar();
- firstLine = false;
- }
- }
- }
-
- outerLoop:
-
- // The outerLoop processes the doc comment, looping once
- // for each line. For each line, it first strips off
- // whitespace, then it consumes any stars, then it
- // puts the rest of the line into our buffer.
- while (bp < buflen) {
-
- // The wsLoop consumes whitespace from the beginning
- // of each line.
- wsLoop:
-
- while (bp < buflen) {
- switch(ch) {
- case ' ':
- scanDocCommentChar();
- break;
- case '\t':
- col = ((col - 1) / TabInc * TabInc) + TabInc;
- scanDocCommentChar();
- break;
- case FF:
- col = 0;
- scanDocCommentChar();
- break;
-// Treat newline at beginning of line (blank line, no star)
-// as comment text. Old Javadoc compatibility requires this.
-/*---------------------------------*
- case CR: // (Spec 3.4)
- scanDocCommentChar();
- if (ch == LF) {
- col = 0;
- scanDocCommentChar();
- }
- break;
- case LF: // (Spec 3.4)
- scanDocCommentChar();
- break;
-*---------------------------------*/
- default:
- // we've seen something that isn't whitespace;
- // jump out.
- break wsLoop;
- }
- }
-
- // Are there stars here? If so, consume them all
- // and check for the end of comment.
- if (ch == '*') {
- // skip all of the stars
- do {
- scanDocCommentChar();
- } while (ch == '*');
-
- // check for the closing slash.
- if (ch == '/') {
- // We're done with the doc comment
- // scanChar() and breakout.
- break outerLoop;
- }
- } else if (! firstLine) {
- //The current line does not begin with a '*' so we will indent it.
- for (int i = 1; i < col; i++) {
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = ' ';
- }
- }
-
- // The textLoop processes the rest of the characters
- // on the line, adding them to our buffer.
- textLoop:
- while (bp < buflen) {
- switch (ch) {
- case '*':
- // Is this just a star? Or is this the
- // end of a comment?
- scanDocCommentChar();
- if (ch == '/') {
- // This is the end of the comment,
- // set ch and return our buffer.
- break outerLoop;
- }
- // This is just an ordinary star. Add it to
- // the buffer.
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = '*';
- break;
- case ' ':
- case '\t':
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = ch;
- scanDocCommentChar();
- break;
- case FF:
- scanDocCommentChar();
- break textLoop; // treat as end of line
- case CR: // (Spec 3.4)
- scanDocCommentChar();
- if (ch != LF) {
- // Canonicalize CR-only line terminator to LF
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = (char)LF;
- break textLoop;
- }
- /* fall through to LF case */
- case LF: // (Spec 3.4)
- // We've seen a newline. Add it to our
- // buffer and break out of this loop,
- // starting fresh on a new line.
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = ch;
- scanDocCommentChar();
- break textLoop;
- default:
- // Add the character to our buffer.
- if (docCommentCount == docCommentBuffer.length)
- expandCommentBuffer();
- docCommentBuffer[docCommentCount++] = ch;
- scanDocCommentChar();
- }
- } // end textLoop
- firstLine = false;
- } // end outerLoop
-
- if (docCommentCount > 0) {
- int i = docCommentCount - 1;
- trailLoop:
- while (i > -1) {
- switch (docCommentBuffer[i]) {
- case '*':
- i--;
- break;
- default:
- break trailLoop;
- }
- }
- docCommentCount = i + 1;
-
- // Store the text of the doc comment
- docComment = new String(docCommentBuffer, 0 , docCommentCount);
- } else {
- docComment = "";
- }
- }
-
- /** Build a map for translating between line numbers and
- * positions in the input.
- *
- * @return a LineMap */
- public Position.LineMap getLineMap() {
- char[] buf = getRawCharacters();
- return Position.makeLineMap(buf, buf.length, true);
- }
-}
diff --git a/src/utils/lombok/javac/java7/CommentCollectingParser.java b/src/utils/lombok/javac/java7/CommentCollectingParser.java
index 82f19c42..0e8a4ef6 100644
--- a/src/utils/lombok/javac/java7/CommentCollectingParser.java
+++ b/src/utils/lombok/javac/java7/CommentCollectingParser.java
@@ -1,3 +1,24 @@
+/*
+ * 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.java7;
import java.util.List;
diff --git a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
index e9575c14..ed8279df 100644
--- a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
@@ -1,3 +1,24 @@
+/*
+ * 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.java7;
import java.lang.reflect.Field;
diff --git a/src/utils/lombok/javac/java7/CommentCollectingScanner.java b/src/utils/lombok/javac/java7/CommentCollectingScanner.java
index 6ebd3ac1..3f76f910 100644
--- a/src/utils/lombok/javac/java7/CommentCollectingScanner.java
+++ b/src/utils/lombok/javac/java7/CommentCollectingScanner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Project Lombok Authors.
+ * Copyright (C) 2011-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
@@ -27,12 +27,12 @@ import lombok.javac.CommentInfo;
import lombok.javac.CommentInfo.EndConnection;
import lombok.javac.CommentInfo.StartConnection;
+import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.parser.DocCommentScanner;
-public class CommentCollectingScanner extends DocCommentScanner {
- private final ListBuffer<CommentInfo> comments = ListBuffer.lb();
+public class CommentCollectingScanner extends Scanner {
+ private final ListBuffer<CommentInfo> comments = new ListBuffer<CommentInfo>();
private int endComment = 0;
public CommentCollectingScanner(CommentCollectingScannerFactory factory, CharBuffer charBuffer) {
diff --git a/src/utils/lombok/javac/java8/CommentCollectingParser.java b/src/utils/lombok/javac/java8/CommentCollectingParser.java
new file mode 100644
index 00000000..e305e44f
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingParser.java
@@ -0,0 +1,53 @@
+/*
+ * 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.java8;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.javac.CommentInfo;
+
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.Lexer;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+
+class CommentCollectingParser extends JavacParser {
+ private final Map<JCCompilationUnit, List<CommentInfo>> commentsMap;
+ private final Lexer lexer;
+
+ protected CommentCollectingParser(ParserFactory fac, Lexer S,
+ boolean keepDocComments, boolean keepLineMap, boolean keepEndPositions, Map<JCCompilationUnit, List<CommentInfo>> commentsMap) {
+ super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
+ lexer = S;
+ this.commentsMap = commentsMap;
+ }
+
+ public JCCompilationUnit parseCompilationUnit() {
+ JCCompilationUnit result = super.parseCompilationUnit();
+ if (lexer instanceof CommentCollectingScanner) {
+ List<CommentInfo> comments = ((CommentCollectingScanner)lexer).getComments();
+ commentsMap.put(result, comments);
+ }
+ return result;
+ }
+} \ No newline at end of file
diff --git a/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
new file mode 100644
index 00000000..6b5f9198
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
@@ -0,0 +1,73 @@
+/*
+ * 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.java8;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+
+import lombok.javac.CommentInfo;
+
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.Lexer;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
+
+public class CommentCollectingParserFactory extends ParserFactory {
+ private final Map<JCCompilationUnit, List<CommentInfo>> commentsMap;
+ private final Context context;
+
+ static Context.Key<ParserFactory> key() {
+ return parserFactoryKey;
+ }
+
+ protected CommentCollectingParserFactory(Context context, Map<JCCompilationUnit, List<CommentInfo>> commentsMap) {
+ super(context);
+ this.context = context;
+ this.commentsMap = commentsMap;
+ }
+
+ public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
+ ScannerFactory scannerFactory = ScannerFactory.instance(context);
+ Lexer lexer = scannerFactory.newScanner(input, true);
+ Object x = new CommentCollectingParser(this, lexer, true, keepLineMap, keepEndPos, commentsMap);
+ return (JavacParser) x;
+ // CCP is based on a stub which extends nothing, but at runtime the stub is replaced with either
+ //javac6's EndPosParser which extends Parser, or javac8's JavacParser which implements Parser.
+ //Either way this will work out.
+ }
+
+ public static void setInCompiler(JavaCompiler compiler, Context context, Map<JCCompilationUnit, List<CommentInfo>> commentsMap) {
+ context.put(CommentCollectingParserFactory.key(), (ParserFactory)null);
+ Field field;
+ try {
+ field = JavaCompiler.class.getDeclaredField("parserFactory");
+ field.setAccessible(true);
+ field.set(compiler, new CommentCollectingParserFactory(context, commentsMap));
+ } catch (Exception e) {
+ throw new IllegalStateException("Could not set comment sensitive parser in the compiler", e);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/utils/lombok/javac/java8/CommentCollectingScanner.java b/src/utils/lombok/javac/java8/CommentCollectingScanner.java
new file mode 100644
index 00000000..b59a9390
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingScanner.java
@@ -0,0 +1,42 @@
+/*
+ * 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.java8;
+
+import lombok.javac.CommentInfo;
+
+import com.sun.tools.javac.parser.Scanner;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.util.List;
+
+public class CommentCollectingScanner extends Scanner {
+
+ private CommentCollectingTokenizer tokenizer;
+
+ public CommentCollectingScanner(ScannerFactory fac, CommentCollectingTokenizer tokenizer) {
+ super(fac, tokenizer);
+ this.tokenizer = tokenizer;
+ }
+
+ public List<CommentInfo> getComments() {
+ return tokenizer.getComments();
+ }
+} \ No newline at end of file
diff --git a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
new file mode 100644
index 00000000..fa79ff67
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011-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.java8;
+
+import java.nio.CharBuffer;
+
+import com.sun.tools.javac.parser.Scanner;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.util.Context;
+
+public class CommentCollectingScannerFactory extends ScannerFactory {
+
+ @SuppressWarnings("all")
+ public static void preRegister(final Context context) {
+ if (context.get(scannerFactoryKey) == null) {
+ // Careful! There is voodoo magic here!
+ //
+ // Context.Factory is parameterized. make() is for javac6 and below; make(Context) is for javac7 and up.
+ // this anonymous inner class definition is intentionally 'raw' - the return type of both 'make' methods is 'T',
+ // which means the compiler will only generate the correct "real" override method (with returntype Object, which is
+ // the lower bound for T, as a synthetic accessor for the make with returntype ScannerFactory) for that make method which
+ // is actually on the classpath (either make() for javac6-, or make(Context) for javac7+).
+ //
+ // We normally solve this issue via src/stubs, with BOTH make methods listed, but for some reason the presence of a stubbed out
+ // Context (or even a complete copy, it doesn't matter) results in a really strange eclipse bug, where any mention of any kind
+ // of com.sun.tools.javac.tree.TreeMaker in a source file disables ALL usage of 'go to declaration' and auto-complete in the entire
+ // source file.
+ //
+ // Thus, in short:
+ // * Do NOT parameterize the anonymous inner class literal.
+ // * Leave the return types as 'j.l.Object'.
+ // * Leave both make methods intact; deleting one has no effect on javac6- / javac7+, but breaks the other. Hard to test for.
+ // * Do not stub com.sun.tools.javac.util.Context or any of its inner types, like Factory.
+ @SuppressWarnings("all")
+ class MyFactory implements Context.Factory {
+ // This overrides the javac6- version of make.
+ public Object make() {
+ return new CommentCollectingScannerFactory(context);
+ }
+
+ // This overrides the javac7+ version.
+ public Object make(Context c) {
+ return new CommentCollectingScannerFactory(c);
+ }
+ }
+ @SuppressWarnings("unchecked") Context.Factory<ScannerFactory> factory = new MyFactory();
+ context.put(scannerFactoryKey, factory);
+ }
+ }
+
+ /** Create a new scanner factory. */
+ protected CommentCollectingScannerFactory(Context context) {
+ super(context);
+ }
+
+ @Override
+ public Scanner newScanner(CharSequence input, boolean keepDocComments) {
+ if (input instanceof CharBuffer) {
+ CharBuffer buf = (CharBuffer) input;
+ return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, buf));
+ }
+ char[] array = input.toString().toCharArray();
+ return newScanner(array, array.length, keepDocComments);
+ }
+
+ @Override
+ public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
+ return new CommentCollectingScanner(this, new CommentCollectingTokenizer(this, input, inputLength));
+ }
+}
diff --git a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
new file mode 100644
index 00000000..1834fb00
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
@@ -0,0 +1,129 @@
+/*
+ * 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.java8;
+
+import java.nio.CharBuffer;
+
+import lombok.javac.CommentInfo;
+import lombok.javac.CommentInfo.EndConnection;
+import lombok.javac.CommentInfo.StartConnection;
+
+import com.sun.tools.javac.parser.JavaTokenizer;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.parser.Tokens.Token;
+import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
+import com.sun.tools.javac.parser.UnicodeReader;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+
+class CommentCollectingTokenizer extends JavaTokenizer {
+ private int prevEndPosition = 0;
+ private final ListBuffer<CommentInfo> comments = new ListBuffer<CommentInfo>();
+ private int endComment = 0;
+
+ CommentCollectingTokenizer(ScannerFactory fac, char[] buf, int inputLength) {
+ super(fac, new PositionUnicodeReader(fac, buf, inputLength));
+ }
+
+ CommentCollectingTokenizer(ScannerFactory fac, CharBuffer buf) {
+ super(fac, new PositionUnicodeReader(fac, buf));
+ }
+
+ @Override public Token readToken() {
+ Token token = super.readToken();
+ prevEndPosition = ((PositionUnicodeReader)reader).pos();
+ return token;
+ }
+
+ @Override
+ protected Comment processComment(int pos, int endPos, CommentStyle style) {
+ int prevEndPos = Math.max(prevEndPosition, endComment);
+ endComment = endPos;
+ String content = new String(reader.getRawCharacters(pos, endPos));
+ StartConnection start = determineStartConnection(prevEndPos, pos);
+ EndConnection end = determineEndConnection(endPos);
+
+ CommentInfo comment = new CommentInfo(prevEndPos, pos, endPos, content, start, end);
+ comments.append(comment);
+
+ return super.processComment(pos, endPos, style);
+ }
+
+ private EndConnection determineEndConnection(int pos) {
+ boolean first = true;
+ for (int i = pos;; i++) {
+ char c;
+ try {
+ c = reader.getRawCharacters(i, i + 1)[0];
+ } catch (IndexOutOfBoundsException e) {
+ c = '\n';
+ }
+ if (isNewLine(c)) {
+ return EndConnection.ON_NEXT_LINE;
+ }
+ if (Character.isWhitespace(c)) {
+ first = false;
+ continue;
+ }
+ return first ? EndConnection.DIRECT_AFTER_COMMENT : EndConnection.AFTER_COMMENT;
+ }
+ }
+
+ private StartConnection determineStartConnection(int from, int to) {
+ if (from == to) {
+ return StartConnection.DIRECT_AFTER_PREVIOUS;
+ }
+ char[] between = reader.getRawCharacters(from, to);
+ if (isNewLine(between[between.length - 1])) {
+ return StartConnection.START_OF_LINE;
+ }
+ for (char c : between) {
+ if (isNewLine(c)) {
+ return StartConnection.ON_NEXT_LINE;
+ }
+ }
+ return StartConnection.AFTER_PREVIOUS;
+ }
+
+ private boolean isNewLine(char c) {
+ return c == '\n' || c == '\r';
+ }
+
+ public List<CommentInfo> getComments() {
+ return comments.toList();
+ }
+
+ static class PositionUnicodeReader extends UnicodeReader {
+ protected PositionUnicodeReader(ScannerFactory sf, char[] input, int inputLength) {
+ super(sf, input, inputLength);
+ }
+
+ public PositionUnicodeReader(ScannerFactory sf, CharBuffer buffer) {
+ super(sf, buffer);
+ }
+
+ int pos() {
+ return bp;
+ }
+ }
+} \ No newline at end of file