package org.eclipse.jdt.internal.compiler.parser;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class implements JavadocTagConstants {
public final static int = 0x0001;
public final static int = 0x0002;
public final static int = 0x0004;
public final static int = 0x0008;
public final static int = 0x0010;
public final static int = 0x0020;
protected final static int = 0x00FF;
protected final static int = 0x0100;
protected final static int = 0x0200;
protected final static int = 1;
protected final static int = 2;
protected final static int = 3;
protected final static int = 4;
public Scanner ;
public char[] ;
protected Parser ;
private int = -1;
public boolean = false;
public boolean = false;
public boolean ;
protected long ;
protected long ;
protected long [] ;
protected int ;
private final static int = 4;
protected boolean ;
protected Object ;
protected int , ;
protected int , = -1;
protected int ;
protected int , ;
protected int , , ;
protected int , ;
protected int , ;
protected int ;
protected int[] ;
protected boolean = false;
protected boolean = false;
protected boolean = false;
protected int ;
protected int = NO_TAG_VALUE;
protected int = NO_TAG_VALUE;
private int , ;
protected int ;
protected char[][] ;
protected int ;
protected int[] ;
protected long[] ;
protected final static int = 10;
protected int ;
protected Object[] ;
protected int ;
protected int[] ;
protected int = -1;
protected TypeReference[] ;
protected int = -1;
protected TypeReference[] ;
protected (Parser sourceParser) {
this.sourceParser = sourceParser;
this.scanner = new Scanner(false, false, false, ClassFileConstants.JDK1_3, null, null, true,
sourceParser != null ? this.sourceParser.options.enablePreviewFeatures : false);
this.identifierStack = new char[20][];
this.identifierPositionStack = new long[20];
this.identifierLengthStack = new int[10];
this.astStack = new Object[30];
this.astLengthStack = new int[20];
this.reportProblems = sourceParser != null;
if (sourceParser != null) {
this.checkDocComment = this.sourceParser.options.docCommentSupport;
this.sourceLevel = this.sourceParser.options.sourceLevel;
this.scanner.sourceLevel = this.sourceLevel;
this.complianceLevel = this.sourceParser.options.complianceLevel;
}
}
protected boolean () {
boolean validComment = true;
try {
this.astLengthPtr = -1;
this.astPtr = -1;
this.identifierPtr = -1;
this.currentTokenType = -1;
setInlineTagStarted(false);
this.inlineTagStart = -1;
this.lineStarted = false;
this.returnStatement = null;
this.inheritedPositions = null;
this.lastBlockTagValue = NO_TAG_VALUE;
this.deprecated = false;
this.lastLinePtr = getLineNumber(this.javadocEnd);
this.textStart = -1;
this.abort = false;
char previousChar = 0;
int invalidTagLineEnd = -1;
int invalidInlineTagLineEnd = -1;
boolean lineHasStar = true;
boolean verifText = (this.kind & TEXT_VERIF) != 0;
boolean isDomParser = (this.kind & DOM_PARSER) != 0;
boolean isFormatterParser = (this.kind & FORMATTER_COMMENT_PARSER) != 0;
int lastStarPosition = -1;
this.linePtr = getLineNumber(this.firstTagPosition);
int realStart = this.linePtr==1 ? this.javadocStart : this.scanner.getLineEnd(this.linePtr-1)+1;
if (realStart < this.javadocStart) realStart = this.javadocStart;
this.scanner.resetTo(realStart, this.javadocEnd);
this.index = realStart;
if (realStart == this.javadocStart) {
readChar();
readChar();
}
int previousPosition = this.index;
char nextCharacter = 0;
if (realStart == this.javadocStart) {
nextCharacter = readChar();
while (peekChar() == '*') {
nextCharacter = readChar();
}
this.javadocTextStart = this.index;
}
this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.javadocEnd: this.scanner.getLineEnd(this.linePtr) - 1;
this.javadocTextEnd = this.javadocEnd - 2;
boolean considerTagAsPlainText = false;
int openingBraces = 0;
int textEndPosition = -1;
while (!this.abort && this.index < this.javadocEnd) {
previousPosition = this.index;
previousChar = nextCharacter;
if (this.index > (this.lineEnd+1)) {
updateLineEnd();
}
if (this.currentTokenType < 0) {
nextCharacter = readChar();
} else {
previousPosition = this.scanner.getCurrentTokenStartPosition();
switch (this.currentTokenType) {
case TerminalTokens.TokenNameRBRACE:
nextCharacter = '}';
break;
case TerminalTokens.TokenNameMULTIPLY:
nextCharacter = '*';
break;
default:
nextCharacter = this.scanner.currentCharacter;
}
consumeToken();
}
switch (nextCharacter) {
case '@' :
if (considerTagAsPlainText) {
if (!this.lineStarted) {
if (openingBraces > 0 && this.reportProblems) {
this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, invalidInlineTagLineEnd);
}
considerTagAsPlainText = false;
this.inlineTagStarted = false;
openingBraces = 0;
}
} else if ((!this.lineStarted || previousChar == '{')) {
if (this.inlineTagStarted) {
setInlineTagStarted(false);
if (this.reportProblems) {
int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
}
validComment = false;
if (this.textStart != -1 && this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
if (isDomParser || isFormatterParser) {
refreshInlineTagPosition(textEndPosition);
}
}
if (previousChar == '{') {
if (this.textStart != -1) {
if (this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
}
setInlineTagStarted(true);
invalidInlineTagLineEnd = this.lineEnd;
} else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) {
pushText(this.textStart, invalidTagLineEnd);
}
this.scanner.resetTo(this.index, this.javadocEnd);
this.currentTokenType = -1;
try {
if (!parseTag(previousPosition)) {
validComment = false;
if (isDomParser) {
createTag();
}
this.textStart = this.tagSourceEnd+1;
invalidTagLineEnd = this.lineEnd;
textEndPosition = this.index;
}
if (!isFormatterParser && (this.tagValue == TAG_LITERAL_VALUE || this.tagValue == TAG_CODE_VALUE)) {
considerTagAsPlainText = true;
openingBraces++;
}
} catch (InvalidInputException e) {
consumeToken();
}
} else {
textEndPosition = this.index;
if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
refreshReturnStatement();
} else if (isFormatterParser) {
if (this.textStart == -1) this.textStart = previousPosition;
}
}
this.lineStarted = true;
break;
case '\r':
case '\n':
if (this.lineStarted) {
if (isFormatterParser && !ScannerHelper.isWhitespace(previousChar)) {
textEndPosition = previousPosition;
}
if (this.textStart != -1 && this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
}
this.lineStarted = false;
lineHasStar = false;
this.textStart = -1;
break;
case '}' :
if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
refreshReturnStatement();
}
if (considerTagAsPlainText) {
invalidInlineTagLineEnd = this.lineEnd;
if (--openingBraces == 0) {
considerTagAsPlainText = false;
}
}
if (this.inlineTagStarted) {
textEndPosition = this.index - 1;
if (!considerTagAsPlainText) {
if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
refreshInlineTagPosition(previousPosition);
}
if (!isFormatterParser && !considerTagAsPlainText)
this.textStart = this.index;
setInlineTagStarted(false);
} else {
if (!this.lineStarted) {
this.textStart = previousPosition;
}
}
this.lineStarted = true;
textEndPosition = this.index;
break;
case '{' :
if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
refreshReturnStatement();
}
if (considerTagAsPlainText) {
openingBraces++;
} else if (this.inlineTagStarted) {
setInlineTagStarted(false);
if (this.reportProblems) {
int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
}
if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
refreshInlineTagPosition(textEndPosition);
textEndPosition = this.index;
} else if (peekChar() != '@') {
if (this.textStart == -1) this.textStart = previousPosition;
textEndPosition = this.index;
}
if (!this.lineStarted) {
this.textStart = previousPosition;
}
this.lineStarted = true;
if (!considerTagAsPlainText) this.inlineTagStart = previousPosition;
break;
case '*' :
lastStarPosition = previousPosition;
if (previousChar != '*') {
this.starPosition = previousPosition;
if (isDomParser || isFormatterParser) {
if (lineHasStar) {
this.lineStarted = true;
if (this.textStart == -1) {
this.textStart = previousPosition;
if (this.index <= this.javadocTextEnd) textEndPosition = this.index;
}
}
if (!this.lineStarted) {
lineHasStar = true;
}
}
}
break;
case '\u000c' :
case ' ' :
case '\t' :
if (isFormatterParser) {
if (!ScannerHelper.isWhitespace(previousChar)) {
textEndPosition = previousPosition;
}
} else if (this.lineStarted && isDomParser) {
textEndPosition = this.index;
}
break;
case '/':
if (previousChar == '*') {
break;
}
default :
if (isFormatterParser && nextCharacter == '<') {
int initialIndex = this.index;
this.scanner.resetTo(this.index, this.javadocEnd);
if (!ScannerHelper.isWhitespace(previousChar)) {
textEndPosition = previousPosition;
}
if (parseHtmlTag(previousPosition, textEndPosition)) {
break;
}
if (this.abort) return false;
this.scanner.currentPosition = initialIndex;
this.index = initialIndex;
}
if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
refreshReturnStatement();
}
if (!this.lineStarted || this.textStart == -1) {
this.textStart = previousPosition;
}
this.lineStarted = true;
textEndPosition = this.index;
break;
}
}
this.javadocTextEnd = this.starPosition-1;
if (this.inlineTagStarted || considerTagAsPlainText) {
if (this.reportProblems) {
int end = this.javadocTextEnd<invalidInlineTagLineEnd ? this.javadocTextEnd : invalidInlineTagLineEnd;
if (this.index >= this.javadocEnd) end = invalidInlineTagLineEnd;
this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
}
if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
pushText(this.textStart, textEndPosition);
}
refreshInlineTagPosition(textEndPosition);
setInlineTagStarted(false);
} else if (this.lineStarted && this.textStart != -1 && this.textStart <= textEndPosition && (this.textStart < this.starPosition || this.starPosition == lastStarPosition)) {
pushText(this.textStart, textEndPosition);
}
updateDocComment();
} catch (Exception ex) {
validComment = false;
}
return validComment;
}
protected void () {
this.currentTokenType = -1;
updateLineEnd();
}
protected abstract Object (char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
protected boolean (int start) {
return true;
}
protected abstract Object (Object receiver) throws InvalidInputException;
protected abstract Object (Object receiver, List arguments) throws InvalidInputException;
protected Object () { return null; }
protected abstract void ();
protected abstract Object (int primitiveToken);
private int () {
if (this.index > this.lineEnd) {
return this.lineEnd;
} else {
return this.index-1;
}
}
private int (int position) {
if (this.scanner.linePtr != -1) {
return Util.getLineNumber(position, this.scanner.lineEnds, 0, this.scanner.linePtr);
}
if (this.lineEnds == null)
return 1;
return Util.getLineNumber(position, this.lineEnds, 0, this.lineEnds.length-1);
}
protected int () {
if (this.scanner.getCurrentTokenEndPosition() > this.lineEnd) {
return this.lineEnd;
} else {
return this.scanner.getCurrentTokenEndPosition();
}
}
protected int () {
return this.currentTokenType;
}
protected Object (Object receiver) throws InvalidInputException {
int modulo = 0;
int iToken = 0;
char[] argName = null;
List arguments = new ArrayList(10);
int start = this.scanner.getCurrentTokenStartPosition();
Object typeRef = null;
int dim = 0;
boolean isVarargs = false;
long[] dimPositions = new long[20];
char[] name = null;
long argNamePos = -1;
nextArg : while (this.index < this.scanner.eofPosition) {
try {
typeRef = parseQualifiedName(false);
if (this.abort) return null;
} catch (InvalidInputException e) {
break nextArg;
}
boolean firstArg = modulo == 0;
if (firstArg) {
if (iToken != 0)
break nextArg;
} else if ((iToken % modulo) != 0) {
break nextArg;
}
if (typeRef == null) {
if (firstArg && this.currentTokenType == TerminalTokens.TokenNameRPAREN) {
if (!verifySpaceOrEndComment()) {
int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
if (this.source[end]=='\n') end--;
if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
return null;
}
this.lineStarted = true;
return createMethodReference(receiver, null);
}
break nextArg;
}
iToken++;
dim = 0;
isVarargs = false;
if (readToken() == TerminalTokens.TokenNameLBRACKET) {
while (readToken() == TerminalTokens.TokenNameLBRACKET) {
int dimStart = this.scanner.getCurrentTokenStartPosition();
consumeToken();
if (readToken() != TerminalTokens.TokenNameRBRACKET) {
break nextArg;
}
consumeToken();
dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
}
} else if (readToken() == TerminalTokens.TokenNameELLIPSIS) {
int dimStart = this.scanner.getCurrentTokenStartPosition();
dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
consumeToken();
isVarargs = true;
}
argNamePos = -1;
if (readToken() == TerminalTokens.TokenNameIdentifier) {
consumeToken();
if (firstArg) {
if (iToken != 1)
break nextArg;
} else if ((iToken % modulo) != 1) {
break nextArg;
}
if (argName == null) {
if (!firstArg) {
break nextArg;
}
}
argName = this.scanner.getCurrentIdentifierSource();
argNamePos = (((long)this.scanner.getCurrentTokenStartPosition())<<32)+this.scanner.getCurrentTokenEndPosition();
iToken++;
} else if (argName != null) {
break nextArg;
}
if (firstArg) {
modulo = iToken + 1;
} else {
if ((iToken % modulo) != (modulo - 1)) {
break nextArg;
}
}
int token = readToken();
name = argName == null ? CharOperation.NO_CHAR : argName;
if (token == TerminalTokens.TokenNameCOMMA) {
Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
if (this.abort) return null;
arguments.add(argument);
consumeToken();
iToken++;
} else if (token == TerminalTokens.TokenNameRPAREN) {
if (!verifySpaceOrEndComment()) {
int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
if (this.source[end]=='\n') end--;
if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
return null;
}
Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
if (this.abort) return null;
arguments.add(argument);
consumeToken();
return createMethodReference(receiver, arguments);
} else {
break nextArg;
}
}
throw new InvalidInputException();
}
protected boolean (int previousPosition, int endTextPosition) throws InvalidInputException {
return false;
}
protected boolean () throws InvalidInputException {
boolean skipComments = this.scanner.skipComments;
this.scanner.skipComments = true;
try {
int start = this.scanner.getCurrentTokenStartPosition();
char currentChar = readChar();
if (currentChar == 'a' || currentChar == 'A') {
this.scanner.currentPosition = this.index;
if (readToken() == TerminalTokens.TokenNameIdentifier) {
consumeToken();
try {
if (CharOperation.equals(this.scanner.getCurrentIdentifierSource(), HREF_TAG, false) &&
readToken() == TerminalTokens.TokenNameEQUAL) {
consumeToken();
if (readToken() == TerminalTokens.TokenNameStringLiteral) {
consumeToken();
while (this.index < this.javadocEnd) {
while (readToken() != TerminalTokens.TokenNameGREATER) {
if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@' ||
(this.inlineTagStarted && this.scanner.currentCharacter == '}')) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
if (this.tagValue != TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
}
return false;
}
this.currentTokenType = -1;
}
consumeToken();
while (readToken() != TerminalTokens.TokenNameLESS) {
if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@' ||
(this.inlineTagStarted && this.scanner.currentCharacter == '}')) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
if (this.tagValue != TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
}
return false;
}
consumeToken();
}
consumeToken();
start = this.scanner.getCurrentTokenStartPosition();
currentChar = readChar();
if (currentChar == '/') {
currentChar = readChar();
if (currentChar == 'a' || currentChar =='A') {
currentChar = readChar();
if (currentChar == '>') {
return true;
}
}
}
if (currentChar == '\r' || currentChar == '\n' || currentChar == '\t' || currentChar == ' ') {
break;
}
}
}
}
} catch (InvalidInputException ex) {
}
}
}
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
if (this.tagValue != TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
}
}
finally {
this.scanner.skipComments = skipComments;
}
return false;
}
protected boolean (boolean report) {
int token = readTokenSafely();
switch (token) {
case TerminalTokens.TokenNameIdentifier:
pushIdentifier(true, false);
return true;
}
if (report) {
this.sourceParser.problemReporter().javadocMissingIdentifier(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
}
return false;
}
protected Object (Object receiver) throws InvalidInputException {
this.identifierPtr = -1;
this.identifierLengthPtr = -1;
int start = this.scanner.getCurrentTokenStartPosition();
this.memberStart = start;
if (readToken() == TerminalTokens.TokenNameIdentifier) {
if (this.scanner.currentCharacter == '.') {
parseQualifiedName(true);
} else {
consumeToken();
pushIdentifier(true, false);
}
int previousPosition = this.index;
if (readToken() == TerminalTokens.TokenNameLPAREN) {
consumeToken();
start = this.scanner.getCurrentTokenStartPosition();
try {
return parseArguments(receiver);
} catch (InvalidInputException e) {
int end = this.scanner.getCurrentTokenEndPosition() < this.lineEnd ?
this.scanner.getCurrentTokenEndPosition() :
this.scanner.getCurrentTokenStartPosition();
end = end < this.lineEnd ? end : this.lineEnd;
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeReferenceArgs(start, end);
}
return null;
}
this.index = previousPosition;
this.scanner.currentPosition = previousPosition;
this.currentTokenType = -1;
if (!verifySpaceOrEndComment()) {
int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
if (this.source[end]=='\n') end--;
if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
return null;
}
return createFieldReference(receiver);
}
int end = getTokenEndPosition() - 1;
end = start > end ? start : end;
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(start, end);
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
return null;
}
protected boolean () throws InvalidInputException {
int start = this.tagSourceStart;
int end = this.tagSourceEnd;
boolean tokenWhiteSpace = this.scanner.tokenizeWhiteSpace;
this.scanner.tokenizeWhiteSpace = true;
try {
boolean isCompletionParser = (this.kind & COMPLETION_PARSER) != 0;
if (this.scanner.currentCharacter != ' ' && !ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(start, this.scanner.getCurrentTokenEndPosition());
if (!isCompletionParser) {
this.scanner.currentPosition = start;
this.index = start;
}
this.currentTokenType = -1;
return false;
}
this.identifierPtr = -1;
this.identifierLengthPtr = -1;
boolean hasMultiLines = this.scanner.currentPosition > (this.lineEnd+1);
boolean isTypeParam = false;
boolean valid = true, empty = true;
boolean mayBeGeneric = this.sourceLevel >= ClassFileConstants.JDK1_5;
int token = -1;
nextToken: while (true) {
this.currentTokenType = -1;
try {
token = readToken();
} catch (InvalidInputException e) {
valid = false;
}
switch (token) {
case TerminalTokens.TokenNameIdentifier :
if (valid) {
pushIdentifier(true, false);
start = this.scanner.getCurrentTokenStartPosition();
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
break nextToken;
}
case TerminalTokens.TokenNameLESS:
if (valid && mayBeGeneric) {
pushIdentifier(true, true);
start = this.scanner.getCurrentTokenStartPosition();
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
isTypeParam = true;
break nextToken;
}
default:
if (token == TerminalTokens.TokenNameLEFT_SHIFT) isTypeParam = true;
if (valid && !hasMultiLines) start = this.scanner.getCurrentTokenStartPosition();
valid = false;
if (!hasMultiLines) {
empty = false;
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
break;
}
end = this.lineEnd;
case TerminalTokens.TokenNameWHITESPACE:
if (this.scanner.currentPosition > (this.lineEnd+1)) hasMultiLines = true;
if (valid) break;
case TerminalTokens.TokenNameEOF:
if (this.reportProblems)
if (empty)
this.sourceParser.problemReporter().javadocMissingParamName(start, end, this.sourceParser.modifiers);
else if (mayBeGeneric && isTypeParam)
this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
else
this.sourceParser.problemReporter().javadocInvalidParamTagName(start, end);
if (!isCompletionParser) {
this.scanner.currentPosition = start;
this.index = start;
}
this.currentTokenType = -1;
return false;
}
}
if (isTypeParam && mayBeGeneric) {
nextToken: while (true) {
this.currentTokenType = -1;
try {
token = readToken();
} catch (InvalidInputException e) {
valid = false;
}
switch (token) {
case TerminalTokens.TokenNameWHITESPACE:
if (valid && this.scanner.currentPosition <= (this.lineEnd+1)) {
break;
}
case TerminalTokens.TokenNameEOF:
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
if (!isCompletionParser) {
this.scanner.currentPosition = start;
this.index = start;
}
this.currentTokenType = -1;
return false;
case TerminalTokens.TokenNameIdentifier :
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
if (valid) {
pushIdentifier(false, false);
break nextToken;
}
break;
default:
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
valid = false;
break;
}
}
boolean spaces = false;
nextToken: while (true) {
this.currentTokenType = -1;
try {
token = readToken();
} catch (InvalidInputException e) {
valid = false;
}
switch (token) {
case TerminalTokens.TokenNameWHITESPACE:
if (this.scanner.currentPosition > (this.lineEnd+1)) {
hasMultiLines = true;
valid = false;
}
spaces = true;
if (valid) break;
case TerminalTokens.TokenNameEOF:
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
if (!isCompletionParser) {
this.scanner.currentPosition = start;
this.index = start;
}
this.currentTokenType = -1;
return false;
case TerminalTokens.TokenNameGREATER:
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
if (valid) {
pushIdentifier(false, true);
break nextToken;
}
break;
default:
if (!spaces) end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
valid = false;
break;
}
}
}
if (valid) {
this.currentTokenType = -1;
int restart = this.scanner.currentPosition;
try {
token = readTokenAndConsume();
} catch (InvalidInputException e) {
valid = false;
}
if (token == TerminalTokens.TokenNameWHITESPACE) {
this.scanner.resetTo(restart, this.javadocEnd);
this.index = restart;
return pushParamName(isTypeParam);
}
}
this.currentTokenType = -1;
if (isCompletionParser) return false;
if (this.reportProblems) {
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
try {
while ((token=readToken()) != TerminalTokens.TokenNameWHITESPACE && token != TerminalTokens.TokenNameEOF) {
this.currentTokenType = -1;
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
}
} catch (InvalidInputException e) {
end = this.lineEnd;
}
if (mayBeGeneric && isTypeParam)
this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
else
this.sourceParser.problemReporter().javadocInvalidParamTagName(start, end);
}
this.scanner.currentPosition = start;
this.index = start;
this.currentTokenType = -1;
return false;
} finally {
this.scanner.tokenizeWhiteSpace = tokenWhiteSpace;
}
}
protected Object (boolean reset) throws InvalidInputException {
if (reset) {
this.identifierPtr = -1;
this.identifierLengthPtr = -1;
}
int primitiveToken = -1;
int parserKind = this.kind & PARSER_KIND;
nextToken : for (int iToken = 0; ; iToken++) {
int token = readTokenSafely();
switch (token) {
case TerminalTokens.TokenNameIdentifier :
if (((iToken & 1) != 0)) {
break nextToken;
}
pushIdentifier(iToken == 0, false);
consumeToken();
break;
case TerminalTokens.TokenNameRestrictedIdentifierYield:
throw new InvalidInputException();
case TerminalTokens.TokenNameDOT :
if ((iToken & 1) == 0) {
throw new InvalidInputException();
}
consumeToken();
break;
case TerminalTokens.TokenNameabstract:
case TerminalTokens.TokenNameassert:
case TerminalTokens.TokenNameboolean:
case TerminalTokens.TokenNamebreak:
case TerminalTokens.TokenNamebyte:
case TerminalTokens.TokenNamecase:
case TerminalTokens.TokenNamecatch:
case TerminalTokens.TokenNamechar:
case TerminalTokens.TokenNameclass:
case TerminalTokens.TokenNamecontinue:
case TerminalTokens.TokenNamedefault:
case TerminalTokens.TokenNamedo:
case TerminalTokens.TokenNamedouble:
case TerminalTokens.TokenNameelse:
case TerminalTokens.TokenNameextends:
case TerminalTokens.TokenNamefalse:
case TerminalTokens.TokenNamefinal:
case TerminalTokens.TokenNamefinally:
case TerminalTokens.TokenNamefloat:
case TerminalTokens.TokenNamefor:
case TerminalTokens.TokenNameif:
case TerminalTokens.TokenNameimplements:
case TerminalTokens.TokenNameimport:
case TerminalTokens.TokenNameinstanceof:
case TerminalTokens.TokenNameint:
case TerminalTokens.TokenNameinterface:
case TerminalTokens.TokenNamelong:
case TerminalTokens.TokenNamenative:
case TerminalTokens.TokenNamenew:
case TerminalTokens.TokenNamenull:
case TerminalTokens.TokenNamepackage:
case TerminalTokens.TokenNameprivate:
case TerminalTokens.TokenNameprotected:
case TerminalTokens.TokenNamepublic:
case TerminalTokens.TokenNameshort:
case TerminalTokens.TokenNamestatic:
case TerminalTokens.TokenNamestrictfp:
case TerminalTokens.TokenNamesuper:
case TerminalTokens.TokenNameswitch:
case TerminalTokens.TokenNamesynchronized:
case TerminalTokens.TokenNamethis:
case TerminalTokens.TokenNamethrow:
case TerminalTokens.TokenNametransient:
case TerminalTokens.TokenNametrue:
case TerminalTokens.TokenNametry:
case TerminalTokens.TokenNamevoid:
case TerminalTokens.TokenNamevolatile:
case TerminalTokens.TokenNamewhile:
if (iToken == 0) {
pushIdentifier(true, true);
primitiveToken = token;
consumeToken();
break nextToken;
}
default :
if (iToken == 0) {
if (this.identifierPtr>=0) {
this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
}
return null;
}
if ((iToken & 1) == 0) {
switch (parserKind) {
case COMPLETION_PARSER:
if (this.identifierPtr>=0) {
this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
}
return syntaxRecoverQualifiedName(primitiveToken);
case DOM_PARSER:
if (this.currentTokenType != -1) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
}
default:
throw new InvalidInputException();
}
}
break nextToken;
}
}
if (parserKind != COMPLETION_PARSER && this.currentTokenType != -1) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
}
if (this.identifierPtr>=0) {
this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
}
return createTypeReference(primitiveToken);
}
protected boolean () throws InvalidInputException {
int currentPosition = this.scanner.currentPosition;
try {
Object typeRef = null;
Object reference = null;
int previousPosition = -1;
int typeRefStartPosition = -1;
nextToken : while (this.index < this.scanner.eofPosition) {
previousPosition = this.index;
int token = readTokenSafely();
switch (token) {
case TerminalTokens.TokenNameStringLiteral :
if (typeRef != null) break nextToken;
consumeToken();
int start = this.scanner.getCurrentTokenStartPosition();
if (this.tagValue == TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getTokenEndPosition(), this.sourceParser.modifiers);
return false;
}
if (verifyEndLine(previousPosition)) {
return createFakeReference(start);
}
if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedText(this.scanner.currentPosition, this.lineEnd);
return false;
case TerminalTokens.TokenNameLESS :
if (typeRef != null) break nextToken;
consumeToken();
start = this.scanner.getCurrentTokenStartPosition();
if (parseHref()) {
consumeToken();
if (this.tagValue == TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getIndexPosition(), this.sourceParser.modifiers);
return false;
}
if (verifyEndLine(previousPosition)) {
return createFakeReference(start);
}
if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedText(this.scanner.currentPosition, this.lineEnd);
}
else if (this.tagValue == TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getIndexPosition(), this.sourceParser.modifiers);
}
return false;
case TerminalTokens.TokenNameERROR :
consumeToken();
if (this.scanner.currentCharacter == '#') {
reference = parseMember(typeRef);
if (reference != null) {
return pushSeeRef(reference);
}
return false;
}
char[] currentError = this.scanner.getCurrentIdentifierSource();
if (currentError.length>0 && currentError[0] == '"') {
if (this.reportProblems) {
boolean isUrlRef = false;
if (this.tagValue == TAG_SEE_VALUE) {
int length=currentError.length, i=1 ;
while (i<length && ScannerHelper.isLetter(currentError[i])) {
i++;
}
if (i<(length-2) && currentError[i] == ':' && currentError[i+1] == '/' && currentError[i+2] == '/') {
isUrlRef = true;
}
}
if (isUrlRef) {
this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(this.scanner.getCurrentTokenStartPosition(), getTokenEndPosition());
} else {
this.sourceParser.problemReporter().javadocInvalidReference(this.scanner.getCurrentTokenStartPosition(), getTokenEndPosition());
}
}
return false;
}
break nextToken;
case TerminalTokens.TokenNameIdentifier :
if (typeRef == null) {
typeRefStartPosition = this.scanner.getCurrentTokenStartPosition();
typeRef = parseQualifiedName(true);
if (this.abort) return false;
break;
}
break nextToken;
default :
break nextToken;
}
}
if (reference == null) reference = typeRef;
if (reference == null) {
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
if (this.tagValue == TAG_VALUE_VALUE) {
if ((this.kind & DOM_PARSER) != 0) createTag();
return true;
}
if (this.reportProblems) {
this.sourceParser.problemReporter().javadocMissingReference(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
}
return false;
}
if (this.lastIdentifierEndPosition > this.javadocStart) {
this.index = this.lastIdentifierEndPosition+1;
this.scanner.currentPosition = this.index;
}
this.currentTokenType = -1;
if (this.tagValue == TAG_VALUE_VALUE) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(typeRefStartPosition, this.lineEnd);
return false;
}
int currentIndex = this.index;
char ch = readChar();
switch (ch) {
case '(' :
if (this.reportProblems) this.sourceParser.problemReporter().javadocMissingHashCharacter(typeRefStartPosition, this.lineEnd, String.valueOf(this.source, typeRefStartPosition, this.lineEnd-typeRefStartPosition+1));
return false;
case ':' :
ch = readChar();
if (ch == '/' && ch == readChar()) {
if (this.reportProblems) {
this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(typeRefStartPosition, this.lineEnd);
return false;
}
}
}
this.index = currentIndex;
if (!verifySpaceOrEndComment()) {
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.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(typeRefStartPosition, end);
return false;
}
return pushSeeRef(reference);
}
catch (InvalidInputException ex) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(currentPosition, getTokenEndPosition());
}
this.index = this.tokenPreviousPosition;
this.scanner.currentPosition = this.tokenPreviousPosition;
this.currentTokenType = -1;
return false;
}
protected abstract boolean (int previousPosition) throws InvalidInputException;
protected boolean () {
int start = this.scanner.currentPosition;
try {
Object typeRef = parseQualifiedName(true);
if (this.abort) return false;
if (typeRef == null) {
if (this.reportProblems)
this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
} else {
return pushThrowName(typeRef);
}
} catch (InvalidInputException ex) {
if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidThrowsClass(start, getTokenEndPosition());
}
return false;
}
protected char () {
int idx = this.index;
char c = this.source[idx++];
if (c == '\\' && this.source[idx] == 'u') {
int c1, c2, c3, c4;
idx++;
while (this.source[idx] == 'u')
idx++;
if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c1 < 0)
|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c2 < 0)
|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c3 < 0)
|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c4 < 0))) {
c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
return c;
}
protected void (boolean newLength, boolean isToken) {
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);
}
this.identifierStack[this.identifierPtr] = isToken ? this.scanner.getCurrentTokenSource() : 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);
}
this.identifierLengthStack[this.identifierLengthPtr] = 1;
} else {
this.identifierLengthStack[this.identifierLengthPtr]++;
}
}
protected void (Object node, boolean newLength) {
if (node == null) {
int stackLength = this.astLengthStack.length;
if (++this.astLengthPtr >= stackLength) {
System.arraycopy(
this.astLengthStack, 0,
this.astLengthStack = new int[stackLength + AST_STACK_INCREMENT], 0,
stackLength);
}
this.astLengthStack[this.astLengthPtr] = 0;
return;
}
int stackLength = this.astStack.length;
if (++this.astPtr >= stackLength) {
System.arraycopy(
this.astStack, 0,
this.astStack = new Object[stackLength + AST_STACK_INCREMENT], 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 + AST_STACK_INCREMENT], 0,
stackLength);
}
this.astLengthStack[this.astLengthPtr] = 1;
} else {
this.astLengthStack[this.astLengthPtr]++;
}
}
protected abstract boolean (boolean isTypeParam);
protected abstract boolean (Object statement);
protected void (int start, int end) {
}
protected abstract boolean (Object typeRef);
protected char () {
char c = this.source[this.index++];
if (c == '\\' && this.source[this.index] == 'u') {
int c1, c2, c3, c4;
int pos = this.index;
this.index++;
while (this.source[this.index] == 'u')
this.index++;
if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0)
|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0)
|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0)
|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) {
c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
} else {
this.index = pos;
}
}
return c;
}
protected int () throws InvalidInputException {
if (this.currentTokenType < 0) {
this.tokenPreviousPosition = this.scanner.currentPosition;
this.currentTokenType = this.scanner.getNextToken();
if (this.scanner.currentPosition > (this.lineEnd+1)) {
this.lineStarted = false;
while (this.currentTokenType == TerminalTokens.TokenNameMULTIPLY) {
this.currentTokenType = this.scanner.getNextToken();
}
}
this.index = this.scanner.currentPosition;
this.lineStarted = true;
}
return this.currentTokenType;
}
protected int readTokenAndConsume() throws InvalidInputException {
int token = readToken();
consumeToken();
return token;
}
protected int () {
int token = TerminalTokens.TokenNameERROR;
try {
token = readToken();
}
catch (InvalidInputException iie) {
}
return token;
}
protected void (long position) {
if (this.inheritedPositions == null) {
this.inheritedPositions = new long[INHERITED_POSITIONS_ARRAY_INCREMENT];
this.inheritedPositionsPtr = 0;
} else {
if (this.inheritedPositionsPtr == this.inheritedPositions.length) {
System.arraycopy(
this.inheritedPositions, 0,
this.inheritedPositions = new long[this.inheritedPositionsPtr + INHERITED_POSITIONS_ARRAY_INCREMENT], 0,
this.inheritedPositionsPtr);
}
}
this.inheritedPositions[this.inheritedPositionsPtr++] = position;
}
protected void (int previousPosition) {
}
protected void () {
}
protected void (boolean started) {
this.inlineTagStarted = started;
}
protected Object (int primitiveToken) throws InvalidInputException {
return null;
}
@Override
public String () {
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;
if (startPos == this.source.length)
return "EOF\n\n" + new String(this.source);
if (endPos > this.source.length)
return "behind the EOF\n\n" + new String(this.source);
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);
} 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);
buffer.append(front);
if (this.scanner.currentPosition<this.index) {
buffer.append("\n===============================\nScanner current position here -->");
} else {
buffer.append("\n===============================\nParser index here -->");
}
buffer.append(middle);
if (this.scanner.currentPosition<this.index) {
buffer.append("<-- Parser index here\n===============================\n");
} else {
buffer.append("<-- Scanner current position here\n===============================\n");
}
buffer.append(end);
return buffer.toString();
}
protected abstract void ();
protected void () {
while (this.index > (this.lineEnd+1)) {
if (this.linePtr < this.lastLinePtr) {
this.lineEnd = this.scanner.getLineEnd(++this.linePtr) - 1;
} else {
this.lineEnd = this.javadocEnd;
return;
}
}
}
protected boolean (int textPosition) {
boolean domParser = (this.kind & DOM_PARSER) != 0;
if (this.inlineTagStarted) {
if (peekChar() == '}') {
if (domParser) {
createTag();
pushText(textPosition, this.index);
}
return true;
}
return false;
}
int startPosition = this.index;
int previousPosition = this.index;
this.starPosition = -1;
char ch = readChar();
nextChar: while (true) {
switch (ch) {
case '\r':
case '\n':
if (domParser) {
createTag();
pushText(textPosition, previousPosition);
}
this.index = previousPosition;
return true;
case '\u000c' :
case ' ' :
case '\t' :
if (this.starPosition >= 0) break nextChar;
break;
case '*':
this.starPosition = previousPosition;
break;
case '/':
if (this.starPosition >= textPosition) {
if (domParser) {
createTag();
pushText(textPosition, this.starPosition);
}
return true;
}
break nextChar;
default :
break nextChar;
}
previousPosition = this.index;
ch = readChar();
}
this.index = startPosition;
return false;
}
protected boolean () {
this.starPosition = -1;
int startPosition = this.index;
char ch = peekChar();
switch (ch) {
case '}':
return this.inlineTagStarted;
default:
if (ScannerHelper.isWhitespace(ch)) {
return true;
}
}
int previousPosition = this.index;
ch = readChar();
while (this.index<this.source.length) {
switch (ch) {
case '*':
this.starPosition = previousPosition;
break;
case '/':
if (this.starPosition >= startPosition) {
return true;
}
default :
this.index = startPosition;
return false;
}
previousPosition = this.index;
ch = readChar();
}
this.index = startPosition;
return false;
}
}