aboutsummaryrefslogtreecommitdiff
path: root/src/utils/lombok/javac/java6
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2013-07-22 23:23:46 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2013-07-22 23:23:46 +0200
commit45697b50816df79475a8bb69dc89ff68747fbfe6 (patch)
tree25cb023eec1f74baf5063cc5a58a5351ee43d6f0 /src/utils/lombok/javac/java6
parent4c03e3d220900431085897878d4888bf530b31ec (diff)
parentdeed98be16e5099af52d951fc611f86a82a42858 (diff)
downloadlombok-45697b50816df79475a8bb69dc89ff68747fbfe6.tar.gz
lombok-45697b50816df79475a8bb69dc89ff68747fbfe6.tar.bz2
lombok-45697b50816df79475a8bb69dc89ff68747fbfe6.zip
Merge branch 'master' into jdk8. Also added some major fixes whilst merging.
Conflicts: src/core/lombok/javac/handlers/JavacHandlerUtil.java src/utils/lombok/javac/CommentCatcher.java src/utils/lombok/javac/Javac.java
Diffstat (limited to 'src/utils/lombok/javac/java6')
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingParserFactory.java2
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingScanner.java5
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java37
-rw-r--r--src/utils/lombok/javac/java6/DocCommentScanner.java461
4 files changed, 495 insertions, 10 deletions
diff --git a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
index b2a248c8..7e34b723 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
@@ -25,7 +25,7 @@ public class CommentCollectingParserFactory extends Parser.Factory {
}
@Override public Parser newParser(Lexer S, boolean keepDocComments, boolean genEndPos) {
- Object x = new CommentCollectingParser(this, S, keepDocComments, commentsMap);
+ Object x = new CommentCollectingParser(this, S, true, commentsMap);
return (Parser) 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 javac7's EndPosParser which implements Parser.
diff --git a/src/utils/lombok/javac/java6/CommentCollectingScanner.java b/src/utils/lombok/javac/java6/CommentCollectingScanner.java
index 66e1514d..b584ec16 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingScanner.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingScanner.java
@@ -27,12 +27,10 @@ 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 Scanner {
+public class CommentCollectingScanner extends DocCommentScanner {
private final ListBuffer<CommentInfo> comments = ListBuffer.lb();
private int endComment = 0;
@@ -56,6 +54,7 @@ public class CommentCollectingScanner extends Scanner {
CommentInfo comment = new CommentInfo(prevEndPos, pos, endPos, content, start, end);
comments.append(comment);
+ super.processComment(style);
}
private EndConnection determineEndConnection(int pos) {
diff --git a/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java
index 30acbd5a..f3d6bd72 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingScannerFactory.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
@@ -26,19 +26,44 @@ import java.nio.CharBuffer;
import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.util.Context;
-public class CommentCollectingScannerFactory extends Scanner.Factory {
+public class CommentCollectingScannerFactory extends DocCommentScanner.Factory {
+ @SuppressWarnings("all")
public static void preRegister(final Context context) {
if (context.get(scannerFactoryKey) == null) {
- context.put(scannerFactoryKey, new Context.Factory<Scanner.Factory>() {
- public CommentCollectingScanner.Factory make() {
+ // 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);
}
- public CommentCollectingScanner.Factory make(Context c) {
+ // This overrides the javac7+ version of make.
+ public Object make(Context c) {
return new CommentCollectingScannerFactory(c);
}
- });
+ }
+
+ @SuppressWarnings("unchecked") Context.Factory<Scanner.Factory> factory = new MyFactory();
+ context.put(scannerFactoryKey, factory);
}
}
diff --git a/src/utils/lombok/javac/java6/DocCommentScanner.java b/src/utils/lombok/javac/java6/DocCommentScanner.java
new file mode 100644
index 00000000..ff3eadd4
--- /dev/null
+++ b/src/utils/lombok/javac/java6/DocCommentScanner.java
@@ -0,0 +1,461 @@
+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);
+ }
+}