Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java')
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java384
1 files changed, 334 insertions, 50 deletions
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index b3d2efa9..2038322a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -1,10 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -66,8 +66,11 @@ public class CompletionParser extends AssistParser {
protected static final int K_PARAMETERIZED_METHOD_INVOCATION = COMPLETION_PARSER + 30;
protected static final int K_PARAMETERIZED_ALLOCATION = COMPLETION_PARSER + 31;
protected static final int K_PARAMETERIZED_CAST = COMPLETION_PARSER + 32;
-
+ protected static final int K_BETWEEN_ANNOTATION_NAME_AND_RPAREN = COMPLETION_PARSER + 33;
+ public final static char[] FAKE_TYPE_NAME = new char[]{' '};
+ public final static char[] VALUE = new char[]{'v', 'a', 'l', 'u', 'e'};
+
/* public fields */
public int cursorLocation;
@@ -97,6 +100,11 @@ public class CompletionParser extends AssistParser {
static final int QUESTION = 1;
static final int COLON = 2;
+
+ // K_BETWEEN_ANNOTATION_NAME_AND_RPAREN arguments
+ static final int LPAREN_NOT_CONSUMED = 1;
+ static final int LPAREN_CONSUMED = 2;
+
// the type of the current invocation (one of the invocation type constants)
int invocationType;
@@ -117,7 +125,7 @@ public class CompletionParser extends AssistParser {
static final int NEXTTOKEN = 1;
static final int YES = 2;
-
+ boolean isAlreadyAttached;
public CompletionParser(ProblemReporter problemReporter) {
super(problemReporter);
this.reportSyntaxErrorIsRequired = false;
@@ -126,7 +134,9 @@ public char[] assistIdentifier(){
return ((CompletionScanner)scanner).completionIdentifier;
}
protected void attachOrphanCompletionNode(){
- if(assistNode == null) return;
+ if(assistNode == null || this.isAlreadyAttached) return;
+
+ this.isAlreadyAttached = true;
if (this.isOrphanCompletionNode) {
ASTNode orphan = this.assistNode;
@@ -188,9 +198,15 @@ protected void attachOrphanCompletionNode(){
}
}
+ if(orphan instanceof MemberValuePair) {
+ buildMoreAnnotationCompletionContext((MemberValuePair) orphan);
+ return;
+ }
+
if(orphan instanceof Annotation) {
TypeDeclaration fakeType =
new CompletionOnAnnotationOfType(
+ FAKE_TYPE_NAME,
this.compilationUnit.compilationResult(),
(Annotation)orphan);
currentElement.add(fakeType, 0);
@@ -214,6 +230,75 @@ protected void attachOrphanCompletionNode(){
return;
}
}
+
+ if (this.isInsideAnnotation()) {
+ // push top expression on ast stack if it contains the completion node
+ Expression expression;
+ if (this.expressionPtr > -1) {
+ expression = this.expressionStack[this.expressionPtr];
+ if(expression == assistNode) {
+ if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+ if (expression instanceof SingleNameReference) {
+ SingleNameReference nameReference = (SingleNameReference) expression;
+ CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(nameReference.token, nameReference.sourceStart, nameReference.sourceEnd);
+
+ buildMoreAnnotationCompletionContext(memberValueName);
+ return;
+ } else if (expression instanceof QualifiedNameReference) {
+ MemberValuePair valuePair =
+ new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+ buildMoreAnnotationCompletionContext(valuePair);
+ }
+ } else {
+ int index;
+ if((index = lastIndexOfElement(K_ATTRIBUTE_VALUE_DELIMITER)) != -1) {
+ int attributeIndentifierPtr = this.elementInfoStack[index];
+ int identLengthPtr = this.identifierLengthPtr;
+ int identPtr = this.identifierPtr;
+ while (attributeIndentifierPtr < identPtr) {
+ identPtr -= this.identifierLengthStack[identLengthPtr--];
+ }
+
+ if(attributeIndentifierPtr != identPtr) return;
+
+ this.identifierLengthPtr = identLengthPtr;
+ this.identifierPtr = identPtr;
+
+ this.identifierLengthPtr--;
+ MemberValuePair memberValuePair = new MemberValuePair(
+ this.identifierStack[this.identifierPtr--],
+ expression.sourceStart,
+ expression.sourceEnd,
+ expression);
+
+ buildMoreAnnotationCompletionContext(memberValuePair);
+ return;
+ }
+ }
+ } else {
+ CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, expression);
+ if(detector.containsCompletionNode()) {
+ MemberValuePair valuePair =
+ new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+ buildMoreAnnotationCompletionContext(valuePair);
+ }
+ }
+ }
+
+ if (this.astPtr > -1) {
+ ASTNode node = this.astStack[this.astPtr];
+ if(node instanceof MemberValuePair) {
+ MemberValuePair memberValuePair = (MemberValuePair) node;
+ CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, memberValuePair);
+ if(detector.containsCompletionNode()) {
+ buildMoreAnnotationCompletionContext(memberValuePair);
+ this.assistNodeParent = detector.getCompletionNodeParent();
+ return;
+ }
+ }
+ }
+ }
+
if(this.currentElement instanceof RecoveredType || this.currentElement instanceof RecoveredMethod) {
if(this.currentElement instanceof RecoveredType) {
RecoveredType recoveredType = (RecoveredType)this.currentElement;
@@ -271,7 +356,7 @@ protected void attachOrphanCompletionNode(){
}
// the following code applies only in methods, constructors or initializers
- if ((!isInsideMethod() && !isInsideFieldInitialization())) {
+ if ((!isInsideMethod() && !isInsideFieldInitialization() && !isInsideAttributeValue())) {
return;
}
@@ -329,6 +414,76 @@ protected void attachOrphanCompletionNode(){
}
}
}
+private void buildMoreAnnotationCompletionContext(MemberValuePair memberValuePair) {
+ if(this.identifierPtr < 0 || this.identifierLengthPtr < 0 ) return;
+
+ TypeReference typeReference = this.getAnnotationType();
+
+ int nodesToRemove = this.astPtr > -1 && this.astStack[this.astPtr] == memberValuePair ? 1 : 0;
+
+ NormalAnnotation annotation;
+ if (memberValuePair instanceof CompletionOnMemberValueName) {
+ MemberValuePair[] memberValuePairs = null;
+ int length;
+ if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+ if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+ System.arraycopy(
+ this.astStack,
+ (this.astPtr -= length) + 1,
+ memberValuePairs = new MemberValuePair[length - nodesToRemove],
+ 0,
+ length - nodesToRemove);
+ }
+ }
+ annotation =
+ new CompletionOnAnnotationMemberValuePair(
+ typeReference,
+ this.intStack[this.intPtr--],
+ memberValuePairs,
+ memberValuePair);
+
+ this.assistNode = memberValuePair;
+ this.assistNodeParent = annotation;
+
+ if (memberValuePair.sourceEnd >= this.lastCheckPoint) {
+ this.lastCheckPoint = memberValuePair.sourceEnd + 1;
+ }
+ } else {
+ MemberValuePair[] memberValuePairs = null;
+ int length = 0;
+ if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+ if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+ System.arraycopy(
+ this.astStack,
+ (this.astPtr -= length) + 1,
+ memberValuePairs = new MemberValuePair[length - nodesToRemove + 1],
+ 0,
+ length - nodesToRemove);
+ }
+ if(memberValuePairs != null) {
+ memberValuePairs[length - nodesToRemove] = memberValuePair;
+ } else {
+ memberValuePairs = new MemberValuePair[]{memberValuePair};
+ }
+ } else {
+ memberValuePairs = new MemberValuePair[]{memberValuePair};
+ }
+
+ annotation =
+ new NormalAnnotation(
+ typeReference,
+ this.intStack[this.intPtr--]);
+ annotation.memberValuePairs = memberValuePairs;
+
+ }
+ TypeDeclaration fakeType =
+ new CompletionOnAnnotationOfType(
+ FAKE_TYPE_NAME,
+ this.compilationUnit.compilationResult(),
+ annotation);
+
+ currentElement.add(fakeType, 0);
+}
private void buildMoreCompletionContext(Expression expression) {
Statement statement = expression;
int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
@@ -462,25 +617,44 @@ private void buildMoreCompletionContext(Expression expression) {
}
break nextElement;
case K_BINARY_OPERATOR :
- if(expressionPtr > 0) {
+ if(expressionPtr > -1) {
Expression operatorExpression = null;
- switch (info) {
- case AND_AND :
- operatorExpression = new AND_AND_Expression(this.expressionStack[expressionPtr-1], expression, info);
- break;
- case OR_OR :
- operatorExpression = new OR_OR_Expression(this.expressionStack[expressionPtr-1], expression, info);
- break;
- case EQUAL_EQUAL :
- case NOT_EQUAL :
- operatorExpression = new EqualExpression(this.expressionStack[expressionPtr-1], expression, info);
- break;
- case INSTANCEOF :
- // should never occur
- break;
- default :
- operatorExpression = new BinaryExpression(this.expressionStack[expressionPtr-1], expression, info);
- break;
+ Expression left = null;
+ if(expressionPtr == 0) {
+ // it is a ***_NotName rule
+ if(this.identifierPtr > -1) {
+ left = getUnspecifiedReferenceOptimized();
+ }
+ } else {
+ left = this.expressionStack[expressionPtr-1];
+ // is it a ***_NotName rule ?
+ if(this.identifierPtr > -1) {
+ int start = (int) (identifierPositionStack[this.identifierPtr] >>> 32);
+ if(left.sourceStart < start) {
+ left = getUnspecifiedReferenceOptimized();
+ }
+ }
+ }
+
+ if(left != null) {
+ switch (info) {
+ case AND_AND :
+ operatorExpression = new AND_AND_Expression(left, expression, info);
+ break;
+ case OR_OR :
+ operatorExpression = new OR_OR_Expression(left, expression, info);
+ break;
+ case EQUAL_EQUAL :
+ case NOT_EQUAL :
+ operatorExpression = new EqualExpression(left, expression, info);
+ break;
+ case INSTANCEOF :
+ // should never occur
+ break;
+ default :
+ operatorExpression = new BinaryExpression(left, expression, info);
+ break;
+ }
}
if(operatorExpression != null) {
assistNodeParent = operatorExpression;
@@ -596,7 +770,33 @@ private void buildMoreCompletionContext(Expression expression) {
}
assistNodeParent = arrayReference;
break;
-
+ case K_BETWEEN_CASE_AND_COLON :
+ if(this.expressionPtr > 0) {
+ SwitchStatement switchStatement = new SwitchStatement();
+ switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
+ if(this.astLengthPtr > -1 && this.astPtr > -1) {
+ int length = this.astLengthStack[this.astLengthPtr];
+ int newAstPtr = this.astPtr - length;
+ ASTNode firstNode = this.astStack[newAstPtr + 1];
+ if(length != 0 && firstNode.sourceStart > switchStatement.expression.sourceEnd) {
+ switchStatement.statements = new Statement[length + 1];
+ System.arraycopy(
+ this.astStack,
+ newAstPtr + 1,
+ switchStatement.statements,
+ 0,
+ length);
+ }
+ }
+ CaseStatement caseStatement = new CaseStatement(expression, expression.sourceStart, expression.sourceEnd);
+ if(switchStatement.statements == null) {
+ switchStatement.statements = new Statement[]{caseStatement};
+ } else {
+ switchStatement.statements[switchStatement.statements.length - 1] = caseStatement;
+ }
+ assistNodeParent = switchStatement;
+ }
+ break;
}
}
if(assistNodeParent != null) {
@@ -1105,6 +1305,29 @@ private boolean checkRecoveredMethod() {
}
return false;
}
+private boolean checkMemberValueName() {
+ /* check if current awaiting identifier is the completion identifier */
+ if (this.indexOfAssistIdentifier() < 0) return false;
+
+ if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) return false;
+
+ if(this.identifierPtr > -1 && this.identifierLengthPtr > -1 && this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+ char[] simpleName = this.identifierStack[this.identifierPtr];
+ long position = this.identifierPositionStack[this.identifierPtr--];
+ this.identifierLengthPtr--;
+ int end = (int) position;
+ int start = (int) (position >>> 32);
+
+
+ CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+ this.assistNode = memberValueName;
+ this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+ this.isOrphanCompletionNode = true;
+
+ return true;
+ }
+ return false;
+}
/**
* Checks if the completion is in the context of a type and on a type reference in this type.
* Persists the identifier into a fake field return type
@@ -1157,14 +1380,16 @@ private boolean checkRecoveredType() {
*/
public void completionIdentifierCheck(){
//if (assistNode != null) return;
-
+
+ if (checkMemberValueName()) return;
if (checkKeyword()) return;
if (checkRecoveredType()) return;
if (checkRecoveredMethod()) return;
// if not in a method in non diet mode and if not inside a field initializer, only record references attached to types
if (!(isInsideMethod() && !this.diet)
- && !isIndirectlyInsideFieldInitialization()) return;
+ && !isIndirectlyInsideFieldInitialization()
+ && !isInsideAttributeValue()) return;
/*
In some cases, the completion identifier may not have yet been consumed,
@@ -1437,11 +1662,6 @@ protected void consumeEnterAnonymousClassBody() {
popElement(K_SELECTOR_INVOCATION_TYPE);
super.consumeEnterAnonymousClassBody();
}
-protected void consumeEnterAnonymousClassBodySimpleName() {
- popElement(K_SELECTOR_QUALIFIER);
- popElement(K_SELECTOR_INVOCATION_TYPE);
- super.consumeEnterAnonymousClassBodySimpleName();
-}
protected void consumeEnterVariable() {
identifierPtr--;
identifierLengthPtr--;
@@ -1589,7 +1809,7 @@ protected void consumeFormalParameter(boolean isVarArgs) {
final int typeDimensions = firstDimensions + extendedDimensions;
TypeReference type = getTypeReference(typeDimensions);
if (isVarArgs) {
- type = type.copyDims(typeDimensions + 1);
+ type = copyDims(type, typeDimensions + 1);
if (extendedDimensions == 0) {
type.sourceEnd = endOfEllipsis;
}
@@ -1923,6 +2143,7 @@ protected void consumeAnnotationName() {
if ((index = this.indexOfAssistIdentifier()) < 0) {
super.consumeAnnotationName();
+ this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_NOT_CONSUMED);
return;
}
@@ -1960,12 +2181,7 @@ protected void consumeAnnotationName() {
}
markerAnnotation = new CompletionOnMarkerAnnotationName(typeReference, typeReference.sourceStart);
- int sourceStart = this.intStack[this.intPtr--];
- if (this.modifiersSourceStart < 0) {
- this.modifiersSourceStart = sourceStart;
- } else if (this.modifiersSourceStart > sourceStart) {
- this.modifiersSourceStart = sourceStart;
- }
+ this.intPtr--;
markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
pushOnExpressionStack(markerAnnotation);
@@ -1975,6 +2191,48 @@ protected void consumeAnnotationName() {
this.lastCheckPoint = markerAnnotation.sourceEnd + 1;
}
+protected void consumeMarkerAnnotation() {
+ this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+ super.consumeMarkerAnnotation();
+}
+protected void consumeMemberValuePair() {
+ /* check if current awaiting identifier is the completion identifier */
+ if (this.indexOfAssistIdentifier() < 0){
+ super.consumeMemberValuePair();
+ MemberValuePair memberValuePair = (MemberValuePair) this.astStack[this.astPtr];
+ if(this.assistNode != null && memberValuePair.value == this.assistNode) {
+ this.assistNodeParent = memberValuePair;
+ }
+ return;
+ }
+
+ char[] simpleName = this.identifierStack[this.identifierPtr];
+ long position = this.identifierPositionStack[this.identifierPtr--];
+ this.identifierLengthPtr--;
+ int end = (int) position;
+ int start = (int) (position >>> 32);
+
+ this.expressionPtr--;
+ this.expressionLengthPtr--;
+
+ CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+ this.pushOnAstStack(memberValueName);
+ this.assistNode = memberValueName;
+ this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+ this.isOrphanCompletionNode = true;
+
+ this.restartRecovery = true;
+}
+protected void consumeMemberValueAsName() {
+ if ((indexOfAssistIdentifier()) < 0) {
+ super.consumeMemberValueAsName();
+ } else {
+ super.consumeMemberValueAsName();
+ if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+ this.restartRecovery = true;
+ }
+ }
+}
protected void consumeMethodBody() {
popElement(K_BLOCK_DELIMITER);
super.consumeMethodBody();
@@ -2003,6 +2261,10 @@ protected void consumeRestoreDiet() {
popElement(K_LOCAL_INITIALIZER_DELIMITER);
}
}
+protected void consumeSingleMemberAnnotation() {
+ this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+ super.consumeSingleMemberAnnotation();
+}
protected void consumeStatementSwitch() {
super.consumeStatementSwitch();
if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SWITCH_LABEL) {
@@ -2014,6 +2276,10 @@ protected void consumeNestedMethod() {
super.consumeNestedMethod();
if(!(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BLOCK_DELIMITER)) pushOnElementStack(K_BLOCK_DELIMITER);
}
+protected void consumeNormalAnnotation() {
+ this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+ super.consumeNormalAnnotation();
+}
protected void consumePrimaryNoNewArrayName() {
// this is class literal access, so reset potential receiver
this.invocationType = NO_RECEIVER;
@@ -2043,7 +2309,7 @@ protected void consumeToken(int token) {
int previous = this.previousToken;
int prevIdentifierPtr = this.previousIdentifierPtr;
- if (isInsideMethod() || isInsideFieldInitialization()) {
+ if (isInsideMethod() || isInsideFieldInitialization() || isInsideAnnotation()) {
switch(token) {
case TokenNameLPAREN:
popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
@@ -2073,7 +2339,7 @@ protected void consumeToken(int token) {
}
}
super.consumeToken(token);
-
+
// if in field initializer (directly or not), on the completion identifier and not in recovery mode yet
// then position end of file at cursor location (so that we have the same behavior as
// in method bodies)
@@ -2085,7 +2351,7 @@ protected void consumeToken(int token) {
}
// if in a method or if in a field initializer
- if (isInsideMethod() || isInsideFieldInitialization()) {
+ if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue()) {
switch (token) {
case TokenNameDOT:
switch (previous) {
@@ -2149,8 +2415,15 @@ protected void consumeToken(int token) {
switch (previous) {
case TokenNameIdentifier: // eg. fred[(]) or foo.fred[(])
if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
- this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, this.invocationType);
- this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+ if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER,1) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+ topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER,1) == LPAREN_NOT_CONSUMED) {
+ this.popElement(K_SELECTOR);
+ this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+ this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_CONSUMED);
+ } else {
+ this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, this.invocationType);
+ this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+ }
}
this.qualifier = -1;
this.invocationType = NO_RECEIVER;
@@ -2568,7 +2841,8 @@ public NameReference createQualifiedAssistNameReference(char[][] previousIdentif
return new CompletionOnQualifiedNameReference(
previousIdentifiers,
assistName,
- positions);
+ positions,
+ isInsideAttributeValue());
}
public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
@@ -2626,7 +2900,7 @@ public TypeReference createParameterizedQualifiedAssistTypeReference(char[][] pr
public NameReference createSingleAssistNameReference(char[] assistName, long position) {
int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
if(!isInsideMethod()) {
- return new CompletionOnSingleNameReference(assistName, position);
+ return new CompletionOnSingleNameReference(assistName, position, isInsideAttributeValue());
} else {
boolean canBeExplicitConstructorCall = false;
if(kind == K_BLOCK_DELIMITER
@@ -2701,7 +2975,7 @@ public NameReference createSingleAssistNameReference(char[] assistName, long pos
}
System.arraycopy(keywords, 0 , keywords = new char[count][], 0, count);
- return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall);
+ return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall, isInsideAttributeValue());
}
}
}
@@ -2736,6 +3010,7 @@ public void flushAssistState() {
super.flushAssistState();
this.isOrphanCompletionNode = false;
+ this.isAlreadyAttached = false;
assistNodeParent = null;
CompletionScanner completionScanner = (CompletionScanner)this.scanner;
completionScanner.completedIdentifierStart = 0;
@@ -2822,6 +3097,15 @@ private boolean isEmptyNameCompletion() {
this.assistNode instanceof CompletionOnSingleNameReference &&
(((CompletionOnSingleNameReference)this.assistNode).token.length == 0);
}
+protected boolean isInsideAnnotation() {
+ int i = elementPtr;
+ while(i > -1) {
+ if(elementKindStack[i] == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN)
+ return true;
+ i--;
+ }
+ return false;
+}
protected boolean isIndirectlyInsideBlock(){
int i = elementPtr;
while(i > -1) {

Back to the top