// recognized tags
public static final char[] TAG_DEPRECATED = "deprecated".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_PARAM = "param".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_RETURN = "return".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_THROWS = "throws".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_EXCEPTION = "exception".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_SEE = "see".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_LINK = "link".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_LINKPLAIN = "linkplain".toCharArray(); //$NON-NLS-1$
+
public static final char[] TAG_INHERITDOC = "inheritDoc".toCharArray(); //$NON-NLS-1$
-
+
// tags expected positions
public final static int ORDERED_TAGS_NUMBER = 3;
+
public final static int PARAM_TAG_EXPECTED_ORDER = 0;
+
public final static int THROWS_TAG_EXPECTED_ORDER = 1;
+
public final static int SEE_TAG_EXPECTED_ORDER = 2;
-
+
// Kind of comment parser
public final static int COMPIL_PARSER = 0x00000001;
+
public final static int DOM_PARSER = 0x00000002;
-
+
// Public fields
public Scanner scanner;
+
public boolean checkDocComment = false;
-
+
// Protected fields
protected boolean inherited, deprecated;
+
protected char[] source;
+
protected int index, endComment, lineEnd;
- protected int tokenPreviousPosition, lastIdentifierEndPosition, starPosition;
+
+ protected int tokenPreviousPosition, lastIdentifierEndPosition,
+ starPosition;
+
protected int textStart, memberStart;
+
protected int tagSourceStart, tagSourceEnd;
+
protected int inlineTagStart;
+
protected Parser sourceParser;
+
protected Object returnStatement;
+
protected boolean lineStarted = false, inlineTagStarted = false;
+
protected int kind;
+
protected int[] lineEnds;
-
+
// Private fields
private int currentTokenType = -1;
-
+
// Line pointers
private int linePtr, lastLinePtr;
-
+
// Identifier stack
protected int identifierPtr;
+
protected char[][] identifierStack;
+
protected int identifierLengthPtr;
+
protected int[] identifierLengthStack;
+
protected long[] identifierPositionStack;
+
// Ast stack
protected static int AstStackIncrement = 10;
+
protected int astPtr;
+
protected Object[] astStack;
+
protected int astLengthPtr;
+
protected int[] astLengthStack;
protected AbstractCommentParser(Parser sourceParser) {
this.sourceParser = sourceParser;
- this.scanner = new Scanner(false, false, false, false, false, null, null, false);
-
+ this.scanner = new Scanner(false, false, false, false, false, null,
+ null, false);
+
this.identifierStack = new char[20][];
this.identifierPositionStack = new long[20];
this.identifierLengthStack = new int[10];
this.astLengthStack = new int[20];
}
- /* (non-Javadoc)
- * Returns true if tag @deprecated is present in javadoc comment.
+ /*
+ * (non-Javadoc) Returns true if tag
*
- * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
- * slot for being consumed later on.
+ * @deprecated is present in javadoc comment.
+ *
+ * If javadoc checking is enabled, will also construct an Javadoc node,
+ * which will be stored into Parser.javadoc slot for being consumed later
+ * on.
*/
protected boolean parseComment(int javadocStart, int javadocEnd) {
readChar(); // starting '/'
int previousPosition = this.index;
readChar(); // first '*'
- char nextCharacter= readChar(); // second '*'
-
+ char nextCharacter = readChar(); // second '*'
+
// Init local variables
this.astLengthPtr = -1;
this.astPtr = -1;
this.deprecated = false;
this.linePtr = getLineNumber(javadocStart);
this.lastLinePtr = getLineNumber(javadocEnd);
- this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment : this.scanner.getLineEnd(this.linePtr);
+ this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment
+ : this.scanner.getLineEnd(this.linePtr);
this.textStart = -1;
char previousChar = 0;
int invalidTagLineEnd = -1;
int invalidInlineTagLineEnd = -1;
-
+
// Loop on each comment character
while (this.index < this.endComment) {
previousPosition = this.index;
previousChar = nextCharacter;
-
- // Calculate line end (cannot use this.scanner.linePtr as scanner does not parse line ends again)
- if (this.index > (this.lineEnd+1)) {
+
+ // Calculate line end (cannot use this.scanner.linePtr as
+ // scanner does not parse line ends again)
+ if (this.index > (this.lineEnd + 1)) {
updateLineEnd();
}
-
+
// Read next char only if token was consumed
if (this.currentTokenType < 0) {
nextCharacter = readChar(); // consider unicodes
} else {
- previousPosition = this.scanner.getCurrentTokenStartPosition();
+ previousPosition = this.scanner
+ .getCurrentTokenStartPosition();
switch (this.currentTokenType) {
- case ITerminalSymbols.TokenNameRBRACE:
- nextCharacter = '}';
- break;
- case ITerminalSymbols.TokenNameMULTIPLY:
- nextCharacter = '*';
- break;
+ case ITerminalSymbols.TokenNameRBRACE:
+ nextCharacter = '}';
+ break;
+ case ITerminalSymbols.TokenNameMULTIPLY:
+ nextCharacter = '*';
+ break;
default:
- nextCharacter = this.scanner.currentCharacter;
+ nextCharacter = this.scanner.currentCharacter;
}
consumeToken();
}
-
+
if (this.index >= this.endComment) {
break;
}
-
+
switch (nextCharacter) {
- case '@' :
- boolean valid = false;
- // Start tag parsing only if we have a java identifier start character and if we are on line beginning or at inline tag beginning
- if ((!this.lineStarted || previousChar == '{')) {
- this.lineStarted = true;
- if (this.inlineTagStarted) {
- this.inlineTagStarted = false;
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
- // Cannot have @ inside inline comment
- if (this.sourceParser != null) {
- int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
- this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
- }
- validComment = false;
- if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
- pushText(this.textStart, previousPosition);
- }
- if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
+ case '@':
+ boolean valid = false;
+ // Start tag parsing only if we have a java identifier start
+ // character and if we are on line beginning or at inline
+ // tag beginning
+ if ((!this.lineStarted || previousChar == '{')) {
+ this.lineStarted = true;
+ if (this.inlineTagStarted) {
+ this.inlineTagStarted = false;
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+ // Cannot have @ inside inline comment
+ if (this.sourceParser != null) {
+ int end = previousPosition < invalidInlineTagLineEnd ? previousPosition
+ : invalidInlineTagLineEnd;
+ this.sourceParser.problemReporter()
+ .javadocUnterminatedInlineTag(
+ this.inlineTagStart, end);
+ }
+ validComment = false;
+ if (this.lineStarted && this.textStart != -1
+ && this.textStart < previousPosition) {
+ pushText(this.textStart, previousPosition);
}
- if (previousChar == '{') {
- if (this.textStart != -1 && this.textStart < this.inlineTagStart) {
- pushText(this.textStart, this.inlineTagStart);
+ if (this.kind == DOM_PARSER)
+ refreshInlineTagPosition(previousPosition);
+ }
+ if (previousChar == '{') {
+ if (this.textStart != -1
+ && this.textStart < this.inlineTagStart) {
+ pushText(this.textStart, this.inlineTagStart);
+ }
+ this.inlineTagStarted = true;
+ invalidInlineTagLineEnd = this.lineEnd;
+ } else if (this.textStart != -1
+ && this.textStart < invalidTagLineEnd) {
+ pushText(this.textStart, invalidTagLineEnd);
+ }
+ this.scanner.resetTo(this.index, this.endComment);
+ this.currentTokenType = -1; // flush token cache at line
+ // begin
+ try {
+ int token = readTokenAndConsume();
+ this.tagSourceStart = this.scanner
+ .getCurrentTokenStartPosition();
+ this.tagSourceEnd = this.scanner
+ .getCurrentTokenEndPosition();
+ char[] tag = this.scanner
+ .getCurrentIdentifierSource(); // first
+ // token is
+ // either an
+ // identifier
+ // or a
+ // keyword
+ if (this.kind == DOM_PARSER) {
+ // For DOM parser, try to get tag name other
+ // than java identifier
+ // (see bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
+ int tk = token;
+ int le = this.lineEnd;
+ char pc = peekChar();
+ tagNameToken: while (tk != ITerminalSymbols.TokenNameEOF) {
+ this.tagSourceEnd = this.scanner
+ .getCurrentTokenEndPosition();
+ token = tk;
+ // !, ", #, %, &, ', -, :, <, >, * chars and
+ // spaces are not allowed in tag names
+ switch (pc) {
+ case '}':
+ case '!':
+ case '#':
+ case '%':
+ case '&':
+ case '\'':
+ case ':':
+ // case '-': allowed in tag names as
+ // this character is often used in
+ // doclets (bug 68087)
+ case '<':
+ case '>':
+ case '*': // break for '*' as this is
+ // perhaps the end of comment
+ // (bug 65288)
+ break tagNameToken;
+ default:
+ if (pc == ' '
+ || Character.isWhitespace(pc))
+ break tagNameToken;
+ }
+ tk = readTokenAndConsume();
+ pc = peekChar();
}
- this.inlineTagStarted = true;
- invalidInlineTagLineEnd = this.lineEnd;
- } else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) {
- pushText(this.textStart, invalidTagLineEnd);
+ int length = this.tagSourceEnd
+ - this.tagSourceStart + 1;
+ tag = new char[length];
+ System.arraycopy(this.source,
+ this.tagSourceStart, tag, 0, length);
+ this.index = this.tagSourceEnd + 1;
+ this.scanner.currentPosition = this.tagSourceEnd + 1;
+ this.tagSourceStart = previousPosition;
+ this.lineEnd = le;
}
- this.scanner.resetTo(this.index, this.endComment);
- this.currentTokenType = -1; // flush token cache at line begin
- try {
- int token = readTokenAndConsume();
- this.tagSourceStart = this.scanner.getCurrentTokenStartPosition();
- this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
- char[] tag = this.scanner.getCurrentIdentifierSource(); // first token is either an identifier or a keyword
- if (this.kind == DOM_PARSER) {
- // For DOM parser, try to get tag name other than java identifier
- // (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
- int tk = token;
- int le = this.lineEnd;
- char pc = peekChar();
- tagNameToken: while (tk != ITerminalSymbols.TokenNameEOF) {
- this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
- token = tk;
- // !, ", #, %, &, ', -, :, <, >, * chars and spaces are not allowed in tag names
- switch (pc) {
- case '}':
- case '!':
- case '#':
- case '%':
- case '&':
- case '\'':
- case ':':
- // case '-': allowed in tag names as this character is often used in doclets (bug 68087)
- case '<':
- case '>':
- case '*': // break for '*' as this is perhaps the end of comment (bug 65288)
- break tagNameToken;
- default:
- if (pc == ' ' || Character.isWhitespace(pc)) break tagNameToken;
- }
- tk = readTokenAndConsume();
- pc = peekChar();
+ switch (token) {
+ case ITerminalSymbols.TokenNameIdentifier:
+ if (CharOperation.equals(tag, TAG_DEPRECATED)) {
+ this.deprecated = true;
+ if (this.kind == DOM_PARSER) {
+ valid = parseTag();
+ } else {
+ valid = true;
+ }
+ } else if (CharOperation.equals(tag,
+ TAG_INHERITDOC)) {
+ // inhibits inherited flag when tags have
+ // been already stored
+ // see bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
+ // Note that for DOM_PARSER, nodes stack may
+ // be not empty even no '@' tag
+ // was encountered in comment. But it cannot
+ // be the case for COMPILER_PARSER
+ // and so is enough as it is only this
+ // parser which signals the missing tag
+ // warnings...
+ this.inherited = this.astPtr == -1;
+ if (this.kind == DOM_PARSER) {
+ valid = parseTag();
+ } else {
+ valid = true;
+ }
+ } else if (CharOperation.equals(tag, TAG_PARAM)) {
+ valid = parseParam();
+ } else if (CharOperation.equals(tag,
+ TAG_EXCEPTION)) {
+ valid = parseThrows(false);
+ } else if (CharOperation.equals(tag, TAG_SEE)) {
+ if (this.inlineTagStarted) {
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+ // Cannot have @see inside inline
+ // comment
+ valid = false;
+ if (this.sourceParser != null)
+ this.sourceParser
+ .problemReporter()
+ .javadocUnexpectedTag(
+ this.tagSourceStart,
+ this.tagSourceEnd);
+ } else {
+ valid = parseSee(false);
}
- int length = this.tagSourceEnd-this.tagSourceStart+1;
- tag = new char[length];
- System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
- this.index = this.tagSourceEnd+1;
- this.scanner.currentPosition = this.tagSourceEnd+1;
- this.tagSourceStart = previousPosition;
- this.lineEnd = le;
+ } else if (CharOperation.equals(tag, TAG_LINK)) {
+ if (this.inlineTagStarted) {
+ valid = parseSee(false);
+ } else {
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+ // Cannot have @link outside inline
+ // comment
+ valid = false;
+ if (this.sourceParser != null)
+ this.sourceParser
+ .problemReporter()
+ .javadocUnexpectedTag(
+ this.tagSourceStart,
+ this.tagSourceEnd);
+ }
+ } else if (CharOperation.equals(tag,
+ TAG_LINKPLAIN)) {
+ if (this.inlineTagStarted) {
+ valid = parseSee(true);
+ } else {
+ valid = parseTag();
+ }
+ } else {
+ valid = parseTag();
}
- switch (token) {
- case ITerminalSymbols.TokenNameIdentifier :
- if (CharOperation.equals(tag, TAG_DEPRECATED)) {
- this.deprecated = true;
- if (this.kind == DOM_PARSER) {
- valid = parseTag();
- } else {
- valid = true;
- }
- } else if (CharOperation.equals(tag, TAG_INHERITDOC)) {
- // inhibits inherited flag when tags have been already stored
- // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
- // Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
- // was encountered in comment. But it cannot be the case for COMPILER_PARSER
- // and so is enough as it is only this parser which signals the missing tag warnings...
- this.inherited = this.astPtr==-1;
- if (this.kind == DOM_PARSER) {
- valid = parseTag();
- } else {
- valid = true;
- }
- } else if (CharOperation.equals(tag, TAG_PARAM)) {
- valid = parseParam();
- } else if (CharOperation.equals(tag, TAG_EXCEPTION)) {
- valid = parseThrows(false);
- } else if (CharOperation.equals(tag, TAG_SEE)) {
- if (this.inlineTagStarted) {
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
- // Cannot have @see inside inline comment
- valid = false;
- if (this.sourceParser != null)
- this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
- } else {
- valid = parseSee(false);
- }
- } else if (CharOperation.equals(tag, TAG_LINK)) {
- if (this.inlineTagStarted) {
- valid = parseSee(false);
- } else {
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
- // Cannot have @link outside inline comment
- valid = false;
- if (this.sourceParser != null)
- this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
- }
- } else if (CharOperation.equals(tag, TAG_LINKPLAIN)) {
- if (this.inlineTagStarted) {
- valid = parseSee(true);
- } else {
- valid = parseTag();
- }
- } else {
- valid = parseTag();
- }
- break;
- case ITerminalSymbols.TokenNamereturn :
- valid = parseReturn();
- // verify characters after return tag (we're expecting text description)
- if(!verifyCharsAfterReturnTag(this.index)) {
- if (this.sourceParser != null) {
- int end = this.starPosition == -1 || this.lineEnd<this.starPosition ? this.lineEnd : this.starPosition;
- this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, end);
- }
- }
- break;
-// case ITerminalSymbols.TokenNamethrows :
-// valid = parseThrows(true);
-// break;
- default:
- if (this.kind == DOM_PARSER) {
- switch (token) {
- case ITerminalSymbols.TokenNameabstract:
-// case ITerminalSymbols.TokenNameassert:
-// case ITerminalSymbols.TokenNameboolean:
- case ITerminalSymbols.TokenNamebreak:
-// case ITerminalSymbols.TokenNamebyte:
- case ITerminalSymbols.TokenNamecase:
- case ITerminalSymbols.TokenNamecatch:
-// case ITerminalSymbols.TokenNamechar:
- case ITerminalSymbols.TokenNameclass:
- case ITerminalSymbols.TokenNamecontinue:
- case ITerminalSymbols.TokenNamedefault:
- case ITerminalSymbols.TokenNamedo:
-// case ITerminalSymbols.TokenNamedouble:
- case ITerminalSymbols.TokenNameelse:
- case ITerminalSymbols.TokenNameextends:
-// case ITerminalSymbols.TokenNamefalse:
- case ITerminalSymbols.TokenNamefinal:
- case ITerminalSymbols.TokenNamefinally:
-// case ITerminalSymbols.TokenNamefloat:
- case ITerminalSymbols.TokenNamefor:
- case ITerminalSymbols.TokenNameif:
- case ITerminalSymbols.TokenNameimplements:
-// case ITerminalSymbols.TokenNameimport:
- case ITerminalSymbols.TokenNameinstanceof:
-// case ITerminalSymbols.TokenNameint:
- case ITerminalSymbols.TokenNameinterface:
-// case ITerminalSymbols.TokenNamelong:
-// case ITerminalSymbols.TokenNamenative:
- case ITerminalSymbols.TokenNamenew:
-// case ITerminalSymbols.TokenNamenull:
-// case ITerminalSymbols.TokenNamepackage:
- case ITerminalSymbols.TokenNameprivate:
- case ITerminalSymbols.TokenNameprotected:
- case ITerminalSymbols.TokenNamepublic:
-// case ITerminalSymbols.TokenNameshort:
- case ITerminalSymbols.TokenNamestatic:
-// case ITerminalSymbols.TokenNamestrictfp:
- case ITerminalSymbols.TokenNamesuper:
- case ITerminalSymbols.TokenNameswitch:
-// case ITerminalSymbols.TokenNamesynchronized:
-// case ITerminalSymbols.TokenNamethis:
- case ITerminalSymbols.TokenNamethrow:
-// case ITerminalSymbols.TokenNametransient:
-// case ITerminalSymbols.TokenNametrue:
- case ITerminalSymbols.TokenNametry:
-// case ITerminalSymbols.TokenNamevoid:
-// case ITerminalSymbols.TokenNamevolatile:
- case ITerminalSymbols.TokenNamewhile:
- valid = parseTag();
- break;
- }
- }
+ break;
+ case ITerminalSymbols.TokenNamereturn:
+ valid = parseReturn();
+ // verify characters after return tag (we're
+ // expecting text description)
+ if (!verifyCharsAfterReturnTag(this.index)) {
+ if (this.sourceParser != null) {
+ int end = this.starPosition == -1
+ || this.lineEnd < this.starPosition ? this.lineEnd
+ : this.starPosition;
+ this.sourceParser.problemReporter()
+ .javadocInvalidTag(
+ this.tagSourceStart,
+ end);
+ }
}
- this.textStart = this.index;
- if (!valid) {
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
- // do not stop the inline tag when error is encountered to get text after
- validComment = false;
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
- // for DOM AST node, store tag as text in case of invalid syntax
- if (this.kind == DOM_PARSER) {
- parseTag();
- this.textStart = this.tagSourceEnd+1;
- invalidTagLineEnd = this.lineEnd;
+ break;
+ // case ITerminalSymbols.TokenNamethrows :
+ // valid = parseThrows(true);
+ // break;
+ default:
+ if (this.kind == DOM_PARSER) {
+ switch (token) {
+ case ITerminalSymbols.TokenNameabstract:
+ // case
+ // ITerminalSymbols.TokenNameassert:
+ // case
+ // ITerminalSymbols.TokenNameboolean:
+ case ITerminalSymbols.TokenNamebreak:
+ // case ITerminalSymbols.TokenNamebyte:
+ case ITerminalSymbols.TokenNamecase:
+ case ITerminalSymbols.TokenNamecatch:
+ // case ITerminalSymbols.TokenNamechar:
+ case ITerminalSymbols.TokenNameclass:
+ case ITerminalSymbols.TokenNamecontinue:
+ case ITerminalSymbols.TokenNamedefault:
+ case ITerminalSymbols.TokenNamedo:
+ // case
+ // ITerminalSymbols.TokenNamedouble:
+ case ITerminalSymbols.TokenNameelse:
+ case ITerminalSymbols.TokenNameextends:
+ // case ITerminalSymbols.TokenNamefalse:
+ case ITerminalSymbols.TokenNamefinal:
+ case ITerminalSymbols.TokenNamefinally:
+ // case ITerminalSymbols.TokenNamefloat:
+ case ITerminalSymbols.TokenNamefor:
+ case ITerminalSymbols.TokenNameif:
+ case ITerminalSymbols.TokenNameimplements:
+ // case
+ // ITerminalSymbols.TokenNameimport:
+ case ITerminalSymbols.TokenNameinstanceof:
+ // case ITerminalSymbols.TokenNameint:
+ case ITerminalSymbols.TokenNameinterface:
+ // case ITerminalSymbols.TokenNamelong:
+ // case
+ // ITerminalSymbols.TokenNamenative:
+ case ITerminalSymbols.TokenNamenew:
+ // case ITerminalSymbols.TokenNamenull:
+ // case
+ // ITerminalSymbols.TokenNamepackage:
+ case ITerminalSymbols.TokenNameprivate:
+ case ITerminalSymbols.TokenNameprotected:
+ case ITerminalSymbols.TokenNamepublic:
+ // case ITerminalSymbols.TokenNameshort:
+ case ITerminalSymbols.TokenNamestatic:
+ // case
+ // ITerminalSymbols.TokenNamestrictfp:
+ case ITerminalSymbols.TokenNamesuper:
+ case ITerminalSymbols.TokenNameswitch:
+ // case
+ // ITerminalSymbols.TokenNamesynchronized:
+ // case ITerminalSymbols.TokenNamethis:
+ case ITerminalSymbols.TokenNamethrow:
+ // case
+ // ITerminalSymbols.TokenNametransient:
+ // case ITerminalSymbols.TokenNametrue:
+ case ITerminalSymbols.TokenNametry:
+ // case ITerminalSymbols.TokenNamevoid:
+ // case
+ // ITerminalSymbols.TokenNamevolatile:
+ case ITerminalSymbols.TokenNamewhile:
+ valid = parseTag();
+ break;
}
}
- } catch (InvalidInputException e) {
- consumeToken();
- }
- }
- break;
- case '\r':
- case '\n':
- if (this.lineStarted && this.textStart < previousPosition) {
- pushText(this.textStart, previousPosition);
- }
- this.lineStarted = false;
- // Fix bug 51650
- this.textStart = -1;
- break;
- case '}' :
- if (this.inlineTagStarted) {
- if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
- pushText(this.textStart, previousPosition);
}
- if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
this.textStart = this.index;
- this.inlineTagStarted = false;
- } else {
- if (!this.lineStarted) {
- this.textStart = previousPosition;
+ if (!valid) {
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+ // do not stop the inline tag when error is
+ // encountered to get text after
+ validComment = false;
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+ // for DOM AST node, store tag as text in case
+ // of invalid syntax
+ if (this.kind == DOM_PARSER) {
+ parseTag();
+ this.textStart = this.tagSourceEnd + 1;
+ invalidTagLineEnd = this.lineEnd;
+ }
}
+ } catch (InvalidInputException e) {
+ consumeToken();
}
- this.lineStarted = true;
- break;
- case '{' :
- if (this.inlineTagStarted) {
- this.inlineTagStarted = false;
- // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
- // Cannot have opening brace in inline comment
- if (this.sourceParser != null) {
- int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
- this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
- }
- if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
- pushText(this.textStart, previousPosition);
- }
- if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
+ }
+ break;
+ case '\r':
+ case '\n':
+ if (this.lineStarted && this.textStart < previousPosition) {
+ pushText(this.textStart, previousPosition);
+ }
+ this.lineStarted = false;
+ // Fix bug 51650
+ this.textStart = -1;
+ break;
+ case '}':
+ if (this.inlineTagStarted) {
+ if (this.lineStarted && this.textStart != -1
+ && this.textStart < previousPosition) {
+ pushText(this.textStart, previousPosition);
}
+ if (this.kind == DOM_PARSER)
+ refreshInlineTagPosition(previousPosition);
+ this.textStart = this.index;
+ this.inlineTagStarted = false;
+ } else {
if (!this.lineStarted) {
this.textStart = previousPosition;
}
- this.lineStarted = true;
- this.inlineTagStart = previousPosition;
- break;
- case '*' :
- case '\u000c' : /* FORM FEED */
- case ' ' : /* SPACE */
- case '\t' : /* HORIZONTAL TABULATION */
- // do nothing for space or '*' characters
- break;
- default :
- if (!this.lineStarted) {
- this.textStart = previousPosition;
+ }
+ this.lineStarted = true;
+ break;
+ case '{':
+ if (this.inlineTagStarted) {
+ this.inlineTagStarted = false;
+ // bug
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+ // Cannot have opening brace in inline comment
+ if (this.sourceParser != null) {
+ int end = previousPosition < invalidInlineTagLineEnd ? previousPosition
+ : invalidInlineTagLineEnd;
+ this.sourceParser.problemReporter()
+ .javadocUnterminatedInlineTag(
+ this.inlineTagStart, end);
}
- this.lineStarted = true;
- break;
+ if (this.lineStarted && this.textStart != -1
+ && this.textStart < previousPosition) {
+ pushText(this.textStart, previousPosition);
+ }
+ if (this.kind == DOM_PARSER)
+ refreshInlineTagPosition(previousPosition);
+ }
+ if (!this.lineStarted) {
+ this.textStart = previousPosition;
+ }
+ this.lineStarted = true;
+ this.inlineTagStart = previousPosition;
+ break;
+ case '*':
+ case '\u000c': /* FORM FEED */
+ case ' ': /* SPACE */
+ case '\t': /* HORIZONTAL TABULATION */
+ // do nothing for space or '*' characters
+ break;
+ default:
+ if (!this.lineStarted) {
+ this.textStart = previousPosition;
+ }
+ this.lineStarted = true;
+ break;
}
}
// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
if (this.inlineTagStarted) {
this.inlineTagStarted = false;
if (this.sourceParser != null) {
- int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
- if (this.index >= this.endComment) end = invalidInlineTagLineEnd;
- this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+ int end = previousPosition < invalidInlineTagLineEnd ? previousPosition
+ : invalidInlineTagLineEnd;
+ if (this.index >= this.endComment)
+ end = invalidInlineTagLineEnd;
+ this.sourceParser.problemReporter()
+ .javadocUnterminatedInlineTag(this.inlineTagStart,
+ end);
}
- if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+ if (this.lineStarted && this.textStart != -1
+ && this.textStart < previousPosition) {
pushText(this.textStart, previousPosition);
}
if (this.kind == DOM_PARSER) {
updateLineEnd();
}
- protected abstract Object createArgumentReference(char[] name, int dim, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
- protected abstract Object createFieldReference(Object receiver) throws InvalidInputException;
- protected abstract Object createMethodReference(Object receiver, List arguments) throws InvalidInputException;
- protected Object createReturnStatement() { return null; }
+ protected abstract Object createArgumentReference(char[] name, int dim,
+ Object typeRef, long[] dimPos, long argNamePos)
+ throws InvalidInputException;
+
+ protected abstract Object createFieldReference(Object receiver)
+ throws InvalidInputException;
+
+ protected abstract Object createMethodReference(Object receiver,
+ List arguments) throws InvalidInputException;
+
+ protected Object createReturnStatement() {
+ return null;
+ }
+
protected abstract Object createTypeReference(int primitiveToken);
-
+
private int getEndPosition() {
if (this.scanner.getCurrentTokenEndPosition() > this.lineEnd) {
return this.lineEnd;
}
/*
- * Search the source position corresponding to the end of a given line number.
- * Warning: returned position is 1-based index!
- * @see Scanner#getLineEnd(int) We cannot directly use this method
- * when linePtr field is not initialized.
- *
- private int getLineEnd(int lineNumber) {
-
- if (this.scanner.linePtr != -1) {
- return this.scanner.getLineEnd(lineNumber);
- }
- if (this.lineEnds == null)
- return -1;
- if (lineNumber > this.lineEnds.length+1)
- return -1;
- if (lineNumber <= 0)
- return -1;
- if (lineNumber == this.lineEnds.length + 1)
- return this.scanner.eofPosition;
- return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
- }
- */
+ * Search the source position corresponding to the end of a given line
+ * number. Warning: returned position is 1-based index!
+ *
+ * @see Scanner#getLineEnd(int) We cannot directly use this method when
+ * linePtr field is not initialized.
+ *
+ * private int getLineEnd(int lineNumber) {
+ *
+ * if (this.scanner.linePtr != -1) { return
+ * this.scanner.getLineEnd(lineNumber); } if (this.lineEnds == null) return
+ * -1; if (lineNumber > this.lineEnds.length+1) return -1; if (lineNumber <=
+ * 0) return -1; if (lineNumber == this.lineEnds.length + 1) return
+ * this.scanner.eofPosition; return this.lineEnds[lineNumber-1]; // next
+ * line start one character behind the lineEnd of the previous line }
+ */
/**
- * Search the line number corresponding to a specific position.
- * Warning: returned position is 1-based index!
- * @see Scanner#getLineNumber(int) We cannot directly use this method
- * when linePtr field is not initialized.
+ * Search the line number corresponding to a specific position. Warning:
+ * returned position is 1-based index!
+ *
+ * @see Scanner#getLineNumber(int) We cannot directly use this method when
+ * linePtr field is not initialized.
*/
private int getLineNumber(int position) {
-
+
if (this.scanner.linePtr != -1) {
return this.scanner.getLineNumber(position);
}
int g = 0, d = length - 1;
int m = 0;
while (g <= d) {
- m = (g + d) /2;
+ m = (g + d) / 2;
if (position < this.lineEnds[m]) {
- d = m-1;
+ d = m - 1;
} else if (position > this.lineEnds[m]) {
- g = m+1;
+ g = m + 1;
} else {
return m + 1;
}
}
if (position < this.lineEnds[m]) {
- return m+1;
+ return m + 1;
}
- return m+2;
+ return m + 2;
}
/*
- * Parse argument in @see tag method reference
+ * Parse argument in
+ *
+ * @see tag method reference
*/
private Object parseArguments(Object receiver) throws InvalidInputException {
// Init
- int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type arg,Type arg,...)
+ int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type
+ // arg,Type arg,...)
int iToken = 0;
char[] argName = null;
List arguments = new ArrayList(10);
int start = this.scanner.getCurrentTokenStartPosition();
-
+
// Parse arguments declaration if method reference
- nextArg : while (this.index < this.scanner.eofPosition) {
+ nextArg: while (this.index < this.scanner.eofPosition) {
// Read argument type reference
Object typeRef;
if (iToken != 0)
break nextArg;
} else if ((iToken % modulo) != 0) {
- break nextArg;
+ break nextArg;
}
if (typeRef == null) {
- if (firstArg && this.currentTokenType == ITerminalSymbols.TokenNameRPAREN) {
- // verify characters after arguments declaration (expecting white space or end comment)
+ if (firstArg
+ && this.currentTokenType == ITerminalSymbols.TokenNameRPAREN) {
+ // verify characters after arguments declaration (expecting
+ // white space or end comment)
if (!verifySpaceOrEndComment()) {
- int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
- if (this.source[end]=='\n') end--;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+ int end = this.starPosition == -1 ? this.lineEnd
+ : this.starPosition;
+ if (this.source[end] == '\n')
+ end--;
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocMalformedSeeReference(start, end);
return null;
}
this.lineStarted = true;
// Read possible array declaration
int dim = 0;
- long[] dimPositions = new long[20]; // assume that there won't be more than 20 dimensions...
+ long[] dimPositions = new long[20]; // assume that there won't be
+ // more than 20 dimensions...
if (readToken() == ITerminalSymbols.TokenNameLBRACKET) {
int dimStart = this.scanner.getCurrentTokenStartPosition();
while (readToken() == ITerminalSymbols.TokenNameLBRACKET) {
break nextArg;
}
consumeToken();
- dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+ dimPositions[dim++] = (((long) dimStart) << 32)
+ + this.scanner.getCurrentTokenEndPosition();
}
}
if (iToken != 1)
break nextArg;
} else if ((iToken % modulo) != 1) {
- break nextArg;
+ break nextArg;
}
- if (argName == null) { // verify that all arguments name are declared
+ if (argName == null) { // verify that all arguments name are
+ // declared
if (!firstArg) {
break nextArg;
}
}
argName = this.scanner.getCurrentIdentifierSource();
- argNamePos = (((long)this.scanner.getCurrentTokenStartPosition())<<32)+this.scanner.getCurrentTokenEndPosition();
+ argNamePos = (((long) this.scanner
+ .getCurrentTokenStartPosition()) << 32)
+ + this.scanner.getCurrentTokenEndPosition();
iToken++;
- } else if (argName != null) { // verify that no argument name is declared
+ } else if (argName != null) { // verify that no argument name is
+ // declared
break nextArg;
}
-
+
// Verify token position
if (firstArg) {
modulo = iToken + 1;
char[] name = argName == null ? new char[0] : argName;
if (token == ITerminalSymbols.TokenNameCOMMA) {
// Create new argument
- Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+ Object argument = createArgumentReference(name, dim, typeRef,
+ dimPositions, argNamePos);
arguments.add(argument);
consumeToken();
iToken++;
} else if (token == ITerminalSymbols.TokenNameRPAREN) {
- // verify characters after arguments declaration (expecting white space or end comment)
+ // verify characters after arguments declaration (expecting
+ // white space or end comment)
if (!verifySpaceOrEndComment()) {
- int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
- if (this.source[end]=='\n') end--;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+ int end = this.starPosition == -1 ? this.lineEnd
+ : this.starPosition;
+ if (this.source[end] == '\n')
+ end--;
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocMalformedSeeReference(start, end);
return null;
}
// Create new argument
- Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+ Object argument = createArgumentReference(name, dim, typeRef,
+ dimPositions, argNamePos);
arguments.add(argument);
consumeToken();
return createMethodReference(receiver, arguments);
}
/*
- * Parse an URL link reference in @see tag
+ * Parse an URL link reference in
+ *
+ * @see tag
*/
private boolean parseHref() throws InvalidInputException {
int start = this.scanner.getCurrentTokenStartPosition();
if (readToken() == ITerminalSymbols.TokenNameIdentifier) {
this.currentTokenType = -1; // do not update line end
try {
- if (CharOperation.equals(this.scanner.getCurrentIdentifierSource(), new char[]{'h', 'r', 'e', 'f'}, false) &&
- readToken() == ITerminalSymbols.TokenNameEQUAL) {
+ if (CharOperation.equals(this.scanner
+ .getCurrentIdentifierSource(), new char[] { 'h',
+ 'r', 'e', 'f' }, false)
+ && readToken() == ITerminalSymbols.TokenNameEQUAL) {
this.currentTokenType = -1; // do not update line end
- if (readToken() == ITerminalSymbols.TokenNameStringDoubleQuote ||
- readToken() == ITerminalSymbols.TokenNameStringSingleQuote) {
- this.currentTokenType = -1; // do not update line end
- // Skip all characters after string literal until closing '>' (see bug 68726)
- while (this.index <= this.lineEnd && readToken() != ITerminalSymbols.TokenNameGREATER) {
- this.currentTokenType = -1; // do not update line end
+ if (readToken() == ITerminalSymbols.TokenNameStringDoubleQuote
+ || readToken() == ITerminalSymbols.TokenNameStringSingleQuote) {
+ this.currentTokenType = -1; // do not update line
+ // end
+ // Skip all characters after string literal until
+ // closing '>' (see bug 68726)
+ while (this.index <= this.lineEnd
+ && readToken() != ITerminalSymbols.TokenNameGREATER) {
+ this.currentTokenType = -1; // do not update
+ // line end
}
if (this.currentTokenType == ITerminalSymbols.TokenNameGREATER) {
- consumeToken(); // update line end as new lines are allowed in URL description
+ consumeToken(); // update line end as new lines
+ // are allowed in URL
+ // description
while (readToken() != ITerminalSymbols.TokenNameLESS) {
- if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@') {
- // Reset position: we want to rescan last token
+ if (this.scanner.currentPosition >= this.scanner.eofPosition
+ || this.scanner.currentCharacter == '@') {
+ // Reset position: we want to rescan
+ // last token
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
// Signal syntax error
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(start, this.lineEnd);
+ if (this.sourceParser != null)
+ this.sourceParser
+ .problemReporter()
+ .javadocInvalidSeeUrlReference(
+ start, this.lineEnd);
return false;
}
consumeToken();
}
- this.currentTokenType = -1; // do not update line end
+ this.currentTokenType = -1; // do not update
+ // line end
if (readChar() == '/') {
if (Character.toLowerCase(readChar()) == 'a') {
if (readChar() == '>') {
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
// Signal syntax error
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(start, this.lineEnd);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(
+ start, this.lineEnd);
return false;
}
/*
- * Parse a method reference in @see tag
+ * Parse a method reference in
+ *
+ * @see tag
*/
private Object parseMember(Object receiver) throws InvalidInputException {
// Init
if (readToken() == ITerminalSymbols.TokenNameIdentifier) {
consumeToken();
pushIdentifier(true);
- // Look for next token to know whether it's a field or method reference
+ // Look for next token to know whether it's a field or method
+ // reference
int previousPosition = this.index;
if (readToken() == ITerminalSymbols.TokenNameLPAREN) {
consumeToken();
try {
return parseArguments(receiver);
} catch (InvalidInputException e) {
- int end = this.scanner.getCurrentTokenEndPosition() < this.lineEnd ?
- this.scanner.getCurrentTokenEndPosition() :
- this.scanner.getCurrentTokenStartPosition();
+ int end = this.scanner.getCurrentTokenEndPosition() < this.lineEnd ? this.scanner
+ .getCurrentTokenEndPosition()
+ : this.scanner.getCurrentTokenStartPosition();
end = end < this.lineEnd ? end : this.lineEnd;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReferenceArgs(start, end);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocInvalidSeeReferenceArgs(start, end);
}
return null;
}
this.scanner.currentPosition = previousPosition;
this.currentTokenType = -1;
- // Verify character(s) after identifier (expecting space or end comment)
+ // Verify character(s) after identifier (expecting space or end
+ // comment)
if (!verifySpaceOrEndComment()) {
- int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
- if (this.source[end]=='\n') end--;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+ int end = this.starPosition == -1 ? this.lineEnd
+ : this.starPosition;
+ if (this.source[end] == '\n')
+ end--;
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocMalformedSeeReference(start, end);
return null;
}
return createFieldReference(receiver);
}
int end = getEndPosition() - 1;
end = start > end ? start : end;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, end);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocInvalidSeeReference(
+ start, end);
// Reset position: we want to rescan last token
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
// Push identifier next
int token = readToken();
switch (token) {
- case ITerminalSymbols.TokenNameIdentifier :
- consumeToken();
- return pushParamName();
- case ITerminalSymbols.TokenNameEOF :
- break;
- default :
- start = this.scanner.getCurrentTokenStartPosition();
- end = getEndPosition();
- if (end < start) start = this.tagSourceStart;
- break;
+ case ITerminalSymbols.TokenNameIdentifier:
+ consumeToken();
+ return pushParamName();
+ case ITerminalSymbols.TokenNameEOF:
+ break;
+ default:
+ start = this.scanner.getCurrentTokenStartPosition();
+ end = getEndPosition();
+ if (end < start)
+ start = this.tagSourceStart;
+ break;
}
} catch (InvalidInputException e) {
end = getEndPosition();
this.currentTokenType = -1;
// Report problem
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingParamName(start, end);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocMissingParamName(start,
+ end);
return false;
}
/*
* Parse a qualified name and built a type reference if the syntax is valid.
*/
- protected Object parseQualifiedName(boolean reset) throws InvalidInputException {
+ protected Object parseQualifiedName(boolean reset)
+ throws InvalidInputException {
// Reset identifier stack if requested
if (reset) {
// Scan tokens
int primitiveToken = -1;
- nextToken : for (int iToken = 0; ; iToken++) {
+ nextToken: for (int iToken = 0;; iToken++) {
int token = readToken();
switch (token) {
- case ITerminalSymbols.TokenNameIdentifier :
- if (((iToken % 2) > 0)) { // identifiers must be odd tokens
- break nextToken;
- }
- pushIdentifier(iToken == 0);
- consumeToken();
- break;
+ case ITerminalSymbols.TokenNameIdentifier:
+ if (((iToken % 2) > 0)) { // identifiers must be odd tokens
+ break nextToken;
+ }
+ pushIdentifier(iToken == 0);
+ consumeToken();
+ break;
- case ITerminalSymbols.TokenNameDOT :
- if ((iToken % 2) == 0) { // dots must be even tokens
- throw new InvalidInputException();
- }
- consumeToken();
- break;
+ case ITerminalSymbols.TokenNameDOT:
+ if ((iToken % 2) == 0) { // dots must be even tokens
+ throw new InvalidInputException();
+ }
+ consumeToken();
+ break;
+
+ // case ITerminalSymbols.TokenNamevoid :
+ // case ITerminalSymbols.TokenNameboolean :
+ // case ITerminalSymbols.TokenNamebyte :
+ // case ITerminalSymbols.TokenNamechar :
+ // case ITerminalSymbols.TokenNamedouble :
+ // case ITerminalSymbols.TokenNamefloat :
+ // case ITerminalSymbols.TokenNameint :
+ // case ITerminalSymbols.TokenNamelong :
+ // case ITerminalSymbols.TokenNameshort :
+ // if (iToken > 0) {
+ // throw new InvalidInputException();
+ // }
+ // pushIdentifier(true);
+ // primitiveToken = token;
+ // consumeToken();
+ // break nextToken;
-// case ITerminalSymbols.TokenNamevoid :
-// case ITerminalSymbols.TokenNameboolean :
-// case ITerminalSymbols.TokenNamebyte :
-// case ITerminalSymbols.TokenNamechar :
-// case ITerminalSymbols.TokenNamedouble :
-// case ITerminalSymbols.TokenNamefloat :
-// case ITerminalSymbols.TokenNameint :
-// case ITerminalSymbols.TokenNamelong :
-// case ITerminalSymbols.TokenNameshort :
-// if (iToken > 0) {
-// throw new InvalidInputException();
-// }
-// pushIdentifier(true);
-// primitiveToken = token;
-// consumeToken();
-// break nextToken;
-
- default :
- if (iToken == 0) {
- return null;
- }
- if ((iToken % 2) == 0) { // cannot leave on a dot
- // Reset position: we want to rescan last token
- if (this.kind == DOM_PARSER && this.currentTokenType != -1) {
- this.index = this.tokenPreviousPosition;
- this.scanner.currentPosition = this.tokenPreviousPosition;
- this.currentTokenType = -1;
- }
- throw new InvalidInputException();
+ default:
+ if (iToken == 0) {
+ return null;
+ }
+ if ((iToken % 2) == 0) { // cannot leave on a dot
+ // Reset position: we want to rescan last token
+ if (this.kind == DOM_PARSER && this.currentTokenType != -1) {
+ this.index = this.tokenPreviousPosition;
+ this.scanner.currentPosition = this.tokenPreviousPosition;
+ this.currentTokenType = -1;
}
- break nextToken;
+ throw new InvalidInputException();
+ }
+ break nextToken;
}
}
// Reset position: we want to rescan last token
}
/*
- * Parse a reference in @see tag
+ * Parse a reference in
+ *
+ * @see tag
*/
- protected boolean parseReference(boolean plain) throws InvalidInputException {
+ protected boolean parseReference(boolean plain)
+ throws InvalidInputException {
Object typeRef = null;
Object reference = null;
int previousPosition = -1;
int typeRefStartPosition = -1;
- nextToken : while (this.index < this.scanner.eofPosition) {
+ nextToken: while (this.index < this.scanner.eofPosition) {
previousPosition = this.index;
int token = readToken();
switch (token) {
- case ITerminalSymbols.TokenNameStringDoubleQuote : // @see "string"
- case ITerminalSymbols.TokenNameStringSingleQuote :
- int start = this.scanner.getCurrentTokenStartPosition();
+ case ITerminalSymbols.TokenNameStringDoubleQuote: // @see "string"
+ case ITerminalSymbols.TokenNameStringSingleQuote:
+ int start = this.scanner.getCurrentTokenStartPosition();
+ consumeToken();
+ // If typeRef != null we may raise a warning here to let user
+ // know there's an unused reference...
+ // Currently as javadoc 1.4.2 ignore it, we do the same (see bug
+ // 69302)
+ if (typeRef != null) {
+ start = this.tagSourceEnd + 1;
+ previousPosition = start;
+ typeRef = null;
+ }
+ // verify end line (expecting empty or end comment)
+ if (verifyEndLine(previousPosition)) {
+ return true;
+ }
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocInvalidSeeReference(start, this.lineEnd);
+ return false;
+ case ITerminalSymbols.TokenNameLESS: // @see "<a
+ // href="URL#Value">label</a>
+ consumeToken();
+ start = this.scanner.getCurrentTokenStartPosition();
+ if (parseHref()) {
consumeToken();
- // If typeRef != null we may raise a warning here to let user know there's an unused reference...
- // Currently as javadoc 1.4.2 ignore it, we do the same (see bug 69302)
+ // If typeRef != null we may raise a warning here to let
+ // user know there's an unused reference...
+ // Currently as javadoc 1.4.2 ignore it, we do the same (see
+ // bug 69302)
if (typeRef != null) {
- start = this.tagSourceEnd+1;
+ start = this.tagSourceEnd + 1;
previousPosition = start;
typeRef = null;
}
if (verifyEndLine(previousPosition)) {
return true;
}
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, this.lineEnd);
- return false;
- case ITerminalSymbols.TokenNameLESS : // @see "<a href="URL#Value">label</a>
+ if (this.sourceParser != null)
+ this.sourceParser
+ .problemReporter()
+ .javadocInvalidSeeReference(start, this.lineEnd);
+ }
+ return false;
+ case ITerminalSymbols.TokenNameERROR:
+ if (this.scanner.currentCharacter == '#') { // @see ...#member
consumeToken();
- start = this.scanner.getCurrentTokenStartPosition();
- if (parseHref()) {
- consumeToken();
- // If typeRef != null we may raise a warning here to let user know there's an unused reference...
- // Currently as javadoc 1.4.2 ignore it, we do the same (see bug 69302)
- if (typeRef != null) {
- start = this.tagSourceEnd+1;
- previousPosition = start;
- typeRef = null;
- }
- // verify end line (expecting empty or end comment)
- if (verifyEndLine(previousPosition)) {
- return true;
- }
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, this.lineEnd);
+ reference = parseMember(typeRef);
+ if (reference != null) {
+ return pushSeeRef(reference, plain);
}
return false;
- case ITerminalSymbols.TokenNameERROR :
- if (this.scanner.currentCharacter == '#') { // @see ...#member
- consumeToken();
- reference = parseMember(typeRef);
- if (reference != null) {
- return pushSeeRef(reference, plain);
- }
- return false;
- }
- break nextToken;
- case ITerminalSymbols.TokenNameIdentifier :
- if (typeRef == null) {
- typeRefStartPosition = this.scanner.getCurrentTokenStartPosition();
- typeRef = parseQualifiedName(true);
- break;
- }
- break nextToken;
- default :
- break nextToken;
+ }
+ break nextToken;
+ case ITerminalSymbols.TokenNameIdentifier:
+ if (typeRef == null) {
+ typeRefStartPosition = this.scanner
+ .getCurrentTokenStartPosition();
+ typeRef = parseQualifiedName(true);
+ break;
+ }
+ break nextToken;
+ default:
+ break nextToken;
}
}
-
+
// Verify that we got a reference
- if (reference == null) reference = typeRef;
+ if (reference == null)
+ reference = typeRef;
if (reference == null) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingSeeReference(this.tagSourceStart, this.tagSourceEnd);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocMissingSeeReference(
+ this.tagSourceStart, this.tagSourceEnd);
return false;
}
// Reset position at the end of type reference
- this.index = this.lastIdentifierEndPosition+1;
+ this.index = this.lastIdentifierEndPosition + 1;
this.scanner.currentPosition = this.index;
this.currentTokenType = -1;
- // Verify that line end does not start with an open parenthese (which could be a constructor reference wrongly written...)
+ // Verify that line end does not start with an open parenthese (which
+ // could be a constructor reference wrongly written...)
// See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=47215
char ch = peekChar();
if (ch == '(') {
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(typeRefStartPosition, this.lineEnd);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocInvalidSeeReference(
+ typeRefStartPosition, this.lineEnd);
return false;
}
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
- int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
- if (this.source[end]=='\n') end--;
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(typeRefStartPosition, end);
+ int end = this.starPosition == -1 ? this.lineEnd
+ : this.starPosition;
+ if (this.source[end] == '\n')
+ end--;
+ if (this.sourceParser != null)
+ this.sourceParser
+ .problemReporter()
+ .javadocMalformedSeeReference(typeRefStartPosition, end);
return false;
}
-
+
// Everything is OK, store reference
return pushSeeRef(reference, plain);
}
protected abstract boolean parseReturn();
/*
- * Parse @see tag declaration
+ * Parse
+ *
+ * @see tag declaration
*/
protected boolean parseSee(boolean plain) {
int start = this.scanner.currentPosition;
try {
return parseReference(plain);
} catch (InvalidInputException ex) {
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, getEndPosition());
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocInvalidSeeReference(
+ start, getEndPosition());
}
// Reset position to avoid missing tokens when new line was encountered
this.index = this.tokenPreviousPosition;
try {
Object typeRef = parseQualifiedName(true);
if (typeRef == null) {
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd);
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter()
+ .javadocMissingThrowsClassName(this.tagSourceStart,
+ this.tagSourceEnd);
} else {
return pushThrowName(typeRef, real);
}
} catch (InvalidInputException ex) {
- if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidThrowsClass(start, getEndPosition());
+ if (this.sourceParser != null)
+ this.sourceParser.problemReporter().javadocInvalidThrowsClass(
+ start, getEndPosition());
}
return false;
}
idx++;
if (!(((c1 = Character.getNumericValue(this.source[idx++])) > 15 || c1 < 0)
|| ((c2 = Character.getNumericValue(this.source[idx++])) > 15 || c2 < 0)
- || ((c3 = Character.getNumericValue(this.source[idx++])) > 15 || c3 < 0) || ((c4 = Character.getNumericValue(this.source[idx++])) > 15 || c4 < 0))) {
+ || ((c3 = Character.getNumericValue(this.source[idx++])) > 15 || c3 < 0) || ((c4 = Character
+ .getNumericValue(this.source[idx++])) > 15 || c4 < 0))) {
c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
}
/*
- * push the consumeToken on the identifier stack. Increase the total number of identifier in the stack.
+ * push the consumeToken on the identifier stack. Increase the total number
+ * of identifier in the stack.
*/
protected void pushIdentifier(boolean newLength) {
int stackLength = this.identifierStack.length;
if (++this.identifierPtr >= stackLength) {
- System.arraycopy(
- this.identifierStack, 0,
- this.identifierStack = new char[stackLength + 10][], 0,
- stackLength);
- System.arraycopy(
- this.identifierPositionStack, 0,
- this.identifierPositionStack = new long[stackLength + 10], 0,
- stackLength);
+ System.arraycopy(this.identifierStack, 0,
+ this.identifierStack = new char[stackLength + 10][], 0,
+ stackLength);
+ System.arraycopy(this.identifierPositionStack, 0,
+ this.identifierPositionStack = new long[stackLength + 10],
+ 0, stackLength);
}
- this.identifierStack[this.identifierPtr] = this.scanner.getCurrentIdentifierSource();
- this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1);
+ this.identifierStack[this.identifierPtr] = this.scanner
+ .getCurrentIdentifierSource();
+ this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32)
+ + (this.scanner.currentPosition - 1);
if (newLength) {
stackLength = this.identifierLengthStack.length;
if (++this.identifierLengthPtr >= stackLength) {
- System.arraycopy(
- this.identifierLengthStack, 0,
- this.identifierLengthStack = new int[stackLength + 10], 0,
- stackLength);
+ System.arraycopy(this.identifierLengthStack, 0,
+ this.identifierLengthStack = new int[stackLength + 10],
+ 0, stackLength);
}
this.identifierLengthStack[this.identifierLengthPtr] = 1;
} else {
}
/*
- * Add a new obj on top of the ast stack.
- * If new length is required, then add also a new length in length stack.
+ * Add a new obj on top of the ast stack. If new length is required, then
+ * add also a new length in length stack.
*/
protected void pushOnAstStack(Object node, boolean newLength) {
int stackLength = this.astStack.length;
if (++this.astPtr >= stackLength) {
- System.arraycopy(
- this.astStack, 0,
- this.astStack = new Object[stackLength + AstStackIncrement], 0,
- stackLength);
+ System
+ .arraycopy(this.astStack, 0,
+ this.astStack = new Object[stackLength
+ + AstStackIncrement], 0, stackLength);
this.astPtr = stackLength;
}
this.astStack[this.astPtr] = node;
if (newLength) {
stackLength = this.astLengthStack.length;
if (++this.astLengthPtr >= stackLength) {
- System.arraycopy(
- this.astLengthStack, 0,
- this.astLengthStack = new int[stackLength + AstStackIncrement], 0,
- stackLength);
+ System.arraycopy(this.astLengthStack, 0,
+ this.astLengthStack = new int[stackLength
+ + AstStackIncrement], 0, stackLength);
}
this.astLengthStack[this.astLengthPtr] = 1;
} else {
protected abstract boolean pushThrowName(Object typeRef, boolean real);
/*
- * Read current character and move index position.
- * Warning: scanner position is unchanged using this method!
+ * Read current character and move index position. Warning: scanner position
+ * is unchanged using this method!
*/
protected char readChar() {
-
+
char c = this.source[this.index++];
if (c == '\\' && this.source[this.index] == 'u') {
int c1, c2, c3, c4;
while (this.source[this.index] == 'u')
this.index++;
if (!(((c1 = Character.getNumericValue(this.source[this.index++])) > 15 || c1 < 0)
- || ((c2 = Character.getNumericValue(this.source[this.index++])) > 15 || c2 < 0)
- || ((c3 = Character.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = Character.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) {
+ || ((c2 = Character
+ .getNumericValue(this.source[this.index++])) > 15 || c2 < 0)
+ || ((c3 = Character
+ .getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = Character
+ .getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) {
c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
} else {
- // TODO (frederic) currently reset to previous position, perhaps signal a syntax error would be more appropriate
+ // TODO (frederic) currently reset to previous position, perhaps
+ // signal a syntax error would be more appropriate
this.index = pos;
}
}
if (this.currentTokenType < 0) {
this.tokenPreviousPosition = this.scanner.currentPosition;
this.currentTokenType = this.scanner.getNextToken();
- if (this.scanner.currentPosition > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+ if (this.scanner.currentPosition > (this.lineEnd + 1)) { // be
+ // sure
+ // to be
+ // on
+ // next
+ // line
+ // (lineEnd
+ // is
+ // still
+ // on
+ // the
+ // same
+ // line)
this.lineStarted = false;
while (this.currentTokenType == ITerminalSymbols.TokenNameMULTIPLY) {
this.currentTokenType = this.scanner.getNextToken();
}
}
this.index = this.scanner.currentPosition;
- this.lineStarted = true; // after having read a token, line is obviously started...
+ this.lineStarted = true; // after having read a token, line is
+ // obviously started...
}
return this.currentTokenType;
}
consumeToken();
return token;
}
-
+
/*
* Refresh start position and length of an inline tag.
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
- int startPos = this.scanner.currentPosition<this.index ? this.scanner.currentPosition : this.index;
- int endPos = this.scanner.currentPosition<this.index ? this.index : this.scanner.currentPosition;
+ int startPos = this.scanner.currentPosition < this.index ? this.scanner.currentPosition
+ : this.index;
+ int endPos = this.scanner.currentPosition < this.index ? this.index
+ : this.scanner.currentPosition;
if (startPos == this.source.length)
return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
if (endPos > this.source.length)
return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
-
+
char front[] = new char[startPos];
System.arraycopy(this.source, 0, front, 0, startPos);
-
+
int middleLength = (endPos - 1) - startPos + 1;
char middle[];
if (middleLength > -1) {
middle = new char[middleLength];
- System.arraycopy(
- this.source,
- startPos,
- middle,
- 0,
- middleLength);
+ System.arraycopy(this.source, startPos, middle, 0, middleLength);
} else {
middle = CharOperation.NO_CHAR;
}
-
+
char end[] = new char[this.source.length - (endPos - 1)];
- System.arraycopy(
- this.source,
- (endPos - 1) + 1,
- end,
- 0,
- this.source.length - (endPos - 1) - 1);
-
+ System.arraycopy(this.source, (endPos - 1) + 1, end, 0,
+ this.source.length - (endPos - 1) - 1);
+
buffer.append(front);
- if (this.scanner.currentPosition<this.index) {
- buffer.append("\n===============================\nScanner current position here -->"); //$NON-NLS-1$
+ if (this.scanner.currentPosition < this.index) {
+ buffer
+ .append("\n===============================\nScanner current position here -->"); //$NON-NLS-1$
} else {
- buffer.append("\n===============================\nParser index here -->"); //$NON-NLS-1$
+ buffer
+ .append("\n===============================\nParser index here -->"); //$NON-NLS-1$
}
buffer.append(middle);
- if (this.scanner.currentPosition<this.index) {
- buffer.append("<-- Parser index here\n===============================\n"); //$NON-NLS-1$
+ if (this.scanner.currentPosition < this.index) {
+ buffer
+ .append("<-- Parser index here\n===============================\n"); //$NON-NLS-1$
} else {
- buffer.append("<-- Scanner current position here\n===============================\n"); //$NON-NLS-1$
+ buffer
+ .append("<-- Scanner current position here\n===============================\n"); //$NON-NLS-1$
}
buffer.append(end);
}
/*
- * Update
+ * Update
*/
protected abstract void updateDocComment();
* Update line end
*/
protected void updateLineEnd() {
- while (this.index > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+ while (this.index > (this.lineEnd + 1)) { // be sure to be on next
+ // line (lineEnd is still on
+ // the same line)
if (this.linePtr < this.lastLinePtr) {
this.lineEnd = this.scanner.getLineEnd(++this.linePtr) - 1;
} else {
}
/*
- * Verify that end of the line only contains space characters or end of comment.
- * Note that end of comment may be preceeding by several contiguous '*' chars.
+ * Verify that end of the line only contains space characters or end of
+ * comment. Note that end of comment may be preceeding by several contiguous
+ * '*' chars.
*/
private boolean verifyEndLine(int textPosition) {
int startPosition = this.index;
char ch = readChar();
nextChar: while (true) {
switch (ch) {
- case '\r':
- case '\n':
+ case '\r':
+ case '\n':
+ if (this.kind == DOM_PARSER) {
+ parseTag();
+ pushText(textPosition, previousPosition);
+ }
+ this.index = previousPosition;
+ return true;
+ case '\u000c': /* FORM FEED */
+ case ' ': /* SPACE */
+ case '\t': /* HORIZONTAL TABULATION */
+ if (this.starPosition >= 0)
+ break nextChar;
+ break;
+ case '*':
+ this.starPosition = previousPosition;
+ break;
+ case '/':
+ if (this.starPosition >= textPosition) {
if (this.kind == DOM_PARSER) {
parseTag();
- pushText(textPosition, previousPosition);
+ pushText(textPosition, this.starPosition);
}
- this.index = previousPosition;
return true;
- case '\u000c' : /* FORM FEED */
- case ' ' : /* SPACE */
- case '\t' : /* HORIZONTAL TABULATION */
- if (this.starPosition >= 0) break nextChar;
- break;
- case '*':
- this.starPosition = previousPosition;
- break;
- case '/':
- if (this.starPosition >= textPosition) {
- if (this.kind == DOM_PARSER) {
- parseTag();
- pushText(textPosition, this.starPosition);
- }
- return true;
- }
- default :
- // leave loop
- break nextChar;
-
+ }
+ default:
+ // leave loop
+ break nextChar;
+
}
previousPosition = this.index;
ch = readChar();
}
/*
- * Verify that some text exists after a @return tag. Text must be different than
- * end of comment which may be preceeding by several '*' chars.
+ * Verify that some text exists after a @return tag. Text must be different
+ * than end of comment which may be preceeding by several '*' chars.
*/
private boolean verifyCharsAfterReturnTag(int startPosition) {
// Whitespace or inline tag closing brace
while (Character.isWhitespace(ch)) {
malformed = false;
previousPosition = this.index;
- ch = readChar();
+ ch = readChar();
}
// End of comment
this.starPosition = -1;
- nextChar: while (this.index<this.source.length) {
+ nextChar: while (this.index < this.source.length) {
switch (ch) {
- case '*':
- // valid whatever the number of star before last '/'
- this.starPosition = previousPosition;
- break;
- case '/':
- if (this.starPosition >= startPosition) { // valid only if a star was previous character
- return false;
- }
- default :
- // valid if any other character is encountered, even white spaces
- this.index = startPosition;
- return !malformed;
-
+ case '*':
+ // valid whatever the number of star before last '/'
+ this.starPosition = previousPosition;
+ break;
+ case '/':
+ if (this.starPosition >= startPosition) { // valid only if a
+ // star was previous
+ // character
+ return false;
+ }
+ default:
+ // valid if any other character is encountered, even white
+ // spaces
+ this.index = startPosition;
+ return !malformed;
+
}
previousPosition = this.index;
ch = readChar();
}
/*
- * Verify characters after a name matches one of following conditions:
- * 1- first character is a white space
- * 2- first character is a closing brace *and* we're currently parsing an inline tag
- * 3- are the end of comment (several contiguous star ('*') characters may be
- * found before the last slash ('/') character).
+ * Verify characters after a name matches one of following conditions: 1-
+ * first character is a white space 2- first character is a closing brace
+ * *and* we're currently parsing an inline tag 3- are the end of comment
+ * (several contiguous star ('*') characters may be found before the last
+ * slash ('/') character).
*/
private boolean verifySpaceOrEndComment() {
int startPosition = this.index;
// Whitespace or inline tag closing brace
char ch = peekChar();
switch (ch) {
- case '}':
- return this.inlineTagStarted;
- default:
- if (Character.isWhitespace(ch)) {
- return true;
- }
+ case '}':
+ return this.inlineTagStarted;
+ default:
+ if (Character.isWhitespace(ch)) {
+ return true;
+ }
}
// End of comment
int previousPosition = this.index;
this.starPosition = -1;
ch = readChar();
- nextChar: while (this.index<this.source.length) {
+ nextChar: while (this.index < this.source.length) {
switch (ch) {
- case '*':
- // valid whatever the number of star before last '/'
- this.starPosition = previousPosition;
- break;
- case '/':
- if (this.starPosition >= startPosition) { // valid only if a star was previous character
- return true;
- }
- default :
- // invalid whatever other character, even white spaces
- this.index = startPosition;
- return false;
-
+ case '*':
+ // valid whatever the number of star before last '/'
+ this.starPosition = previousPosition;
+ break;
+ case '/':
+ if (this.starPosition >= startPosition) { // valid only if a
+ // star was previous
+ // character
+ return true;
+ }
+ default:
+ // invalid whatever other character, even white spaces
+ this.index = startPosition;
+ return false;
+
}
previousPosition = this.index;
ch = readChar();