Skip to content

Commit

Permalink
missing pieces in the AST: parser seems to skip broken annotation val…
Browse files Browse the repository at this point in the history
…ue when there is a . at the end (eclipse-jdt#3161)

detect the situation during Parser.consumeZeroTypeAnnotations() (similar to eclipse-jdt#3155) and recover accordingly in RecoveredAnnotation.updateFromParserState()

fixes eclipse-jdt#3156
  • Loading branch information
stephan-herrmann authored Oct 25, 2024
1 parent a0b0601 commit 55fbb80
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6668,12 +6668,17 @@ protected void consumeZeroTypeAnnotations() {
// Name ::= SimpleName
// TypeAnnotationsopt ::= $empty
pushOnTypeAnnotationLengthStack(0); // signal absence of @308 annotations.
if (this.currentElement instanceof RecoveredAnnotation ann
&& ann.parent instanceof RecoveredMethod meth
&& !meth.foundOpeningBrace
&& this.currentToken == TokenNameRPAREN) {
// take note of an incomplete annotation "@Ann(v=)":
meth.incompleteParameterAnnotationSeen = true;
if (this.currentElement instanceof RecoveredAnnotation ann) {
if (ann.parent instanceof RecoveredMethod meth
&& !meth.foundOpeningBrace
&& this.currentToken == TokenNameRPAREN) {
// take note of an incomplete annotation "@Ann(v=)":
meth.incompleteParameterAnnotationSeen = true;
}
if (this.identifierPtr > ann.identifierPtr) {
ann.hasPendingMemberValueName = true;
ann.errorToken = this.currentToken;
}
}
}
// BEGIN_AUTOGENERATED_REGION_CONSUME_RULE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* Copyright (c) 2008, 2024 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -21,12 +21,13 @@ public class RecoveredAnnotation extends RecoveredElement {
public static final int SINGLE_MEMBER = 2;

private int kind;
private final int identifierPtr;
final int identifierPtr;
private final int identifierLengthPtr;
private final int sourceStart;
public boolean hasPendingMemberValueName;
public int memberValuPairEqualEnd = -1;
public Annotation annotation;
public int errorToken;

public RecoveredAnnotation(int identifierPtr, int identifierLengthPtr, int sourceStart, RecoveredElement parent, int bracketBalance) {
super(parent, bracketBalance);
Expand Down Expand Up @@ -70,16 +71,24 @@ public void updateFromParserState() {
boolean needUpdateRParenPos = false;

MemberValuePair pendingMemberValueName = null;
Expression singleValue = null;
if (this.hasPendingMemberValueName && this.identifierPtr < parser.identifierPtr) {
char[] memberValueName = parser.identifierStack[this.identifierPtr + 1];

long pos = parser.identifierPositionStack[this.identifierPtr + 1];
int start = (int) (pos >>> 32);
int end = (int)pos;
int valueEnd = this.memberValuPairEqualEnd > -1 ? this.memberValuPairEqualEnd : end;

SingleNameReference fakeExpression = new SingleNameReference(RecoveryScanner.FAKE_IDENTIFIER, (((long) valueEnd + 1) << 32) + (valueEnd));
pendingMemberValueName = new MemberValuePair(memberValueName, start, end, fakeExpression);
if (this.errorToken == TerminalTokens.TokenNameDOT) {
// do we need to consult identifierLengthStack to pull more than one name segment?
char[][] qname = new char[][] { memberValueName, RecoveryScanner.FAKE_IDENTIFIER };
singleValue = new QualifiedNameReference(qname, new long[] {pos,pos}, start, end);
this.kind = SINGLE_MEMBER;
} else {
int valueEnd = this.memberValuPairEqualEnd > -1 ? this.memberValuPairEqualEnd : end;
SingleNameReference fakeExpression = new SingleNameReference(RecoveryScanner.FAKE_IDENTIFIER, (((long) valueEnd + 1) << 32) + (valueEnd));
pendingMemberValueName = new MemberValuePair(memberValueName, start, end, fakeExpression);
}
}
parser.identifierPtr = this.identifierPtr;
parser.identifierLengthPtr = this.identifierLengthPtr;
Expand Down Expand Up @@ -136,9 +145,10 @@ public void updateFromParserState() {

break;
case SINGLE_MEMBER:
if (parser.expressionPtr > -1) {
Expression memberValue = parser.expressionStack[parser.expressionPtr--];

Expression memberValue = singleValue != null ? singleValue
: parser.expressionPtr > -1 ? parser.expressionStack[parser.expressionPtr--]
: null;
if (memberValue != null) {
SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.sourceStart);
singleMemberAnnotation.memberValue = memberValue;
singleMemberAnnotation.declarationSourceEnd = memberValue.sourceEnd;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1120,4 +1120,39 @@ public TestDependsOnClass( @Qualifier(value=$missing$) Object mybean){
assertTrue(mod.isAnnotation());
assertEquals("Qualifier", ((Annotation) mod).getTypeName().toString());
}

public void testGH3156() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy(
"/Converter18/src/test/X.java",
"""
package test;
public class X {
@Value(spring.) private String value1;
}
""");
ASTNode result = runConversion(getJLS8(), this.workingCopies[0], true, true);

assertASTNodeEquals(
"""
package test;
public class X {
@Value(spring.$missing$) private String value1;
}
""",
result);

ASTNode node = getASTNode((CompilationUnit) result, 0, 0);
assertNotNull(node);
assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); //$NON-NLS-1$
FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
IExtendedModifier mod = (IExtendedModifier) fieldDeclaration.modifiers().get(0);
assertTrue(mod.isAnnotation());
Annotation annotation = (Annotation) mod;
assertEquals("Value", annotation.getTypeName().toString());
assertTrue(annotation.isSingleMemberAnnotation());
Expression value = ((SingleMemberAnnotation) annotation).getValue();
assertEquals(QualifiedName.class, value.getClass());
assertEquals("spring.$missing$", value.toString());
}
}

0 comments on commit 55fbb80

Please sign in to comment.