aboutsummaryrefslogtreecommitdiff
path: root/src/utils/lombok/javac/java8
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/lombok/javac/java8')
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParser.java32
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParserFactory.java52
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScanner.java21
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java89
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingTokenizer.java108
5 files changed, 302 insertions, 0 deletions
diff --git a/src/utils/lombok/javac/java8/CommentCollectingParser.java b/src/utils/lombok/javac/java8/CommentCollectingParser.java
new file mode 100644
index 00000000..6cf65dca
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingParser.java
@@ -0,0 +1,32 @@
+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..594ff8ba
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
@@ -0,0 +1,52 @@
+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..1b8474ac
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingScanner.java
@@ -0,0 +1,21 @@
+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..95945f8f
--- /dev/null
+++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java
@@ -0,0 +1,108 @@
+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 = ListBuffer.lb();
+ 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