package org.eclipse.jdt.internal.codeassist.impl;
import java.util.HashSet;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ModuleReference;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.ast.RequiresStatement;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.RecoveredBlock;
import org.eclipse.jdt.internal.compiler.parser.RecoveredElement;
import org.eclipse.jdt.internal.compiler.parser.RecoveredExportsStatement;
import org.eclipse.jdt.internal.compiler.parser.RecoveredField;
import org.eclipse.jdt.internal.compiler.parser.RecoveredInitializer;
import org.eclipse.jdt.internal.compiler.parser.RecoveredLocalVariable;
import org.eclipse.jdt.internal.compiler.parser.RecoveredMethod;
import org.eclipse.jdt.internal.compiler.parser.RecoveredStatement;
import org.eclipse.jdt.internal.compiler.parser.RecoveredType;
import org.eclipse.jdt.internal.compiler.parser.RecoveredUnit;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
public abstract class AssistParser extends Parser {
public ASTNode assistNode;
public boolean isOrphanCompletionNode;
private boolean resumedAfterRepair = false;
protected int lastModifiers = ClassFileConstants.AccDefault;
protected int = -1;
int[] blockStarts = new int[30];
protected int previousToken;
protected int previousIdentifierPtr;
protected int bracketDepth;
protected static final int ElementStackIncrement = 100;
protected int elementPtr;
protected int[] elementKindStack = new int[ElementStackIncrement];
protected int[] elementInfoStack = new int[ElementStackIncrement];
protected Object[] elementObjectInfoStack = new Object[ElementStackIncrement];
protected int previousKind;
protected int previousInfo;
protected Object previousObjectInfo;
protected static final int ASSIST_PARSER = 512;
protected static final int K_SELECTOR = ASSIST_PARSER + 1;
protected static final int K_TYPE_DELIMITER = ASSIST_PARSER + 2;
protected static final int K_METHOD_DELIMITER = ASSIST_PARSER + 3;
protected static final int K_FIELD_INITIALIZER_DELIMITER = ASSIST_PARSER + 4;
protected static final int K_ATTRIBUTE_VALUE_DELIMITER = ASSIST_PARSER + 5;
protected static final int K_ENUM_CONSTANT_DELIMITER = ASSIST_PARSER + 6;
protected static final int K_LAMBDA_EXPRESSION_DELIMITER = ASSIST_PARSER + 7;
protected static final int K_MODULE_INFO_DELIMITER = ASSIST_PARSER + 8;
protected static final int K_SWITCH_EXPRESSION_DELIMITTER = ASSIST_PARSER + 9;
protected static final int THIS_CONSTRUCTOR = -1;
protected static final int SUPER_CONSTRUCTOR = -2;
protected static final int NO_BODY = 0;
protected static final int WITH_BODY = 1;
protected static final int EXPRESSION_BODY = 0;
protected static final int BLOCK_BODY = 1;
protected boolean isFirst = false;
AssistParser[] snapShotStack = new AssistParser[3];
int[] snapShotPositions = new int[3];
int snapShotPtr = -1;
protected static final int[] RECOVERY_TOKENS = { TokenNameSEMICOLON, TokenNameRPAREN, TokenNameRBRACE, TokenNameRBRACKET};
public AssistParser(ProblemReporter problemReporter) {
super(problemReporter, true);
this.javadocParser.checkDocComment = false;
setMethodsFullRecovery(false);
setStatementsRecovery(false);
}
public abstract char[] assistIdentifier();
@Override
public void copyState(Parser from) {
super.copyState(from);
AssistParser parser = (AssistParser) from;
this.previousToken = parser.previousToken;
this.previousIdentifierPtr = parser.previousIdentifierPtr;
this.lastModifiers = parser.lastModifiers;
this.lastModifiersStart = parser.lastModifiersStart;
this.bracketDepth = parser.bracketDepth;
this.elementPtr = parser.elementPtr;
int length;
System.arraycopy(parser.blockStarts, 0, this.blockStarts = new int [length = parser.blockStarts.length], 0, length);
System.arraycopy(parser.elementKindStack, 0, this.elementKindStack = new int [length = parser.elementKindStack.length], 0, length);
System.arraycopy(parser.elementInfoStack, 0, this.elementInfoStack = new int [length = parser.elementInfoStack.length], 0, length);
System.arraycopy(parser.elementObjectInfoStack, 0, this.elementObjectInfoStack = new Object [length = parser.elementObjectInfoStack.length], 0, length);
this.previousKind = parser.previousKind;
this.previousInfo = parser.previousInfo;
this.previousObjectInfo = parser.previousObjectInfo;
}
public Object becomeSimpleParser() {
return null;
}
public void restoreAssistParser(Object parserState) {
}
public int bodyEnd(AbstractMethodDeclaration method){
return method.bodyEnd;
}
public int bodyEnd(Initializer initializer){
return initializer.declarationSourceEnd;
}
@Override
public RecoveredElement buildInitialRecoveryState(){
if (this.referenceContext instanceof CompilationUnitDeclaration){
RecoveredElement element = super.buildInitialRecoveryState();
flushAssistState();
flushElementStack();
this.snapShotPtr = -1;
initModuleInfo(element);
return element;
}
this.lastCheckPoint = 0;
RecoveredElement element = null;
if (this.referenceContext instanceof AbstractMethodDeclaration){
element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
} else {
if (this.referenceContext instanceof TypeDeclaration){
TypeDeclaration type = (TypeDeclaration) this.referenceContext;
FieldDeclaration[] fields = type.fields;
int length = fields == null ? 0 : fields.length;
for (int i = 0; i < length; i++){
FieldDeclaration field = fields[i];
if (field != null
&& field.getKind() == AbstractVariableDeclaration.INITIALIZER
&& field.declarationSourceStart <= this.scanner.initialPosition
&& this.scanner.initialPosition <= field.declarationSourceEnd
&& this.scanner.eofPosition <= field.declarationSourceEnd+1){
element = new RecoveredInitializer(field, null, 1, this);
this.lastCheckPoint = field.declarationSourceStart;
break;
}
}
}
}
if (element == null) return element;
Block block = new Block(0);
int lastStart = this.blockStarts[0];
block.sourceStart = lastStart;
element = element.add(block, 1);
int blockIndex = 1;
ASTNode node = null, lastNode = null;
for (int i = 0; i <= this.astPtr; i++, lastNode = node) {
node = this.astStack[i];
int nodeStart = node.sourceStart;
for (int j = blockIndex; j <= this.realBlockPtr; j++){
if (this.blockStarts[j] >= 0) {
if (this.blockStarts[j] > nodeStart){
blockIndex = j;
break;
}
if (this.blockStarts[j] != lastStart){
block = new Block(0);
block.sourceStart = lastStart = this.blockStarts[j];
element = element.add(block, 1);
}
} else {
if (-this.blockStarts[j] > nodeStart){
blockIndex = j;
break;
}
block = new Block(0);
block.sourceStart = lastStart = -this.blockStarts[j];
element = element.add(block, 1);
}
blockIndex = j+1;
}
if (node instanceof LocalDeclaration){
LocalDeclaration local = (LocalDeclaration) node;
if (local.declarationSourceEnd == 0){
element = element.add(local, 0);
if (local.initialization == null){
this.lastCheckPoint = local.sourceEnd + 1;
} else {
this.lastCheckPoint = local.initialization.sourceEnd + 1;
}
} else {
if (!local.isArgument()) {
element = element.add(local, 0);
} else {
element.add(local, 0);
}
this.lastCheckPoint = local.declarationSourceEnd + 1;
}
continue;
}
if (node instanceof AbstractMethodDeclaration){
AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
if (method.declarationSourceEnd == 0){
element = element.add(method, 0);
this.lastCheckPoint = method.bodyStart;
} else {
element = element.add(method, 0);
this.lastCheckPoint = method.declarationSourceEnd + 1;
}
continue;
}
if (node instanceof Initializer){
Initializer initializer = (Initializer) node;
if (initializer.declarationSourceEnd == 0){
element = element.add(initializer, 1);
this.lastCheckPoint = initializer.sourceStart;
} else {
element = element.add(initializer, 0);
this.lastCheckPoint = initializer.declarationSourceEnd + 1;
}
continue;
}
if (node instanceof FieldDeclaration){
FieldDeclaration field = (FieldDeclaration) node;
if (field.declarationSourceEnd == 0){
element = element.add(field, 0);
if (field.initialization == null){
this.lastCheckPoint = field.sourceEnd + 1;
} else {
this.lastCheckPoint = field.initialization.sourceEnd + 1;
}
} else {
element = element.add(field, 0);
this.lastCheckPoint = field.declarationSourceEnd + 1;
}
continue;
}
if (node instanceof TypeDeclaration){
TypeDeclaration type = (TypeDeclaration) node;
if (type.declarationSourceEnd == 0){
element = element.add(type, 0);
this.lastCheckPoint = type.bodyStart;
} else {
element = element.add(type, 0);
this.lastCheckPoint = type.declarationSourceEnd + 1;
}
continue;
}
if (this.assistNode != null && node instanceof Statement) {
Statement stmt = (Statement) node;
if (!(stmt instanceof Expression && ((Expression) stmt).isTrulyExpression()) || ((Expression) stmt).statementExpression()) {
if (this.assistNode.sourceStart >= stmt.sourceStart && this.assistNode.sourceEnd <= stmt.sourceEnd) {
element.add(stmt, 0);
this.lastCheckPoint = stmt.sourceEnd + 1;
this.isOrphanCompletionNode = false;
} else if ((stmt instanceof ForeachStatement) && ((ForeachStatement) stmt).action == null) {
element = element.add(stmt, 0);
this.lastCheckPoint = stmt.sourceEnd + 1;
}
}
continue;
}
if (node instanceof ImportReference){
ImportReference importRef = (ImportReference) node;
element = element.add(importRef, 0);
this.lastCheckPoint = importRef.declarationSourceEnd + 1;
}
}
if (this.currentToken == TokenNameRBRACE) {
if (isIndirectlyInsideLambdaExpression())
this.ignoreNextClosingBrace = true;
else
this.currentToken = 0;
}
int pos = this.assistNode == null ? this.lastCheckPoint : this.assistNode.sourceStart;
boolean createLambdaBlock = lastNode instanceof LambdaExpression && ((LambdaExpression) node).body() instanceof Block;
for (int j = blockIndex; j <= this.realBlockPtr; j++){
if (this.blockStarts[j] >= 0) {
if ((this.blockStarts[j] < pos || createLambdaBlock) && (this.blockStarts[j] != lastStart)){
block = new Block(0);
block.sourceStart = lastStart = this.blockStarts[j];
element = element.add(block, 1);
createLambdaBlock = false;
}
} else {
if ((this.blockStarts[j] < pos)){
block = new Block(0);
block.sourceStart = lastStart = -this.blockStarts[j];
element = element.add(block, 1);
}
}
}
return element;
}
private void initModuleInfo(RecoveredElement element) {
if (element instanceof RecoveredUnit) {
RecoveredUnit unit = (RecoveredUnit) element;
if (unit.unitDeclaration.isModuleInfo()) {
ASTNode node = null;
int i = 0;
for (; i <= this.astPtr; i++) {
if ((node = this.astStack[i]) instanceof ModuleDeclaration) {
unit.add((ModuleDeclaration) node, this.bracketDepth);
break;
}
}
}
}
}
@Override
protected void () {
super.consumeAnnotationTypeDeclarationHeader();
pushOnElementStack(K_TYPE_DELIMITER);
}
@Override
protected void consumeClassBodyDeclaration() {
popElement(K_METHOD_DELIMITER);
super.consumeClassBodyDeclaration();
}
@Override
protected void consumeClassBodyopt() {
super.consumeClassBodyopt();
popElement(K_SELECTOR);
}
@Override
protected void () {
super.consumeClassHeader();
pushOnElementStack(K_TYPE_DELIMITER);
}
@Override
protected void consumeConstructorBody() {
super.consumeConstructorBody();
popElement(K_METHOD_DELIMITER);
}
@Override
protected void () {
super.consumeConstructorHeader();
pushOnElementStack(K_METHOD_DELIMITER);
}
@Override
protected void (boolean hasModifiers) {
super.consumeEnhancedForStatementHeaderInit(hasModifiers);
if (this.currentElement != null) {
LocalDeclaration localDecl = ((ForeachStatement)this.astStack[this.astPtr]).elementVariable;
this.lastCheckPoint = localDecl.sourceEnd + 1;
this.currentElement = this.currentElement.add(localDecl, 0);
}
}
@Override
protected void consumeEnterAnonymousClassBody(boolean qualified) {
super.consumeEnterAnonymousClassBody(qualified);
popElement(K_SELECTOR);
pushOnElementStack(K_TYPE_DELIMITER);
}
@Override
protected void consumeEnterMemberValue() {
super.consumeEnterMemberValue();
pushOnElementStack(K_ATTRIBUTE_VALUE_DELIMITER, this.identifierPtr);
}
@Override
protected void () {
if(this.currentToken == TokenNameLBRACE) {
popElement(K_ENUM_CONSTANT_DELIMITER);
pushOnElementStack(K_ENUM_CONSTANT_DELIMITER, WITH_BODY);
pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
pushOnElementStack(K_TYPE_DELIMITER);
}
super.consumeEnumConstantHeader();
if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true) && this.currentElement != null)
this.restartRecovery = true;
}
@Override
protected void () {
super.consumeEnumConstantHeaderName();
pushOnElementStack(K_ENUM_CONSTANT_DELIMITER);
}
@Override
protected void consumeEnumConstantWithClassBody() {
popElement(K_TYPE_DELIMITER);
popElement(K_FIELD_INITIALIZER_DELIMITER);
popElement(K_ENUM_CONSTANT_DELIMITER);
super.consumeEnumConstantWithClassBody();
}
@Override
protected void consumeEnumConstantNoClassBody() {
popElement(K_ENUM_CONSTANT_DELIMITER);
super.consumeEnumConstantNoClassBody();
}
@Override
protected void () {
super.consumeEnumHeader();
pushOnElementStack(K_TYPE_DELIMITER);
}
@Override
protected void consumeExitMemberValue() {
super.consumeExitMemberValue();
popElement(K_ATTRIBUTE_VALUE_DELIMITER);
}
@Override
protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
super.consumeExplicitConstructorInvocation(flag, recFlag);
popElement(K_SELECTOR);
}
protected boolean triggerRecoveryUponLambdaClosure(Statement statement, boolean shouldCommit) {
boolean lambdaClosed = false;
int statementStart, statementEnd;
statementStart = statement.sourceStart;
statementEnd = statement instanceof AbstractVariableDeclaration ? ((AbstractVariableDeclaration)statement).declarationSourceEnd : statement.sourceEnd;
for (int i = this.elementPtr; i >= 0; --i) {
if (this.elementKindStack[i] != K_LAMBDA_EXPRESSION_DELIMITER)
continue;
LambdaExpression expression = (LambdaExpression) this.elementObjectInfoStack[i];
if (expression == null)
return false;
if (expression.sourceStart >= statementStart && expression.sourceEnd <= statementEnd) {
this.elementPtr = i - 1;
lambdaClosed = true;
} else {
if (shouldCommit) {
int stackLength = this.stack.length;
if (++this.stateStackTop >= stackLength) {
System.arraycopy(
this.stack, 0,
this.stack = new int[stackLength + StackIncrement], 0,
stackLength);
}
this.stack[this.stateStackTop] = this.unstackedAct;
commit(false);
this.stateStackTop --;
}
return false;
}
}
if (lambdaClosed && this.currentElement != null && !(this.currentElement instanceof RecoveredField)) {
if (!(statement instanceof AbstractVariableDeclaration)) {
statement = replaceAssistStatement(this.currentElement.topElement(),
this.assistNodeParent(), statementStart, statementEnd, statement);
if (statement != null) {
RecoveredBlock recoveredBlock = (RecoveredBlock) (this.currentElement instanceof RecoveredBlock ? this.currentElement :
(this.currentElement.parent instanceof RecoveredBlock) ? this.currentElement.parent :
this.currentElement instanceof RecoveredMethod ? ((RecoveredMethod) this.currentElement).methodBody : null);
if (recoveredBlock != null) {
RecoveredStatement recoveredStatement = recoveredBlock.statementCount > 0 ? recoveredBlock.statements[recoveredBlock.statementCount - 1] : null;
ASTNode parseTree = recoveredStatement != null ? recoveredStatement.updatedStatement(0, new HashSet<TypeDeclaration>()) : null;
if (parseTree != null) {
if ((parseTree.sourceStart == 0 || parseTree.sourceEnd == 0) || (parseTree.sourceStart >= statementStart && parseTree.sourceEnd <= statementEnd)) {
recoveredBlock.statements[recoveredBlock.statementCount - 1] = new RecoveredStatement(statement, recoveredBlock, 0);
statement = null;
} else if (recoveredStatement instanceof RecoveredLocalVariable && statement instanceof Expression &&
((Expression) statement).isTrulyExpression()) {
RecoveredLocalVariable local = (RecoveredLocalVariable) recoveredStatement;
if (local.localDeclaration != null && local.localDeclaration.initialization != null) {
if ((local.localDeclaration.initialization.sourceStart == 0 || local.localDeclaration.initialization.sourceEnd == 0) ||
(local.localDeclaration.initialization.sourceStart >= statementStart && local.localDeclaration.initialization.sourceEnd <= statementEnd) ){
local.localDeclaration.initialization = (Expression) statement;
local.localDeclaration.declarationSourceEnd = statement.sourceEnd;
local.localDeclaration.declarationEnd = statement.sourceEnd;
statement = null;
}
}
}
}
}
}
if (statement != null) {
while (this.currentElement != null) {
ASTNode tree = this.currentElement.parseTree();
if (tree.sourceStart < statement.sourceStart) {
this.currentElement.add(statement, 0);
break;
}
this.currentElement = this.currentElement.parent;
}
}
}
}
if (this.snapShotPtr > -1)
popSnapShot();
return lambdaClosed;
}
public Statement replaceAssistStatement(RecoveredElement top, ASTNode assistParent, int start, int end, Statement stmt) {
if (top == null) return null;
if (top instanceof RecoveredBlock) {
RecoveredBlock blk = (RecoveredBlock) top;
RecoveredStatement[] statements = blk.statements;
boolean found = false;
if (statements != null) {
for(int i = 0; i < statements.length; i++) {
if (statements[i] == null) break;
ASTNode node = statements[i].parseTree();
if ((node.sourceStart >= start && node.sourceEnd <= end)) {
if (!found) {
statements[i] = new RecoveredStatement(stmt, blk, 0);
found = true;
blk.statementCount = i + 1;
} else {
statements[i] = null;
}
}
}
if (found) return null;
}
} else if (top instanceof RecoveredMethod) {
stmt = replaceAssistStatement(((RecoveredMethod) top).methodBody, assistParent, start, end, stmt);
} else if (top instanceof RecoveredInitializer) {
stmt = replaceAssistStatement(((RecoveredInitializer) top).initializerBody, assistParent, start, end, stmt);
}
return stmt;
}
protected ASTNode assistNodeParent() {
return null;
}
protected ASTNode enclosingNode() {
return null;
}
@Override
protected boolean isAssistParser() {
return true;
}
@Override
protected void consumeBlockStatement() {
super.consumeBlockStatement();
if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true) && this.currentElement != null)
this.restartRecovery = true;
}
@Override
protected void consumeBlockStatements() {
super.consumeBlockStatements();
if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true) && this.currentElement != null) {
this.restartRecovery = true;
}
}
@Override
protected void consumeBlock() {
super.consumeBlock();
if (this.snapShotPtr > -1) {
ASTNode top = this.astStack[this.astPtr];
if (top instanceof Block) {
assert this.snapShotPositions[this.snapShotPtr] == top.sourceStart : "Block positions should be consistent";
popSnapShot();
}
}
}
@Override
protected void consumeFieldDeclaration() {
super.consumeFieldDeclaration();
if (triggerRecoveryUponLambdaClosure((Statement) this.astStack[this.astPtr], true)) {
if (this.currentElement instanceof RecoveredType)
popUntilElement(K_TYPE_DELIMITER);
if (this.currentElement != null)
this.restartRecovery = true;
}
}
@Override
protected void consumeForceNoDiet() {
super.consumeForceNoDiet();
if (!isInsideMethod()) {
if(topKnownElementKind(ASSIST_PARSER) != K_ENUM_CONSTANT_DELIMITER) {
if(topKnownElementKind(ASSIST_PARSER, 2) != K_ENUM_CONSTANT_DELIMITER) {
pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
}
} else {
int info = topKnownElementInfo(ASSIST_PARSER);
if(info != NO_BODY) {
pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
}
}
}
}
@Override
protected void () {
super.consumeInterfaceHeader();
pushOnElementStack(K_TYPE_DELIMITER);
}
@Override
protected void consumeNestedLambda() {
super.consumeNestedLambda();
LambdaExpression lexp = (LambdaExpression) this.astStack[this.astPtr];
pushOnElementStack(K_LAMBDA_EXPRESSION_DELIMITER, EXPRESSION_BODY, lexp);
}
@Override
protected void consumeMethodBody() {
super.consumeMethodBody();
popElement(K_METHOD_DELIMITER);
}
@Override
protected void consumeMethodDeclaration(boolean isNotAbstract, boolean isDefaultMethod) {
if (!isNotAbstract) {
popElement(K_METHOD_DELIMITER);
}
super.consumeMethodDeclaration(isNotAbstract, isDefaultMethod);
if (this.snapShotPtr > -1) {
ASTNode top = this.astStack[this.astPtr];
if (top instanceof AbstractMethodDeclaration) {
assert this.snapShotPositions[this.snapShotPtr] + 1 == ((AbstractMethodDeclaration) top).bodyStart : "Method positions should be consistent";
popSnapShot();
}
}
}
@Override
protected void () {
super.consumeMethodHeader();
pushOnElementStack(K_METHOD_DELIMITER);
}
@Override
protected void consumeMethodInvocationName() {
super.consumeMethodInvocationName();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void consumeMethodInvocationNameWithTypeArguments() {
super.consumeMethodInvocationNameWithTypeArguments();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void consumeMethodInvocationPrimary() {
super.consumeMethodInvocationPrimary();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void consumeMethodInvocationPrimaryWithTypeArguments() {
super.consumeMethodInvocationPrimaryWithTypeArguments();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void consumeMethodInvocationSuper() {
super.consumeMethodInvocationSuper();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void consumeMethodInvocationSuperWithTypeArguments() {
super.consumeMethodInvocationSuperWithTypeArguments();
popElement(K_SELECTOR);
MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
if (messageSend == this.assistNode){
this.lastCheckPoint = messageSend.sourceEnd + 1;
}
}
@Override
protected void () {
pushOnElementStack(K_MODULE_INFO_DELIMITER);
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeModuleHeader();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ModuleDeclaration typeDecl = createAssistModuleDeclaration(this.compilationUnit.compilationResult, subset, positions);
this.compilationUnit.moduleDeclaration = typeDecl;
this.assistNode = typeDecl;
this.lastCheckPoint = typeDecl.sourceEnd + 1;
typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
typeDecl.bodyStart = typeDecl.sourceEnd + 1;
pushOnAstStack(typeDecl);
this.listLength = 0;
if (this.currentElement != null){
this.lastCheckPoint = typeDecl.bodyStart;
this.currentElement = this.currentElement.add(typeDecl, 0);
this.lastIgnoredToken = -1;
}
}
@Override
protected void consumeModuleDeclaration() {
super.consumeModuleDeclaration();
popElement(K_MODULE_INFO_DELIMITER);
}
@Override
protected void consumeNestedMethod() {
super.consumeNestedMethod();
if(!isInsideMethod()) pushOnElementStack(K_METHOD_DELIMITER);
}
@Override
protected void consumeOpenBlock() {
super.consumeOpenBlock();
int stackLength = this.blockStarts.length;
if (this.realBlockPtr >= stackLength) {
System.arraycopy(
this.blockStarts, 0,
this.blockStarts = new int[stackLength + StackIncrement], 0,
stackLength);
}
this.blockStarts[this.realBlockPtr] = this.scanner.startPosition;
if (requireExtendedRecovery()) {
if (this.currentToken == TokenNameLBRACE && this.unstackedAct > NUM_RULES) {
stackLength = this.stack.length;
if (++this.stateStackTop >= stackLength - 1) {
System.arraycopy(
this.stack, 0,
this.stack = new int[stackLength + StackIncrement], 0,
stackLength);
}
this.stack[this.stateStackTop++] = this.unstackedAct;
this.stack[this.stateStackTop] = tAction(this.unstackedAct, this.currentToken);
commit(true);
this.stateStackTop -= 2;
}
}
}
protected void consumeOpenFakeBlock() {
super.consumeOpenBlock();
int stackLength = this.blockStarts.length;
if (this.realBlockPtr >= stackLength) {
System.arraycopy(
this.blockStarts, 0,
this.blockStarts = new int[stackLength + StackIncrement], 0,
stackLength);
}
this.blockStarts[this.realBlockPtr] = -this.scanner.startPosition;
}
@Override
protected void consumePackageDeclarationName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumePackageDeclarationName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistPackageReference(subset, positions);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
this.compilationUnit.currentPackage = reference;
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.restartRecovery = true;
}
}
@Override
protected void consumePackageDeclarationNameWithModifiers() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumePackageDeclarationNameWithModifiers();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
this.intPtr--;
this.intPtr--;
ImportReference reference = createAssistPackageReference(subset, positions);
if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
System.arraycopy(
this.expressionStack,
(this.expressionPtr -= length) + 1,
reference.annotations = new Annotation[length],
0,
length);
}
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
this.compilationUnit.currentPackage = reference;
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.restartRecovery = true;
}
}
@Override
protected void consumeRestoreDiet() {
super.consumeRestoreDiet();
if (!isInsideMethod()) {
popUntilElement(K_FIELD_INITIALIZER_DELIMITER);
popElement(K_FIELD_INITIALIZER_DELIMITER);
}
}
@Override
protected void consumeSingleStaticImportDeclarationName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeSingleStaticImportDeclarationName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccStatic);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.currentElement = this.currentElement.add(reference, 0);
this.lastIgnoredToken = -1;
this.restartRecovery = true;
}
}
@Override
protected void consumeSinglePkgName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeSinglePkgName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistPackageVisibilityReference(subset, positions);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentToken == TokenNameSEMICOLON) {
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
}
@Override
protected void consumeSingleTargetModuleName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeSingleTargetModuleName();
return;
}
ModuleReference reference = createAssistModuleReference(index);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentElement instanceof RecoveredExportsStatement){
this.lastCheckPoint = reference.sourceEnd+1;
this.currentElement = ((RecoveredExportsStatement) this.currentElement).add(reference, 0);
this.lastIgnoredToken = -1;
}
}
@Override
protected void consumeSingleRequiresModuleName() {
int index = indexOfAssistIdentifier();
if (index < 0) {
super.consumeSingleRequiresModuleName();
return;
}
ModuleReference reference = createAssistModuleReference(index);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
RequiresStatement req = new RequiresStatement(reference);
if (this.currentToken == TokenNameSEMICOLON){
req.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
req.declarationSourceEnd = reference.sourceEnd;
}
req.sourceStart = req.declarationSourceStart;
req.declarationEnd = req.declarationSourceEnd;
req.modifiersSourceStart = this.intStack[this.intPtr--];
req.modifiers |= this.intStack[this.intPtr--];
req.declarationSourceStart = this.intStack[this.intPtr--];
if (req.modifiersSourceStart >= 0) {
req.declarationSourceStart = req.modifiersSourceStart;
}
req.sourceEnd = reference.sourceEnd;
pushOnAstStack(req);
if (this.currentElement != null){
this.lastCheckPoint = req.declarationSourceEnd + 1;
this.currentElement = this.currentElement.add(req, 0);
this.lastIgnoredToken = -1;
}
}
@Override
protected void consumeSingleTypeImportDeclarationName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeSingleTypeImportDeclarationName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccDefault);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.currentElement = this.currentElement.add(reference, 0);
this.lastIgnoredToken = -1;
this.restartRecovery = true;
}
}
@Override
protected void consumeStaticImportOnDemandDeclarationName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeStaticImportOnDemandDeclarationName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccStatic);
reference.bits |= ASTNode.OnDemand;
reference.trailingStarPosition = this.intStack[this.intPtr--];
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.currentElement = this.currentElement.add(reference, 0);
this.lastIgnoredToken = -1;
this.restartRecovery = true;
}
}
@Override
protected void consumeStaticInitializer() {
super.consumeStaticInitializer();
popElement(K_METHOD_DELIMITER);
}
@Override
protected void consumeStaticOnly() {
super.consumeStaticOnly();
pushOnElementStack(K_METHOD_DELIMITER);
}
private void adjustBracket(int token) {
switch (token) {
case TokenNameLPAREN :
case TokenNameLBRACE:
case TokenNameLBRACKET:
this.bracketDepth++;
break;
case TokenNameRBRACE:
case TokenNameRBRACKET:
case TokenNameRPAREN:
this.bracketDepth--;
break;
}
}
@Override
protected void consumeToken(int token) {
super.consumeToken(token);
if(this.isFirst) {
this.isFirst = false;
return;
}
if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue() || isInsideEnumConstantnitialization()) {
adjustBracket(token);
switch (token) {
case TokenNameLPAREN :
switch (this.previousToken) {
case TokenNameIdentifier:
this.pushOnElementStack(K_SELECTOR, this.identifierPtr);
break;
case TokenNamethis:
this.pushOnElementStack(K_SELECTOR, THIS_CONSTRUCTOR);
break;
case TokenNamesuper:
this.pushOnElementStack(K_SELECTOR, SUPER_CONSTRUCTOR);
break;
case TokenNameGREATER:
case TokenNameRIGHT_SHIFT:
case TokenNameUNSIGNED_RIGHT_SHIFT:
if(this.identifierPtr > -1) {
this.pushOnElementStack(K_SELECTOR, this.identifierPtr);
}
break;
}
break;
case TokenNameLBRACE:
if (this.previousToken == TokenNameARROW) {
popElement(K_LAMBDA_EXPRESSION_DELIMITER);
if (topKnownElementKind(ASSIST_PARSER, 1) != K_SWITCH_EXPRESSION_DELIMITTER)
pushOnElementStack(K_LAMBDA_EXPRESSION_DELIMITER, BLOCK_BODY, this.previousObjectInfo);
}
break;
}
} else if (isInsideModuleInfo()) {
adjustBracket(token);
} else {
switch (token) {
case TokenNameRBRACE :
if(topKnownElementKind(ASSIST_PARSER) == K_TYPE_DELIMITER) {
popElement(K_TYPE_DELIMITER);
}
break;
}
}
this.previousToken = token;
if (token == TokenNameIdentifier) {
this.previousIdentifierPtr = this.identifierPtr;
}
}
@Override
protected void consumeTypeImportOnDemandDeclarationName() {
int index;
if ((index = indexOfAssistIdentifier()) < 0) {
super.consumeTypeImportOnDemandDeclarationName();
return;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(index+1);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccDefault);
reference.bits |= ASTNode.OnDemand;
reference.trailingStarPosition = this.intStack[this.intPtr--];
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
pushOnAstStack(reference);
if (this.currentToken == TokenNameSEMICOLON){
reference.declarationSourceEnd = this.scanner.currentPosition - 1;
} else {
reference.declarationSourceEnd = (int) positions[length-1];
}
reference.declarationSourceStart = this.intStack[this.intPtr--];
reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
if (this.currentElement != null){
this.lastCheckPoint = reference.declarationSourceEnd+1;
this.currentElement = this.currentElement.add(reference, 0);
this.lastIgnoredToken = -1;
this.restartRecovery = true;
}
}
public abstract ImportReference createAssistPackageVisibilityReference(char[][] tokens, long[] positions);
public abstract ImportReference createAssistImportReference(char[][] tokens, long[] positions, int mod);
public abstract ModuleReference createAssistModuleReference(int index);
public abstract ImportReference createAssistPackageReference(char[][] tokens, long[] positions);
public abstract NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions);
public abstract TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions);
public abstract TypeReference createParameterizedQualifiedAssistTypeReference(char[][] previousIdentifiers, TypeReference[][] typeArguments, char[] asistIdentifier, TypeReference[] assistTypeArguments, long[] positions);
public abstract NameReference createSingleAssistNameReference(char[] assistName, long position);
public abstract TypeReference createSingleAssistTypeReference(char[] assistName, long position);
public abstract TypeReference createParameterizedSingleAssistTypeReference(TypeReference[] typeArguments, char[] assistName, long position);
public abstract ModuleDeclaration createAssistModuleDeclaration(CompilationResult compilationResult, char[][] tokens, long[] positions);
public void flushAssistState(){
this.assistNode = null;
this.isOrphanCompletionNode = false;
setAssistIdentifier(null);
}
protected void flushElementStack() {
for (int j = 0; j <= this.elementPtr; j++) {
this.elementObjectInfoStack[j] = null;
}
this.elementPtr = -1;
this.previousKind = 0;
this.previousInfo = 0;
this.previousObjectInfo = null;
}
@Override
protected TypeReference getTypeReference(int dim) {
int index;
if ((index = indexOfAssistIdentifier(true)) < 0) {
return super.getTypeReference(dim);
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
TypeReference reference;
int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--];
if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
this.identifierLengthPtr--;
reference = getAssistTypeReferenceForGenericType(dim, length, numberOfIdentifiers);
} else {
char[][] subset = identifierSubSet(index);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
if (index == 0) {
this.genericsLengthPtr--;
reference = createSingleAssistTypeReference(
assistIdentifier(),
positions[0]);
} else {
this.genericsLengthPtr--;
reference = createQualifiedAssistTypeReference(
subset,
assistIdentifier(),
positions);
}
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
}
return reference;
}
protected TypeReference getAssistTypeReferenceForGenericType(int dim, int identifierLength, int numberOfIdentifiers) {
if ( (identifierLength == 1 && numberOfIdentifiers == 1)) {
int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
TypeReference[] typeArguments;
if (currentTypeArgumentsLength > -1) {
typeArguments = new TypeReference[currentTypeArgumentsLength];
this.genericsPtr -= currentTypeArgumentsLength;
System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength);
} else {
typeArguments = TypeReference.NO_TYPE_ARGUMENTS;
}
long[] positions = new long[identifierLength];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr,
positions,
0,
identifierLength);
this.identifierPtr--;
TypeReference reference = createParameterizedSingleAssistTypeReference(
typeArguments,
assistIdentifier(),
positions[0]);
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
return reference;
}
TypeReference[][] typeArguments = new TypeReference[numberOfIdentifiers][];
char[][] tokens = new char[numberOfIdentifiers][];
long[] positions = new long[numberOfIdentifiers];
int index = numberOfIdentifiers;
int currentIdentifiersLength = identifierLength;
while (index > 0) {
int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
if (currentTypeArgumentsLength > 0) {
this.genericsPtr -= currentTypeArgumentsLength;
System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
}
switch(currentIdentifiersLength) {
case 1 :
tokens[index - 1] = this.identifierStack[this.identifierPtr];
positions[index - 1] = this.identifierPositionStack[this.identifierPtr--];
break;
default:
this.identifierPtr -= currentIdentifiersLength;
System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, index - currentIdentifiersLength, currentIdentifiersLength);
System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, index - currentIdentifiersLength, currentIdentifiersLength);
}
index -= currentIdentifiersLength;
if (index > 0) {
currentIdentifiersLength = this.identifierLengthStack[this.identifierLengthPtr--];
}
}
int realLength = numberOfIdentifiers;
for (int i = 0; i < numberOfIdentifiers; i++) {
if(tokens[i] == assistIdentifier()) {
realLength = i;
}
}
TypeReference reference;
if(realLength == 0) {
if(typeArguments[0] != null && typeArguments[0].length > 0) {
reference = createParameterizedSingleAssistTypeReference(typeArguments[0], assistIdentifier(), positions[0]);
} else {
reference = createSingleAssistTypeReference(assistIdentifier(), positions[0]);
}
} else {
TypeReference[] assistTypeArguments = typeArguments[realLength];
System.arraycopy(tokens, 0, tokens = new char[realLength][], 0, realLength);
System.arraycopy(typeArguments, 0, typeArguments = new TypeReference[realLength][], 0, realLength);
boolean isParameterized = false;
for (int i = 0; i < typeArguments.length; i++) {
if(typeArguments[i] != null) {
isParameterized = true;
}
}
if(isParameterized || (assistTypeArguments != null && assistTypeArguments.length > 0)) {
reference = createParameterizedQualifiedAssistTypeReference(tokens, typeArguments, assistIdentifier(), assistTypeArguments, positions);
} else {
reference = createQualifiedAssistTypeReference(tokens, assistIdentifier(), positions);
}
}
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
return reference;
}
@Override
protected NameReference getUnspecifiedReferenceOptimized() {
int completionIndex;
if ((completionIndex = indexOfAssistIdentifier()) < 0) {
return super.getUnspecifiedReferenceOptimized();
}
consumeNonTypeUseName();
int length = this.identifierLengthStack[this.identifierLengthPtr];
char[][] subset = identifierSubSet(completionIndex);
this.identifierLengthPtr--;
this.identifierPtr -= length;
long[] positions = new long[length];
System.arraycopy(
this.identifierPositionStack,
this.identifierPtr + 1,
positions,
0,
length);
NameReference reference;
if (completionIndex == 0) {
reference = createSingleAssistNameReference(assistIdentifier(), positions[0]);
} else {
reference = createQualifiedAssistNameReference(subset, assistIdentifier(), positions);
}
reference.bits &= ~ASTNode.RestrictiveFlagMASK;
reference.bits |= Binding.LOCAL | Binding.FIELD;
this.assistNode = reference;
this.lastCheckPoint = reference.sourceEnd + 1;
return reference;
}
@Override
public void goForBlockStatementsopt() {
super.goForBlockStatementsopt();
this.isFirst = true;
}
@Override
public void (){
super.goForHeaders();
this.isFirst = true;
}
@Override
public void goForCompilationUnit(){
super.goForCompilationUnit();
this.isFirst = true;
}
@Override
public void () {
super.goForBlockStatementsOrCatchHeader();
this.isFirst = true;
}
protected char[][] identifierSubSet(int subsetLength){
if (subsetLength == 0) return null;
char[][] subset;
System.arraycopy(
this.identifierStack,
this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + 1,
(subset = new char[subsetLength][]),
0,
subsetLength);
return subset;
}
protected int indexOfAssistIdentifier(){
return this.indexOfAssistIdentifier(false);
}
protected int indexOfAssistIdentifier(boolean useGenericsStack){
if (this.identifierLengthPtr < 0){
return -1;
}
char[] assistIdentifier ;
if ((assistIdentifier = assistIdentifier()) == null){
return -1;
}
int length = this.identifierLengthStack[this.identifierLengthPtr];
if(useGenericsStack && length > 0 && this.genericsIdentifiersLengthPtr > -1 ) {
length = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr];
}
for (int i = 0; i < length; i++){
if (this.identifierStack[this.identifierPtr - i] == assistIdentifier){
return length - i - 1;
}
}
return -1;
}
@Override
public void initialize() {
super.initialize();
flushAssistState();
flushElementStack();
this.previousIdentifierPtr = -1;
this.bracketDepth = 0;
}
@Override
public void initialize(boolean parsingCompilationUnit) {
super.initialize(parsingCompilationUnit);
flushAssistState();
flushElementStack();
this.previousIdentifierPtr = -1;
this.bracketDepth = 0;
}
@Override
public abstract void initializeScanner();
protected boolean isIndirectlyInsideFieldInitialization(){
int i = this.elementPtr;
while(i > -1) {
if(this.elementKindStack[i] == K_FIELD_INITIALIZER_DELIMITER)
return true;
i--;
}
return false;
}
protected boolean isIndirectlyInsideEnumConstantnitialization(){
int i = this.elementPtr;
while(i > -1) {
if(this.elementKindStack[i] == K_ENUM_CONSTANT_DELIMITER)
return true;
i--;
}
return false;
}
protected boolean isIndirectlyInsideMethod(){
int i = this.elementPtr;
while(i > -1) {
if(this.elementKindStack[i] == K_METHOD_DELIMITER)
return true;
i--;
}
return false;
}
@Override
protected boolean isIndirectlyInsideLambdaExpression(){
int i = this.elementPtr;
while (i > -1) {
if (this.elementKindStack[i] == K_LAMBDA_EXPRESSION_DELIMITER)
return true;
i--;
}
return false;
}
protected boolean isIndirectlyInsideLambdaBlock(){
int i = this.elementPtr;
while (i > -1) {
if (this.elementKindStack[i] == K_LAMBDA_EXPRESSION_DELIMITER && this.elementInfoStack[i] == BLOCK_BODY)
return true;
i--;
}
return false;
}
protected boolean isIndirectlyInsideType(){
int i = this.elementPtr;
while(i > -1) {
if(this.elementKindStack[i] == K_TYPE_DELIMITER)
return true;
i--;
}
return false;
}
protected boolean isInsideAttributeValue(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER : return false;
case K_METHOD_DELIMITER : return false;
case K_FIELD_INITIALIZER_DELIMITER : return false;
case K_ATTRIBUTE_VALUE_DELIMITER : return true;
}
i--;
}
return false;
}
protected boolean isInsideFieldInitialization(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER : return false;
case K_METHOD_DELIMITER : return false;
case K_FIELD_INITIALIZER_DELIMITER :
return true;
}
i--;
}
return false;
}
protected boolean isInsideEnumConstantnitialization(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER : return false;
case K_METHOD_DELIMITER : return false;
case K_ENUM_CONSTANT_DELIMITER :
return true;
}
i--;
}
return false;
}
protected boolean isInsideModuleInfo(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER :
case K_METHOD_DELIMITER :
case K_FIELD_INITIALIZER_DELIMITER :
return false;
case K_MODULE_INFO_DELIMITER:
return true;
}
i--;
}
return false;
}
protected boolean isInsideMethod(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER : return false;
case K_METHOD_DELIMITER : return true;
case K_FIELD_INITIALIZER_DELIMITER : return false;
}
i--;
}
return false;
}
protected boolean isInsideType(){
int i = this.elementPtr;
while(i > -1) {
switch (this.elementKindStack[i]) {
case K_TYPE_DELIMITER : return true;
case K_METHOD_DELIMITER : return false;
case K_FIELD_INITIALIZER_DELIMITER : return false;
}
i--;
}
return false;
}
protected int lastIndexOfElement(int kind) {
int i = this.elementPtr;
while(i > -1) {
if(this.elementKindStack[i] == kind) return i;
i--;
}
return -1;
}
public void parseBlockStatements(AbstractMethodDeclaration md, CompilationUnitDeclaration unit) {
if (md instanceof MethodDeclaration) {
parseBlockStatements((MethodDeclaration) md, unit);
} else if (md instanceof ConstructorDeclaration) {
parseBlockStatements((ConstructorDeclaration) md, unit);
}
}
public void parseBlockStatements(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
initialize();
this.lastModifiers = cd.modifiers;
this.lastModifiersStart = cd.modifiersSourceStart;
goForBlockStatementsopt();
this.referenceContext = cd;
this.compilationUnit = unit;
this.scanner.resetTo(cd.bodyStart, bodyEnd(cd));
consumeNestedMethod();
try {
parse();
} catch (AbortCompilation ex) {
this.lastAct = ERROR_ACTION;
}
if (this.lastAct == ERROR_ACTION) {
cd.bits |= ASTNode.HasSyntaxErrors;
return;
}
cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
int length;
if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
this.astPtr -= length;
if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
{
System.arraycopy(
this.astStack,
this.astPtr + 2,
cd.statements = new Statement[length - 1],
0,
length - 1);
cd.constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
} else {
System.arraycopy(
this.astStack,
this.astPtr + 1,
cd.statements = new Statement[length],
0,
length);
cd.constructorCall = SuperReference.implicitSuperConstructorCall();
}
} else {
cd.constructorCall = SuperReference.implicitSuperConstructorCall();
if (!containsComment(cd.bodyStart, cd.bodyEnd)) {
cd.bits |= ASTNode.UndocumentedEmptyBlock;
}
}
if (cd.constructorCall.sourceEnd == 0) {
cd.constructorCall.sourceEnd = cd.sourceEnd;
cd.constructorCall.sourceStart = cd.sourceStart;
}
}
public void parseBlockStatements(
Initializer initializer,
TypeDeclaration type,
CompilationUnitDeclaration unit) {
initialize();
this.lastModifiers = initializer.modifiers;
this.lastModifiersStart = initializer.modifiersSourceStart;
goForBlockStatementsopt();
this.referenceContext = type;
this.compilationUnit = unit;
this.scanner.resetTo(initializer.sourceStart, bodyEnd(initializer));
consumeNestedMethod();
try {
parse();
} catch (AbortCompilation ex) {
this.lastAct = ERROR_ACTION;
} finally {
this.nestedMethod[this.nestedType]--;
}
if (this.lastAct == ERROR_ACTION) {
initializer.bits |= ASTNode.HasSyntaxErrors;
return;
}
initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
int length;
if ((length = this.astLengthStack[this.astLengthPtr--]) > 0) {
System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length);
} else {
if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) {
initializer.block.bits |= ASTNode.UndocumentedEmptyBlock;
}
}
if ((type.bits & ASTNode.HasLocalType) != 0) {
initializer.bits |= ASTNode.HasLocalType;
}
}
public void parseBlockStatements(MethodDeclaration md, CompilationUnitDeclaration unit) {
if (md.isNative())
return;
if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
return;
initialize();
this.lastModifiers = md.modifiers;
this.lastModifiersStart = md.modifiersSourceStart;
goForBlockStatementsopt();
this.referenceContext = md;
this.compilationUnit = unit;
this.scanner.resetTo(md.bodyStart, bodyEnd(md));
consumeNestedMethod();
try {
parse();
} catch (AbortCompilation ex) {
this.lastAct = ERROR_ACTION;
} finally {
this.nestedMethod[this.nestedType]--;
}
if (this.lastAct == ERROR_ACTION) {
md.bits |= ASTNode.HasSyntaxErrors;
return;
}
md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
int length;
if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
System.arraycopy(
this.astStack,
(this.astPtr -= length) + 1,
md.statements = new Statement[length],
0,
length);
} else {
if (!containsComment(md.bodyStart, md.bodyEnd)) {
md.bits |= ASTNode.UndocumentedEmptyBlock;
}
}
}
protected void popElement(int kind) {
if (this.elementPtr < 0)
return;
int stackPointer = this.elementPtr;
if (kind != K_LAMBDA_EXPRESSION_DELIMITER) {
while (this.elementKindStack[stackPointer] == K_LAMBDA_EXPRESSION_DELIMITER) {
if (--stackPointer < 0) break;
}
}
if (stackPointer < 0 || this.elementKindStack[stackPointer] != kind)
return;
this.previousKind = this.elementKindStack[stackPointer];
this.previousInfo = this.elementInfoStack[stackPointer];
this.previousObjectInfo = this.elementObjectInfoStack[stackPointer];
final int length = this.elementPtr - stackPointer;
if (length > 0) {
System.arraycopy(this.elementKindStack, stackPointer + 1, this.elementKindStack, stackPointer, length);
System.arraycopy(this.elementInfoStack, stackPointer + 1, this.elementInfoStack, stackPointer, length);
System.arraycopy(this.elementObjectInfoStack, stackPointer + 1, this.elementObjectInfoStack, stackPointer, length);
}
this.elementObjectInfoStack[this.elementPtr] = null;
this.elementPtr--;
}
protected void popUntilElement(int kind){
if(this.elementPtr < 0) return;
int i = this.elementPtr;
while (i >= 0 && this.elementKindStack[i] != kind) {
i--;
}
if(i >= 0) {
if(i < this.elementPtr) {
this.previousKind = this.elementKindStack[i+1];
this.previousInfo = this.elementInfoStack[i+1];
this.previousObjectInfo = this.elementObjectInfoStack[i+1];
for (int j = i + 1; j <= this.elementPtr; j++) {
this.elementObjectInfoStack[j] = null;
}
}
this.elementPtr = i;
}
}
@Override
protected void prepareForBlockStatements() {
this.nestedMethod[this.nestedType = 0] = 1;
this.variablesCounter[this.nestedType] = 0;
this.realBlockStack[this.realBlockPtr = 1] = 0;
int fieldInitializerIndex = lastIndexOfElement(K_FIELD_INITIALIZER_DELIMITER);
int methodIndex = lastIndexOfElement(K_METHOD_DELIMITER);
if(methodIndex == fieldInitializerIndex) {
flushElementStack();
} else if(methodIndex > fieldInitializerIndex) {
popUntilElement(K_METHOD_DELIMITER);
} else {
popUntilElement(K_FIELD_INITIALIZER_DELIMITER);
}
}
protected void () {
this.nestedMethod[this.nestedType = 0] = 0;
this.variablesCounter[this.nestedType] = 0;
this.realBlockStack[this.realBlockPtr = 0] = 0;
popUntilElement(K_TYPE_DELIMITER);
if(this.topKnownElementKind(ASSIST_PARSER) != K_TYPE_DELIMITER) {
flushElementStack();
}
}
public boolean requireExtendedRecovery() {
return lastIndexOfElement(K_LAMBDA_EXPRESSION_DELIMITER) >= 0;
}
protected void pushOnElementStack(int kind){
this.pushOnElementStack(kind, 0, null);
}
protected void pushOnElementStack(int kind, int info){
this.pushOnElementStack(kind, info, null);
}
protected void pushOnElementStack(int kind, int info, Object objectInfo){
if (this.elementPtr < -1) return;
this.previousKind = 0;
this.previousInfo = 0;
this.previousObjectInfo = null;
int stackLength = this.elementKindStack.length;
if (++this.elementPtr >= stackLength) {
System.arraycopy(
this.elementKindStack, 0,
this.elementKindStack = new int[stackLength + StackIncrement], 0,
stackLength);
System.arraycopy(
this.elementInfoStack, 0,
this.elementInfoStack = new int[stackLength + StackIncrement], 0,
stackLength);
System.arraycopy(
this.elementObjectInfoStack, 0,
this.elementObjectInfoStack = new Object[stackLength + StackIncrement], 0,
stackLength);
}
this.elementKindStack[this.elementPtr] = kind;
this.elementInfoStack[this.elementPtr] = info;
this.elementObjectInfoStack[this.elementPtr] = objectInfo;
}
@Override
public void recoveryExitFromVariable() {
if(this.currentElement != null && this.currentElement instanceof RecoveredField
&& !(this.currentElement instanceof RecoveredInitializer)) {
RecoveredElement oldElement = this.currentElement;
super.recoveryExitFromVariable();
if(oldElement != this.currentElement) {
popElement(K_FIELD_INITIALIZER_DELIMITER);
}
} else {
super.recoveryExitFromVariable();
}
}
@Override
public void recoveryTokenCheck() {
RecoveredElement oldElement = this.currentElement;
switch (this.currentToken) {
case TokenNameLBRACE :
super.recoveryTokenCheck();
if(this.currentElement instanceof RecoveredInitializer) {
if(oldElement instanceof RecoveredField) {
popUntilElement(K_FIELD_INITIALIZER_DELIMITER);
popElement(K_FIELD_INITIALIZER_DELIMITER);
}
if(this.currentElement != oldElement
&& topKnownElementKind(ASSIST_PARSER) != K_METHOD_DELIMITER) {
pushOnElementStack(K_METHOD_DELIMITER);
}
}
break;
case TokenNameRBRACE :
super.recoveryTokenCheck();
if(this.currentElement != oldElement && !isInsideAttributeValue() && !isIndirectlyInsideLambdaExpression()) {
if(oldElement instanceof RecoveredInitializer
|| oldElement instanceof RecoveredMethod
|| (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredInitializer)
|| (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredMethod)) {
popUntilElement(K_METHOD_DELIMITER);
popElement(K_METHOD_DELIMITER);
} else if(oldElement instanceof RecoveredType) {
popUntilElement(K_TYPE_DELIMITER);
if(!(this.referenceContext instanceof CompilationUnitDeclaration)
|| isIndirectlyInsideFieldInitialization()
|| this.currentElement instanceof RecoveredUnit) {
popElement(K_TYPE_DELIMITER);
}
}
}
break;
default :
super.recoveryTokenCheck();
break;
}
}
public void reset(){
flushAssistState();
}
void commit(boolean isStart) {
int newSnapShotPosition = this.scanner.startPosition;
if (this.snapShotPtr == -1) {
addNewSnapShot(newSnapShotPosition);
} else {
int currentStartPosition = isStart ? newSnapShotPosition : this.blockStarts[this.realBlockPtr];
if (currentStartPosition != this.snapShotPositions[this.snapShotPtr])
addNewSnapShot(newSnapShotPosition);
}
this.snapShotStack[this.snapShotPtr].copyState(this);
}
void addNewSnapShot(int newSnapShotPosition) {
if (++this.snapShotPtr >= this.snapShotStack.length) {
int len = this.snapShotStack.length;
System.arraycopy(this.snapShotStack, 0, this.snapShotStack = new AssistParser[len+3], 0, len);
System.arraycopy(this.snapShotPositions, 0, this.snapShotPositions = new int[len+3], 0, len);
}
this.snapShotStack[this.snapShotPtr] = createSnapShotParser();
this.snapShotPositions[this.snapShotPtr] = newSnapShotPosition;
}
void popSnapShot() {
this.snapShotStack[this.snapShotPtr--] = null;
}
protected boolean assistNodeNeedsStacking() {
return false;
}
protected void shouldStackAssistNode() {
}
protected int getNextToken() {
try {
return this.scanner.getNextToken();
} catch (InvalidInputException e) {
return TokenNameEOF;
}
}
protected abstract AssistParser createSnapShotParser();
protected int fallBackToSpringForward(Statement unused) {
int nextToken;
int automatonState = automatonState();
if (this.currentToken == TokenNameEOF) {
int extendedEnd = this.scanner.source.length;
if (this.referenceContext instanceof AbstractMethodDeclaration)
extendedEnd = ((AbstractMethodDeclaration) this.referenceContext).bodyEnd;
if (this.scanner.eofPosition < extendedEnd) {
shouldStackAssistNode();
this.scanner.eofPosition = extendedEnd;
nextToken = getNextToken();
if (automatonWillShift(nextToken, automatonState)) {
this.currentToken = nextToken;
return RESUME;
}
this.scanner.ungetToken(nextToken);
} else {
return HALT;
}
} else {
nextToken = this.currentToken;
this.scanner.ungetToken(nextToken);
if (nextToken == TokenNameRBRACE)
ignoreNextClosingBrace();
}
for (int i = 0, length = RECOVERY_TOKENS.length; i < length; i++) {
if (automatonWillShift(RECOVERY_TOKENS[i], automatonState)) {
this.currentToken = RECOVERY_TOKENS[i];
return RESUME;
}
}
if (this.snapShotPtr == -1)
return RESTART;
this.copyState(this.snapShotStack[this.snapShotPtr]);
if (assistNodeNeedsStacking()) {
this.currentToken = TokenNameSEMICOLON;
return RESUME;
}
this.currentToken = this.scanner.fastForward(unused);
return RESUME;
}
@Override
protected int resumeAfterRecovery() {
if (requireExtendedRecovery()) {
if (this.unstackedAct == ERROR_ACTION) {
int mode = fallBackToSpringForward((Statement) null);
this.resumedAfterRepair = mode == RESUME;
if (mode == RESUME || mode == HALT)
return mode;
} else {
if (this.currentToken == TokenNameLBRACE)
this.ignoreNextOpeningBrace = true;
return RESUME;
}
}
this.astPtr = -1;
this.astLengthPtr = -1;
this.expressionPtr = -1;
this.expressionLengthPtr = -1;
this.typeAnnotationLengthPtr = -1;
this.typeAnnotationPtr = -1;
this.identifierPtr = -1;
this.identifierLengthPtr = -1;
this.intPtr = -1;
this.dimensions = 0 ;
this.recoveredStaticInitializerStart = 0;
this.genericsIdentifiersLengthPtr = -1;
this.genericsLengthPtr = -1;
this.genericsPtr = -1;
this.valueLambdaNestDepth = -1;
this.modifiers = ClassFileConstants.AccDefault;
this.modifiersSourceStart = -1;
if (this.diet) this.dietInt = 0;
if (this.unstackedAct != ERROR_ACTION && this.resumedAfterRepair) {
this.scanner.ungetToken(this.currentToken);
} else {
if (!moveRecoveryCheckpoint()) return HALT;
}
this.resumedAfterRepair = false;
if (this.referenceContext instanceof CompilationUnitDeclaration
|| this.assistNode != null){
if(isInsideMethod() &&
isIndirectlyInsideFieldInitialization() &&
this.assistNode == null
){
prepareForBlockStatements();
goForBlockStatementsOrCatchHeader();
} else if((isInsideArrayInitializer()) &&
isIndirectlyInsideFieldInitialization() &&
this.assistNode == null){
prepareForBlockStatements();
goForBlockStatementsopt();
} else {
prepareForHeaders();
if (this.referenceContext instanceof CompilationUnitDeclaration) {
CompilationUnitDeclaration unit = (CompilationUnitDeclaration) this.referenceContext;
if (unit.isModuleInfo()) {
pushOnElementStack(K_MODULE_INFO_DELIMITER);
}
}
goForHeaders();
this.diet = true;
this.dietInt = 0;
}
return RESTART;
}
if (this.referenceContext instanceof AbstractMethodDeclaration
|| this.referenceContext instanceof TypeDeclaration){
if (this.currentElement instanceof RecoveredType){
prepareForHeaders();
goForHeaders();
} else {
prepareForBlockStatements();
goForBlockStatementsOrCatchHeader();
}
return RESTART;
}
return HALT;
}
protected boolean isInsideArrayInitializer() {
return false;
}
public abstract void setAssistIdentifier(char[] assistIdent);
protected int topKnownElementInfo(int owner) {
return topKnownElementInfo(owner, 0);
}
protected int topKnownElementInfo(int owner, int offSet) {
int i = this.elementPtr;
while(i > -1) {
if((this.elementKindStack[i] & owner) != 0) {
if(offSet <= 0) return this.elementInfoStack[i];
offSet--;
}
i--;
}
return 0;
}
protected int topKnownElementKind(int owner) {
return topKnownElementKind(owner, 0);
}
protected int topKnownElementKind(int owner, int offSet) {
int i = this.elementPtr;
while(i > -1) {
if((this.elementKindStack[i] & owner) != 0) {
if(offSet <= 0) return this.elementKindStack[i];
offSet--;
}
i--;
}
return 0;
}
protected Object topKnownElementObjectInfo(int owner, int offSet) {
int i = this.elementPtr;
while(i > -1) {
if((this.elementKindStack[i] & owner) != 0) {
if(offSet <= 0) return this.elementObjectInfoStack[i];
offSet--;
}
i--;
}
return null;
}
protected Object topKnownElementObjectInfo(int owner) {
return topKnownElementObjectInfo(owner, 0);
}
protected ASTNode wrapWithExplicitConstructorCallIfNeeded(ASTNode ast) {
int selector;
if (ast != null && topKnownElementKind(ASSIST_PARSER) == K_SELECTOR && ast instanceof Expression &&
((Expression) ast).isTrulyExpression() &&
(((selector = topKnownElementInfo(ASSIST_PARSER)) == THIS_CONSTRUCTOR) ||
(selector == SUPER_CONSTRUCTOR))) {
ExplicitConstructorCall call = new ExplicitConstructorCall(
(selector == THIS_CONSTRUCTOR) ?
ExplicitConstructorCall.This :
ExplicitConstructorCall.Super
);
call.arguments = new Expression[] {(Expression)ast};
call.sourceStart = ast.sourceStart;
call.sourceEnd = ast.sourceEnd;
return call;
} else {
return ast;
}
}
}