package org.eclipse.jdt.internal.codeassist.complete;
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.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
@SuppressWarnings({"rawtypes", "unchecked"})
public class CompletionJavadocParser extends JavadocParser {
public final static int INLINE_ALL_TAGS_LENGTH;
public final static int BLOCK_ALL_TAGS_LENGTH;
static {
int length = 0;
for (int i=0; i<INLINE_TAGS_LENGTH; i++) {
length += INLINE_TAGS[i].length;
}
INLINE_ALL_TAGS_LENGTH = length;
length = 0;
for (int i=0; i<BLOCK_TAGS_LENGTH; i++) {
length += BLOCK_TAGS[i].length;
}
BLOCK_ALL_TAGS_LENGTH = length;
}
char[][][] levelTags = new char[2][][];
int[] levelTagsLength = new int[2];
int cursorLocation;
CompletionOnJavadoc completionNode = null;
boolean pushText = false;
boolean allPossibleTags = false;
public CompletionJavadocParser(CompletionParser sourceParser) {
super(sourceParser);
this.scanner = new CompletionScanner(ClassFileConstants.JDK1_3);
this.kind = COMPLETION_PARSER | TEXT_PARSE;
initLevelTags();
}
@Override
public boolean checkDeprecation(int commentPtr) {
boolean isDeprecated = false;
this.cursorLocation = ((CompletionParser)this.sourceParser).cursorLocation;
CompletionScanner completionScanner = (CompletionScanner)this.scanner;
completionScanner.cursorLocation = this.cursorLocation;
this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr];
if (this.javadocStart <= this.cursorLocation && this.cursorLocation <= this.javadocEnd) {
if (CompletionEngine.DEBUG) {
System.out.println("COMPLETION in Javadoc:");
}
completionScanner.completionIdentifier = null;
super.checkDeprecation(commentPtr);
} else {
if (this.sourceParser.scanner.commentTagStarts[commentPtr] != 0) {
boolean previousValue = this.checkDocComment;
this.checkDocComment = false;
isDeprecated = super.checkDeprecation(commentPtr);
this.checkDocComment = previousValue;
}
this.docComment = null;
}
return isDeprecated;
}
@Override
protected boolean () {
this.docComment = new CompletionJavadoc(this.javadocStart, this.javadocEnd);
this.firstTagPosition = 1;
return super.commentParse();
}
@Override
protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
char[] argName = name==null ? CharOperation.NO_CHAR : name;
Expression expression = (Expression) super.createArgumentReference(argName, dim, isVarargs, typeRef, dimPositions, argNamePos);
int refStart = ((TypeReference)typeRef).sourceStart;
int refEnd = ((TypeReference)typeRef).sourceEnd;
boolean inCompletion = (refStart <= this.cursorLocation && this.cursorLocation <= refEnd)
|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation));
if (this.completionNode == null && inCompletion) {
JavadocArgumentExpression javadocArgument = (JavadocArgumentExpression) expression;
TypeReference expressionType = javadocArgument.argument.type;
if (expressionType instanceof JavadocSingleTypeReference) {
this.completionNode = new CompletionOnJavadocSingleTypeReference((JavadocSingleTypeReference) expressionType);
} else if (expressionType instanceof JavadocQualifiedTypeReference) {
this.completionNode = new CompletionOnJavadocQualifiedTypeReference((JavadocQualifiedTypeReference) expressionType);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion argument="+this.completionNode);
}
return this.completionNode;
}
return expression;
}
@Override
protected Object createFieldReference(Object receiver) throws InvalidInputException {
int refStart = (int) (this.identifierPositionStack[0] >>> 32);
int refEnd = (int) this.identifierPositionStack[0];
boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd)
|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation))
|| (this.memberStart == this.cursorLocation);
if (inCompletion) {
JavadocFieldReference fieldRef = (JavadocFieldReference) super.createFieldReference(receiver);
char[] name = this.sourceParser.compilationUnit.getMainTypeName();
TypeDeclaration typeDecl = getParsedTypeDeclaration();
if (typeDecl != null) {
name = typeDecl.name;
}
this.completionNode = new CompletionOnJavadocFieldReference(fieldRef, this.memberStart, name);
if (CompletionEngine.DEBUG) {
System.out.println(" completion field="+this.completionNode);
}
return this.completionNode;
}
return super.createFieldReference(receiver);
}
@Override
protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
int memberPtr = this.identifierLengthStack[0] - 1;
int refStart = (int) (this.identifierPositionStack[memberPtr] >>> 32);
int refEnd = (int) this.identifierPositionStack[memberPtr];
boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd)
|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation))
|| (this.memberStart == this.cursorLocation);
if (inCompletion) {
ASTNode node = (ASTNode) super.createMethodReference(receiver, arguments);
if (node instanceof JavadocMessageSend) {
JavadocMessageSend messageSend = (JavadocMessageSend) node;
int nameStart = (int) (messageSend.nameSourcePosition >>> 32);
int nameEnd = (int) messageSend.nameSourcePosition;
if ((nameStart <= (this.cursorLocation+1) && this.cursorLocation <= nameEnd)) {
this.completionNode = new CompletionOnJavadocFieldReference(messageSend, this.memberStart);
} else {
this.completionNode = new CompletionOnJavadocMessageSend(messageSend, this.memberStart);
}
} else if (node instanceof JavadocAllocationExpression) {
this.completionNode = new CompletionOnJavadocAllocationExpression((JavadocAllocationExpression)node, this.memberStart);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion method="+this.completionNode);
}
return this.completionNode;
}
return super.createMethodReference(receiver, arguments);
}
@Override
protected Object createTypeReference(int primitiveToken) {
int nbIdentifiers = this.identifierLengthStack[this.identifierLengthPtr];
int startPtr = this.identifierPtr - (nbIdentifiers-1);
int refStart = (int) (this.identifierPositionStack[startPtr] >>> 32);
int refEnd = (int) this.identifierPositionStack[this.identifierPtr];
boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd)
|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation));
if (!inCompletion) {
return super.createTypeReference(primitiveToken);
}
this.identifierLengthPtr--;
if (nbIdentifiers == 1) {
this.completionNode = new CompletionOnJavadocSingleTypeReference(
this.identifierStack[this.identifierPtr],
this.identifierPositionStack[this.identifierPtr],
this.tagSourceStart,
this.tagSourceEnd);
} else if (nbIdentifiers > 1) {
for (int i=startPtr; i<this.identifierPtr; i++) {
int start = (int) (this.identifierPositionStack[i] >>> 32);
int end = (int) this.identifierPositionStack[i];
if (start <= this.cursorLocation && this.cursorLocation <= end) {
if (i == startPtr) {
this.completionNode = new CompletionOnJavadocSingleTypeReference(
this.identifierStack[startPtr],
this.identifierPositionStack[startPtr],
this.tagSourceStart,
this.tagSourceEnd);
} else {
char[][] tokens = new char[i][];
System.arraycopy(this.identifierStack, startPtr, tokens, 0, i);
long[] positions = new long[i+1];
System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, i+1);
this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, this.identifierStack[i], positions, this.tagSourceStart, this.tagSourceEnd);
}
break;
}
}
if (this.completionNode == null) {
char[][] tokens = new char[nbIdentifiers-1][];
System.arraycopy(this.identifierStack, startPtr, tokens, 0, nbIdentifiers-1);
long[] positions = new long[nbIdentifiers];
System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, nbIdentifiers);
this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, this.identifierStack[this.identifierPtr], positions, this.tagSourceStart, this.tagSourceEnd);
}
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion partial qualified type="+this.completionNode);
}
return this.completionNode;
}
private char[][][] possibleTags(char[] prefix, boolean newLine) {
char[][][] possibleTags = new char[2][][];
if (newLine) {
System.arraycopy(this.levelTags[BLOCK_IDX], 0, possibleTags[BLOCK_IDX] = new char[this.levelTagsLength[BLOCK_IDX]][], 0, this.levelTagsLength[BLOCK_IDX]);
} else {
possibleTags[BLOCK_IDX] = CharOperation.NO_CHAR_CHAR;
}
System.arraycopy(this.levelTags[INLINE_IDX], 0, possibleTags[INLINE_IDX] = new char[this.levelTagsLength[INLINE_IDX]][], 0, this.levelTagsLength[INLINE_IDX]);
if (prefix == null || prefix.length == 0) return possibleTags;
int kinds = this.levelTags.length;
for (int k=0; k<kinds; k++) {
int length = possibleTags[k].length, size = 0;
int indexes[] = new int[length];
for (int i=0; i<length; i++) {
if (CharOperation.prefixEquals(prefix, possibleTags[k][i], false)) {
indexes[size++] = i;
}
}
char[][] tags = new char[size][];
for (int i=0; i<size; i++) {
tags[i] = possibleTags[k][indexes[i]];
}
possibleTags[k] = tags;
}
return possibleTags;
}
private CompletionJavadoc getCompletionJavadoc() {
return (CompletionJavadoc)this.docComment;
}
private CompletionParser getCompletionParser() {
return (CompletionParser)this.sourceParser;
}
private void initLevelTags() {
int level = ((int)(this.complianceLevel >>> 16)) - ClassFileConstants.MAJOR_VERSION_1_1 + 1;
if ( level >= BLOCK_TAGS_LENGTH)
return;
this.levelTags[BLOCK_IDX] = new char[BLOCK_ALL_TAGS_LENGTH][];
this.levelTagsLength[BLOCK_IDX] = 0;
for (int i=0; i<=level; i++) {
int length = BLOCK_TAGS[i].length;
System.arraycopy(BLOCK_TAGS[i], 0, this.levelTags[BLOCK_IDX], this.levelTagsLength[BLOCK_IDX], length);
this.levelTagsLength[BLOCK_IDX] += length;
}
if (this.levelTagsLength[BLOCK_IDX] < BLOCK_ALL_TAGS_LENGTH) {
System.arraycopy(this.levelTags[BLOCK_IDX], 0, this.levelTags[BLOCK_IDX] = new char[this.levelTagsLength[BLOCK_IDX]][], 0, this.levelTagsLength[BLOCK_IDX]);
}
this.levelTags[INLINE_IDX] = new char[INLINE_ALL_TAGS_LENGTH][];
this.levelTagsLength[INLINE_IDX]= 0;
for (int i=0; i<=level; i++) {
int length = INLINE_TAGS[i].length;
System.arraycopy(INLINE_TAGS[i], 0, this.levelTags[INLINE_IDX], this.levelTagsLength[INLINE_IDX], length);
this.levelTagsLength[INLINE_IDX] += length;
}
if (this.levelTagsLength[INLINE_IDX] < INLINE_ALL_TAGS_LENGTH) {
System.arraycopy(this.levelTags[INLINE_IDX], 0, this.levelTags[INLINE_IDX] = new char[this.levelTagsLength[INLINE_IDX]][], 0, this.levelTagsLength[INLINE_IDX]);
}
}
@Override
protected Object parseArguments(Object receiver) throws InvalidInputException {
if (this.tagSourceStart>this.cursorLocation) {
return super.parseArguments(receiver);
}
int modulo = 0;
int iToken = 0;
char[] argName = null;
List arguments = new ArrayList(10);
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 && getCurrentTokenType() == TerminalTokens.TokenNameRPAREN) {
this.lineStarted = true;
return createMethodReference(receiver, null);
}
Object methodRef = createMethodReference(receiver, arguments);
return syntaxRecoverEmptyArgumentType(methodRef);
}
if (this.index >= this.scanner.eofPosition) {
int argumentStart = ((ASTNode)typeRef).sourceStart;
Object argument = createArgumentReference(this.scanner.getCurrentIdentifierSource(), 0, false, typeRef, null, (((long)argumentStart)<<32)+this.tokenPreviousPosition-1);
return syntaxRecoverArgumentType(receiver, arguments, argument);
}
if (this.index >= this.cursorLocation) {
if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
if (singleTypeReference.token == null || singleTypeReference.token.length == 0) {
Object methodRef = createMethodReference(receiver, arguments);
return syntaxRecoverEmptyArgumentType(methodRef);
}
}
if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
CompletionOnJavadocQualifiedTypeReference qualifiedTypeReference = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
if (qualifiedTypeReference.tokens == null || qualifiedTypeReference.tokens.length < qualifiedTypeReference.sourcePositions.length) {
Object methodRef = createMethodReference(receiver, arguments);
return syntaxRecoverEmptyArgumentType(methodRef);
}
}
}
iToken++;
dim = 0;
isVarargs = false;
if (readToken() == TerminalTokens.TokenNameLBRACKET) {
int dimStart = this.scanner.getCurrentTokenStartPosition();
while (readToken() == TerminalTokens.TokenNameLBRACKET) {
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) {
Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
if (this.abort) return null;
arguments.add(argument);
consumeToken();
return createMethodReference(receiver, arguments);
} else {
Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
return syntaxRecoverArgumentType(receiver, arguments, argument);
}
}
throw new InvalidInputException();
}
@Override
protected boolean parseParam() throws InvalidInputException {
int startPosition = this.index;
int endPosition = this.index;
long namePosition = (((long)startPosition)<<32) + endPosition;
this.identifierPtr = -1;
boolean valid = super.parseParam();
if (this.identifierPtr > 2) return valid;
char[] name = null;
CompletionScanner completionScanner = (CompletionScanner) this.scanner;
boolean isTypeParam = false;
if (this.identifierPtr >= 0) {
char[] identifier = null;
switch (this.identifierPtr) {
case 2:
if (!valid && completionScanner.completionIdentifier != null && completionScanner.completionIdentifier.length == 0) {
valid = pushParamName(true);
}
case 1:
isTypeParam = this.identifierStack[0][0] == '<';
identifier = this.identifierStack[1];
namePosition = this.identifierPositionStack[1];
break;
case 0:
identifier = this.identifierStack[0];
namePosition = this.identifierPositionStack[0];
isTypeParam = identifier.length > 0 && identifier[0] == '<';
break;
}
if (identifier != null && identifier.length > 0 && ScannerHelper.isJavaIdentifierPart(this.complianceLevel, identifier[0])) {
name = identifier;
}
startPosition = (int)(this.identifierPositionStack[0]>>32);
endPosition = (int)this.identifierPositionStack[this.identifierPtr];
}
boolean inCompletion = (startPosition <= (this.cursorLocation+1) && this.cursorLocation <= endPosition)
|| ((startPosition == (endPosition+1) && endPosition == this.cursorLocation));
if (inCompletion) {
if (this.completionNode == null) {
if (isTypeParam) {
this.completionNode = new CompletionOnJavadocTypeParamReference(name, namePosition, startPosition, endPosition);
} else {
this.completionNode = new CompletionOnJavadocParamNameReference(name, namePosition, startPosition, endPosition);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion param="+this.completionNode);
}
} else if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
CompletionOnJavadocParamNameReference paramNameRef = (CompletionOnJavadocParamNameReference)this.completionNode;
int nameStart = (int) (namePosition>>32);
paramNameRef.sourceStart = nameStart;
int nameEnd = (int) namePosition;
if (nameStart<this.cursorLocation && this.cursorLocation<nameEnd) {
paramNameRef.sourceEnd = this.cursorLocation + 1;
} else {
paramNameRef.sourceEnd = nameEnd;
}
paramNameRef.tagSourceStart = startPosition;
paramNameRef.tagSourceEnd = endPosition;
} else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
CompletionOnJavadocTypeParamReference typeParamRef = (CompletionOnJavadocTypeParamReference)this.completionNode;
int nameStart = (int) (namePosition>>32);
typeParamRef.sourceStart = nameStart;
int nameEnd = (int) namePosition;
if (nameStart<this.cursorLocation && this.cursorLocation<nameEnd) {
typeParamRef.sourceEnd = this.cursorLocation + 1;
} else {
typeParamRef.sourceEnd = nameEnd;
}
typeParamRef.tagSourceStart = startPosition;
typeParamRef.tagSourceEnd = endPosition;
}
}
return valid;
}
@Override
protected boolean parseReference() throws InvalidInputException {
boolean completed = this.completionNode != null;
boolean valid = super.parseReference();
if (!completed && this.completionNode != null) {
this.completionNode.addCompletionFlags(CompletionOnJavadoc.FORMAL_REFERENCE);
}
return valid;
}
@Override
protected boolean parseTag(int previousPosition) throws InvalidInputException {
int startPosition = this.inlineTagStarted ? this.inlineTagStart : previousPosition;
boolean newLine = !this.lineStarted;
boolean valid = super.parseTag(previousPosition);
boolean inCompletion = (this.tagSourceStart <= (this.cursorLocation+1) && this.cursorLocation <= this.tagSourceEnd)
|| ((this.tagSourceStart == (this.tagSourceEnd+1) && this.tagSourceEnd == this.cursorLocation));
if (inCompletion) {
int end = this.tagSourceEnd;
if (this.inlineTagStarted && this.scanner.currentCharacter == '}') {
end = this.scanner.currentPosition;
}
long position = (((long)startPosition)<<32) + end;
int length = this.cursorLocation+1-this.tagSourceStart;
char[] tag = new char[length];
System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
char[][][] tags = possibleTags(tag, newLine);
if (tags != null) {
this.completionNode = new CompletionOnJavadocTag(tag, position, startPosition, end, tags, this.allPossibleTags);
}
}
return valid;
}
@Override
protected boolean parseThrows() {
try {
Object typeRef = parseQualifiedName(true);
if (this.completionNode != null) {
this.completionNode.addCompletionFlags(CompletionOnJavadoc.EXCEPTION);
}
return pushThrowName(typeRef);
} catch (InvalidInputException ex) {
}
return false;
}
@Override
protected boolean pushParamName(boolean isTypeParam) {
if (super.pushParamName(isTypeParam)) {
Expression expression = (Expression) this.astStack[this.astPtr];
if (expression.sourceStart <= (this.cursorLocation+1) && this.cursorLocation <= expression.sourceEnd) {
if (isTypeParam) {
this.completionNode = new CompletionOnJavadocTypeParamReference((JavadocSingleTypeReference)expression);
} else {
this.completionNode = new CompletionOnJavadocParamNameReference((JavadocSingleNameReference)expression);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion param="+this.completionNode);
}
}
return true;
}
return false;
}
@Override
protected void pushText(int start, int end) {
if (start <= this.cursorLocation && this.cursorLocation <= end) {
this.scanner.resetTo(start, end);
boolean tokenizeWhiteSpace = this.scanner.tokenizeWhiteSpace;
this.scanner.tokenizeWhiteSpace = true;
try {
Object typeRef = null;
this.pushText = true;
int previousToken = TerminalTokens.TokenNameWHITESPACE;
while (!this.scanner.atEnd() && this.completionNode == null && !this.abort) {
int token = readTokenSafely();
switch (token) {
case TerminalTokens.TokenNameStringLiteral :
int strStart = 0, strEnd = 0;
if ((strStart=this.scanner.getCurrentTokenStartPosition()+1) <= this.cursorLocation &&
this.cursorLocation <= (strEnd=this.scanner.getCurrentTokenEndPosition()-1))
{
this.scanner.resetTo(strStart, strEnd);
}
consumeToken();
break;
case TerminalTokens.TokenNameERROR :
consumeToken();
if (this.scanner.currentCharacter == '#') {
Object member = null;
try {
this.scanner.tokenizeWhiteSpace = false;
member = parseMember(typeRef);
} catch (InvalidInputException e) {
consumeToken();
}
this.scanner.tokenizeWhiteSpace = true;
if (this.completionNode != null) {
int flags = this.inlineTagStarted ? 0 : CompletionOnJavadoc.TEXT|CompletionOnJavadoc.ONLY_INLINE_TAG;
if (member instanceof JavadocMessageSend) {
JavadocMessageSend msgSend = (JavadocMessageSend) member;
this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart, flags);
if (CompletionEngine.DEBUG) {
System.out.println(" new completion method="+this.completionNode);
}
} else if (member instanceof JavadocAllocationExpression) {
JavadocAllocationExpression alloc = (JavadocAllocationExpression) member;
this.completionNode = new CompletionOnJavadocAllocationExpression(alloc, this.memberStart, flags);
if (CompletionEngine.DEBUG) {
System.out.println(" new completion method="+this.completionNode);
}
} else {
this.completionNode.addCompletionFlags(flags);
}
}
}
break;
case TerminalTokens.TokenNameIdentifier :
try {
this.scanner.tokenizeWhiteSpace = false;
typeRef = parseQualifiedName(true);
if (this.completionNode == null) {
consumeToken();
this.scanner.resetTo(this.tokenPreviousPosition, end);
this.index = this.tokenPreviousPosition;
}
}
catch (InvalidInputException e) {
consumeToken();
}
finally {
this.scanner.tokenizeWhiteSpace = true;
}
if (previousToken != TerminalTokens.TokenNameWHITESPACE) {
typeRef = null;
this.completionNode = null;
}
break;
case TerminalTokens.TokenNameAT:
consumeToken();
try {
this.scanner.tokenizeWhiteSpace = false;
int startPosition = this.scanner.getCurrentTokenStartPosition();
parseTag(startPosition);
if (this.completionNode != null) {
if (this.inlineTagStarted) {
} else {
}
}
} catch (InvalidInputException e) {
consumeToken();
}
this.scanner.tokenizeWhiteSpace = true;
break;
default :
consumeToken();
typeRef = null;
break;
}
previousToken = token;
}
}
finally {
this.scanner.tokenizeWhiteSpace = tokenizeWhiteSpace;
this.pushText = false;
}
this.index = end;
this.scanner.currentPosition = end;
consumeToken();
if (this.completionNode != null) {
if (this.inlineTagStarted) {
this.completionNode.addCompletionFlags(CompletionOnJavadoc.FORMAL_REFERENCE);
} else {
this.completionNode.addCompletionFlags(CompletionOnJavadoc.TEXT);
}
}
}
}
@Override
protected int readToken() throws InvalidInputException {
int token = super.readToken();
if (token == TerminalTokens.TokenNameIdentifier && this.scanner.currentPosition == this.scanner.startPosition) {
this.scanner.getCurrentIdentifierSource();
}
return token;
}
@Override
protected Object syntaxRecoverQualifiedName(int primitiveToken) throws InvalidInputException {
if (this.cursorLocation == ((int)this.identifierPositionStack[this.identifierPtr])) {
return createTypeReference(primitiveToken);
}
int idLength = this.identifierLengthStack[this.identifierLengthPtr];
char[][] tokens = new char[idLength][];
int startPtr = this.identifierPtr-idLength+1;
System.arraycopy(this.identifierStack, startPtr, tokens, 0, idLength);
long[] positions = new long[idLength+1];
System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, idLength);
positions[idLength] = (((long)this.tokenPreviousPosition)<<32) + this.tokenPreviousPosition;
this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, CharOperation.NO_CHAR, positions, this.tagSourceStart, this.tagSourceEnd);
if (CompletionEngine.DEBUG) {
System.out.println(" completion partial qualified type="+this.completionNode);
}
return this.completionNode;
}
protected Object syntaxRecoverArgumentType(Object receiver, List arguments, Object argument) throws InvalidInputException {
if (this.completionNode != null && !this.pushText) {
this.completionNode.addCompletionFlags(CompletionOnJavadoc.BASE_TYPES);
if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
char[] token = ((CompletionOnJavadocSingleTypeReference)this.completionNode).token;
if (token != null && token.length > 0) {
return this.completionNode;
}
} else {
return this.completionNode;
}
}
if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
if (singleTypeReference.token != null && singleTypeReference.token.length > 0) {
arguments.add(argument);
}
} else if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
CompletionOnJavadocQualifiedTypeReference qualifiedTypeReference = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
if (qualifiedTypeReference.tokens != null && qualifiedTypeReference.tokens.length == qualifiedTypeReference.sourcePositions.length) {
arguments.add(argument);
}
} else {
arguments.add(argument);
}
Object methodRef = super.createMethodReference(receiver, arguments);
if (methodRef instanceof JavadocMessageSend) {
JavadocMessageSend msgSend = (JavadocMessageSend) methodRef;
if (this.index > this.cursorLocation) {
msgSend.sourceEnd = this.tokenPreviousPosition-1;
}
int nameStart = (int) (msgSend.nameSourcePosition >>> 32);
int nameEnd = (int) msgSend.nameSourcePosition;
if ((nameStart <= (this.cursorLocation+1) && this.cursorLocation <= nameEnd)) {
this.completionNode = new CompletionOnJavadocFieldReference(msgSend, this.memberStart);
} else {
this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart);
}
} else if (methodRef instanceof JavadocAllocationExpression) {
JavadocAllocationExpression allocExp = (JavadocAllocationExpression) methodRef;
if (this.index > this.cursorLocation) {
allocExp.sourceEnd = this.tokenPreviousPosition-1;
}
this.completionNode = new CompletionOnJavadocAllocationExpression(allocExp, this.memberStart);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion method="+this.completionNode);
}
return this.completionNode;
}
protected Object syntaxRecoverEmptyArgumentType(Object methodRef) throws InvalidInputException {
if (methodRef instanceof JavadocMessageSend) {
JavadocMessageSend msgSend = (JavadocMessageSend) methodRef;
if (this.index > this.cursorLocation) {
msgSend.sourceEnd = this.tokenPreviousPosition-1;
}
this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart);
} else if (methodRef instanceof JavadocAllocationExpression) {
JavadocAllocationExpression allocExp = (JavadocAllocationExpression) methodRef;
if (this.index > this.cursorLocation) {
allocExp.sourceEnd = this.tokenPreviousPosition-1;
}
this.completionNode = new CompletionOnJavadocAllocationExpression(allocExp, this.memberStart);
}
if (CompletionEngine.DEBUG) {
System.out.println(" completion method="+this.completionNode);
}
return this.completionNode;
}
@Override
protected void () {
super.updateDocComment();
if (this.completionNode instanceof Expression && ((Expression) this.completionNode).isTrulyExpression()) {
getCompletionParser().assistNodeParent = this.docComment;
getCompletionParser().assistNode = (ASTNode) this.completionNode;
getCompletionJavadoc().completionNode = (Expression) this.completionNode;
}
}
@Override
protected boolean () {
CompletionScanner completionScanner = (CompletionScanner) this.scanner;
if (completionScanner.completionIdentifier != null && completionScanner.completedIdentifierStart <= this.cursorLocation && this.cursorLocation <= completionScanner.completedIdentifierEnd) {
return true;
}
return super.verifySpaceOrEndComment();
}
}