### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest_1_5.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest_1_5.java,v retrieving revision 1.4 diff -u -r1.4 StatementRecoveryTest_1_5.java --- src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest_1_5.java 25 Jan 2008 11:59:24 -0000 1.4 +++ src/org/eclipse/jdt/core/tests/compiler/parser/StatementRecoveryTest_1_5.java 6 May 2008 17:31:49 -0000 @@ -611,7 +611,7 @@ " super();\n" + " }\n" + " void foo() {\n" + - " @AnAnnotation class Y {\n" + + " @AnAnnotation(name = $missing$) class Y {\n" + " Y() {\n" + " super();\n" + " }\n" + @@ -627,7 +627,7 @@ " }\n" + " void foo() {\n" + " foo1();\n" + - " @AnAnnotation class Y {\n" + + " @AnAnnotation(name = $missing$) class Y {\n" + " Y() {\n" + " super();\n" + " }\n" + Index: src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java,v retrieving revision 1.17 diff -u -r1.17 AnnotationDietRecoveryTest.java --- src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java 23 Apr 2008 08:21:42 -0000 1.17 +++ src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java 6 May 2008 17:31:49 -0000 @@ -919,7 +919,7 @@ String expectedDietUnitToString = "package a;\n" + - "public @AnAnnotation @AnAnnotation2(name2) class X {\n" + + "public @AnAnnotation(name = $missing$) @AnAnnotation2(name2) class X {\n" + " public X() {\n" + " }\n" + "}\n"; @@ -927,7 +927,7 @@ String expectedDietPlusBodyUnitToString = "package a;\n" + - "public @AnAnnotation @AnAnnotation2(name2) class X {\n" + + "public @AnAnnotation(name = $missing$) @AnAnnotation2(name2) class X {\n" + " public X() {\n" + " super();\n" + " }\n" + @@ -965,14 +965,14 @@ String expectedDietUnitToString = "package a;\n" + - "public @AnAnnotation(name) @AnAnnotation2 class X {\n" + + "public @AnAnnotation(name) @AnAnnotation2(name2 = $missing$) class X {\n" + " public X() {\n" + " }\n" + "}\n"; String expectedDietPlusBodyUnitToString = "package a;\n" + - "public @AnAnnotation(name) @AnAnnotation2 class X {\n" + + "public @AnAnnotation(name) @AnAnnotation2(name2 = $missing$) class X {\n" + " public X() {\n" + " super();\n" + " }\n" + @@ -1059,7 +1059,7 @@ String expectedDietUnitToString = "package a;\n" + "public class X {\n" + - " @AnAnnotation int field;\n" + + " @AnAnnotation(name = $missing$) int field;\n" + " public X() {\n" + " }\n" + "}\n"; @@ -1067,7 +1067,7 @@ String expectedDietPlusBodyUnitToString = "package a;\n" + "public class X {\n" + - " @AnAnnotation int field;\n" + + " @AnAnnotation(name = $missing$) int field;\n" + " public X() {\n" + " super();\n" + " }\n" + @@ -1160,7 +1160,7 @@ "public class X {\n" + " public X() {\n" + " }\n" + - " @AnAnnotation void foo() {\n" + + " @AnAnnotation(name = $missing$) void foo() {\n" + " }\n" + "}\n"; @@ -1170,7 +1170,7 @@ " public X() {\n" + " super();\n" + " }\n" + - " @AnAnnotation void foo() {\n" + + " @AnAnnotation(name = $missing$) void foo() {\n" + " }\n" + "}\n"; @@ -1641,14 +1641,14 @@ String expectedDietUnitToString = "package a;\n" + - "public @AnAnnotation1 class X {\n" + + "public @AnAnnotation1(name = $missing$) class X {\n" + " public X() {\n" + " }\n" + "}\n"; String expectedDietPlusBodyUnitToString = "package a;\n" + - "public @AnAnnotation1 class X {\n" + + "public @AnAnnotation1(name = $missing$) class X {\n" + " public X() {\n" + " super();\n" + " }\n" + @@ -1774,4 +1774,139 @@ expectedCompletionDietUnitToString, testName); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228464 +public void test0038() { + + String s = + "package a; \n" + + "@AnAnnotation(name=) \n" + + "public class X { \n" + + "} \n"; + + String expectedDietUnitToString = + "package a;\n" + + "public @AnAnnotation(name = $missing$) class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + + String expectedDietPlusBodyUnitToString = + "package a;\n" + + "public @AnAnnotation(name = $missing$) class X {\n" + + " public X() {\n" + + " super();\n" + + " }\n" + + "}\n"; + + + String expectedFullUnitToString = + expectedDietUnitToString; + + String expectedCompletionDietUnitToString = + "package a;\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + String testName = ""; + checkParse( + s.toCharArray(), + expectedDietUnitToString, + expectedDietPlusBodyUnitToString, + expectedFullUnitToString, + expectedCompletionDietUnitToString, + testName); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228464 +public void test0039() { + + String s = + "package a; \n" + + "@AnAnnotation(name1=a,name2=) \n" + + "public class X { \n" + + "} \n"; + + String expectedDietUnitToString = + "package a;\n" + + "public @AnAnnotation(name1 = a,name2 = $missing$) class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + + String expectedDietPlusBodyUnitToString = + "package a;\n" + + "public @AnAnnotation(name1 = a,name2 = $missing$) class X {\n" + + " public X() {\n" + + " super();\n" + + " }\n" + + "}\n"; + + + String expectedFullUnitToString = + expectedDietUnitToString; + + String expectedCompletionDietUnitToString = + "package a;\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + String testName = ""; + checkParse( + s.toCharArray(), + expectedDietUnitToString, + expectedDietPlusBodyUnitToString, + expectedFullUnitToString, + expectedCompletionDietUnitToString, + testName); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228464 +public void test0040() { + + String s = + "package a; \n" + + "@AnAnnotation(name1=a,name2=,name3=c) \n" + + "public class X { \n" + + "} \n"; + + String expectedDietUnitToString = + "package a;\n" + + "public @AnAnnotation(name1 = a,name2 = $missing$) class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + + String expectedDietPlusBodyUnitToString = + "package a;\n" + + "public @AnAnnotation(name1 = a,name2 = $missing$) class X {\n" + + " public X() {\n" + + " super();\n" + + " }\n" + + "}\n"; + + + String expectedFullUnitToString = + expectedDietUnitToString; + + String expectedCompletionDietUnitToString = + "package a;\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + "}\n"; + + String testName = ""; + checkParse( + s.toCharArray(), + expectedDietUnitToString, + expectedDietPlusBodyUnitToString, + expectedFullUnitToString, + expectedCompletionDietUnitToString, + testName); +} } #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/LocalVariable.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java,v retrieving revision 1.25 diff -u -r1.25 LocalVariable.java --- model/org/eclipse/jdt/internal/core/LocalVariable.java 1 Mar 2008 18:41:15 -0000 1.25 +++ model/org/eclipse/jdt/internal/core/LocalVariable.java 6 May 2008 17:32:02 -0000 @@ -24,6 +24,7 @@ import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner; import org.eclipse.jdt.internal.core.util.MementoTokenizer; import org.eclipse.jdt.internal.core.util.Util; @@ -174,6 +175,10 @@ return new String(qualifiedName); } else if (expression instanceof SingleNameReference) { char[] simpleName = ((SingleNameReference) expression).token; + if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) { + memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; + return null; + } memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME; return new String(simpleName); } else if (expression instanceof ArrayInitializer) { Index: model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java,v retrieving revision 1.78 diff -u -r1.78 CompilationUnitStructureRequestor.java --- model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java 6 Mar 2008 15:31:29 -0000 1.78 +++ model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java 6 May 2008 17:32:02 -0000 @@ -31,6 +31,7 @@ import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.parser.Parser; +import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter; import org.eclipse.jdt.internal.core.util.Util; @@ -664,6 +665,10 @@ return new String(qualifiedName); } else if (expression instanceof SingleNameReference) { char[] simpleName = ((SingleNameReference) expression).token; + if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) { + memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; + return null; + } memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME; return new String(simpleName); } else if (expression instanceof ArrayInitializer) { Index: compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java,v retrieving revision 1.1 diff -u -r1.1 RecoveredAnnotation.java --- compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java 25 Jan 2008 11:59:19 -0000 1.1 +++ compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java 6 May 2008 17:31:57 -0000 @@ -17,6 +17,7 @@ import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -29,6 +30,8 @@ private int identifierPtr; private int identifierLengthPtr; private int sourceStart; + public boolean hasPendingMemberValueName; + public int memberValuPairEqualEnd = -1; public Annotation annotation; public RecoveredAnnotation(int identifierPtr, int identifierLengthPtr, int sourceStart, RecoveredElement parent, int bracketBalance) { @@ -69,32 +72,62 @@ boolean needUpdateRParenPos = false; + MemberValuePair pendingMemberValueName = 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); + } parser.identifierPtr = this.identifierPtr; parser.identifierLengthPtr = this.identifierLengthPtr; TypeReference typeReference = parser.getAnnotationType(); switch (this.kind) { case NORMAL: - MemberValuePair[] memberValuePairs = null; if (parser.astPtr > -1 && parser.astStack[parser.astPtr] instanceof MemberValuePair) { + MemberValuePair[] memberValuePairs = null; + int argLength = parser.astLengthStack[parser.astLengthPtr]; int argStart = parser.astPtr - argLength + 1; if (argLength > 0) { - System.arraycopy(parser.astStack, argStart, memberValuePairs = new MemberValuePair[argLength], 0, argLength); - parser.astLengthPtr--; - parser.astPtr -= argLength; - - MemberValuePair lastMemberValuePair = memberValuePairs[memberValuePairs.length - 1]; - - NormalAnnotation normalAnnotation = new NormalAnnotation(typeReference, this.sourceStart); - normalAnnotation.memberValuePairs = memberValuePairs; - normalAnnotation.declarationSourceEnd = - lastMemberValuePair.value != null + int annotationEnd; + if (pendingMemberValueName != null) { + memberValuePairs = new MemberValuePair[argLength + 1]; + + System.arraycopy(parser.astStack, argStart, memberValuePairs, 0, argLength); + parser.astLengthPtr--; + parser.astPtr -= argLength; + + memberValuePairs[argLength] = pendingMemberValueName; + + annotationEnd = pendingMemberValueName.sourceEnd; + } else { + memberValuePairs = new MemberValuePair[argLength]; + + System.arraycopy(parser.astStack, argStart, memberValuePairs, 0, argLength); + parser.astLengthPtr--; + parser.astPtr -= argLength; + + MemberValuePair lastMemberValuePair = memberValuePairs[memberValuePairs.length - 1]; + + annotationEnd = + lastMemberValuePair.value != null ? lastMemberValuePair.value instanceof Annotation ? ((Annotation)lastMemberValuePair.value).declarationSourceEnd : lastMemberValuePair.value.sourceEnd : lastMemberValuePair.sourceEnd; + } + + NormalAnnotation normalAnnotation = new NormalAnnotation(typeReference, this.sourceStart); + normalAnnotation.memberValuePairs = memberValuePairs; + normalAnnotation.declarationSourceEnd = annotationEnd; normalAnnotation.bits |= ASTNode.IsRecovered; annot = normalAnnotation; @@ -122,11 +155,20 @@ } if (!needUpdateRParenPos) { - MarkerAnnotation markerAnnotation = new MarkerAnnotation(typeReference, this.sourceStart); - markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd; - markerAnnotation.bits |= ASTNode.IsRecovered; - - annot = markerAnnotation; + if (pendingMemberValueName != null) { + NormalAnnotation normalAnnotation = new NormalAnnotation(typeReference, this.sourceStart); + normalAnnotation.memberValuePairs = new MemberValuePair[]{pendingMemberValueName}; + normalAnnotation.declarationSourceEnd = pendingMemberValueName.value.sourceEnd; + normalAnnotation.bits |= ASTNode.IsRecovered; + + annot = normalAnnotation; + } else { + MarkerAnnotation markerAnnotation = new MarkerAnnotation(typeReference, this.sourceStart); + markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd; + markerAnnotation.bits |= ASTNode.IsRecovered; + + annot = markerAnnotation; + } } parser.currentElement = this.addAnnotation(annot, this.identifierPtr); Index: compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java,v retrieving revision 1.386 diff -u -r1.386 Parser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 23 Apr 2008 13:18:56 -0000 1.386 +++ compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 6 May 2008 17:31:57 -0000 @@ -3046,7 +3046,10 @@ } protected void consumeEnterMemberValue() { // EnterMemberValue ::= $empty - // do nothing by default + if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { + RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation)this.currentElement; + recoveredAnnotation.hasPendingMemberValueName = true; + } } protected void consumeEnterMemberValueArrayInitializer() { // EnterMemberValueArrayInitializer ::= $empty @@ -3541,7 +3544,11 @@ } protected void consumeExitMemberValue() { // ExitMemberValue ::= $empty - // do nothing by default + if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { + RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation)this.currentElement; + recoveredAnnotation.hasPendingMemberValueName = false; + recoveredAnnotation.memberValuPairEqualEnd = -1; + } } protected void consumeExitTryBlock() { //ExitTryBlock ::= $empty @@ -7613,10 +7620,17 @@ break; case TokenNameELLIPSIS : pushOnIntStack(this.scanner.currentPosition - 1); - break; + break; + case TokenNameEQUAL : + if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { + RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation) this.currentElement; + if (recoveredAnnotation.memberValuPairEqualEnd == -1) { + recoveredAnnotation.memberValuPairEqualEnd = this.scanner.currentPosition - 1; + } + } + break; // case TokenNameCOMMA : // case TokenNameCOLON : - // case TokenNameEQUAL : // case TokenNameLBRACKET : // case TokenNameDOT : // case TokenNameERROR : Index: dom/org/eclipse/jdt/core/dom/ASTConverter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java,v retrieving revision 1.260 diff -u -r1.260 ASTConverter.java --- dom/org/eclipse/jdt/core/dom/ASTConverter.java 19 Mar 2008 09:39:24 -0000 1.260 +++ dom/org/eclipse/jdt/core/dom/ASTConverter.java 6 May 2008 17:32:02 -0000 @@ -39,6 +39,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation; import org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -2081,6 +2082,12 @@ start = memberValuePair.sourceStart; end = value.getStartPosition() + value.getLength() - 1; pair.setSourceRange(start, end - start + 1); + + if (memberValuePair.value instanceof SingleNameReference && + ((SingleNameReference)memberValuePair.value).token == RecoveryScanner.FAKE_IDENTIFIER) { + pair.setFlags(pair.getFlags() | ASTNode.RECOVERED); + } + if (this.resolveBindings) { recordNodes(simpleName, memberValuePair); recordNodes(pair, memberValuePair); @@ -2116,14 +2123,22 @@ public NormalAnnotation convert(org.eclipse.jdt.internal.compiler.ast.NormalAnnotation annotation) { final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast); setTypeNameForAnnotation(annotation, normalAnnotation); + + int start = annotation.sourceStart; + int end = annotation.declarationSourceEnd; + org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs; if (memberValuePairs != null) { for (int i = 0, max = memberValuePairs.length; i < max; i++) { - normalAnnotation.values().add(convert(memberValuePairs[i])); + MemberValuePair memberValuePair = convert(memberValuePairs[i]); + int memberValuePairEnd = memberValuePair.getStartPosition() + memberValuePair.getLength() - 1; + if (end == memberValuePairEnd) { + normalAnnotation.setFlags(normalAnnotation.getFlags() | ASTNode.RECOVERED); + } + normalAnnotation.values().add(memberValuePair); } } - int start = annotation.sourceStart; - int end = annotation.declarationSourceEnd; + normalAnnotation.setSourceRange(start, end - start + 1); if (this.resolveBindings) { recordNodes(normalAnnotation, annotation); #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTestJLS3.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTestJLS3.java,v retrieving revision 1.4 diff -u -r1.4 ASTConverterBugsTestJLS3.java --- src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTestJLS3.java 11 Apr 2008 13:40:26 -0000 1.4 +++ src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTestJLS3.java 6 May 2008 17:32:04 -0000 @@ -441,7 +441,7 @@ ASTResult result = this.buildMarkedAST( "/Converter15/src/a/X.java", "package a;\n" + - "[*1*]@AnAnnotation[*1*](value=)\n" + + "[*1*]@AnAnnotation(value=[*1*])\n" + "[*2*]@AnAnnotation2(value=\"b\")[*2*]\n" + "[*3*]public[*3*] class X {\n" + "}\n"); @@ -449,11 +449,11 @@ assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*]@AnAnnotation[*1*] [*2*]@AnAnnotation2(value=\"b\")[*2*] [*3*]public[*3*] class X {\n" + + "[*1*]@AnAnnotation(value=$missing$)[*1*] [*2*]@AnAnnotation2(value=\"b\")[*2*] [*3*]public[*3*] class X {\n" + "}\n" + "\n" + "===== Details =====\n" + - "1:MARKER_ANNOTATION,[11,13],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "1:NORMAL_ANNOTATION,[11,20],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + "2:NORMAL_ANNOTATION,[33,25],,,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + "3:MODIFIER,[59,6],,,[N/A]\n" + "===== Problems =====\n" + @@ -486,19 +486,19 @@ "/Converter15/src/a/X.java", "package a;\n" + "[*1*]@AnAnnotation(value=\"a\")[*1*]\n" + - "[*2*]@AnAnnotation2[*2*](value=)\n" + + "[*2*]@AnAnnotation2(value=[*2*])\n" + "[*3*]public[*3*] class X {\n" + "}\n"); assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*]@AnAnnotation(value=\"a\")[*1*] [*2*]@AnAnnotation2[*2*] [*3*]public[*3*] class X {\n" + + "[*1*]@AnAnnotation(value=\"a\")[*1*] [*2*]@AnAnnotation2(value=$missing$)[*2*] [*3*]public[*3*] class X {\n" + "}\n" + "\n" + "===== Details =====\n" + "1:NORMAL_ANNOTATION,[11,24],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + - "2:MARKER_ANNOTATION,[36,14],,,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + + "2:NORMAL_ANNOTATION,[36,21],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + "3:MODIFIER,[59,6],,,[N/A]\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 3)\n" + @@ -529,20 +529,20 @@ ASTResult result = this.buildMarkedAST( "/Converter15/src/a/X.java", "package a;\n" + - "[*1*]@AnAnnotation[*1*](value=)\n" + - "[*2*]@AnAnnotation2[*2*](value=)\n" + + "[*1*]@AnAnnotation(value=[*1*])\n" + + "[*2*]@AnAnnotation2(value=[*2*])\n" + "[*3*]public[*3*] class X {\n" + "}\n"); assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*]@AnAnnotation[*1*] [*2*]@AnAnnotation2[*2*] [*3*]public[*3*] class X {\n" + + "[*1*]@AnAnnotation(value=$missing$)[*1*] [*2*]@AnAnnotation2(value=$missing$)[*2*] [*3*]public[*3*] class X {\n" + "}\n" + "\n" + "===== Details =====\n" + - "1:MARKER_ANNOTATION,[11,13],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + - "2:MARKER_ANNOTATION,[33,14],,,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + + "1:NORMAL_ANNOTATION,[11,20],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "2:NORMAL_ANNOTATION,[33,21],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + "3:MODIFIER,[56,6],,,[N/A]\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 2)\n" + @@ -579,7 +579,7 @@ "package a;\n" + "public class X {\n" + " public void foo(){\n" + - " [*1*]@AnAnnotation[*1*](value=)\n" + + " [*1*]@AnAnnotation(value=[*1*])\n" + " [*2*]@AnAnnotation2(value=\"b\")[*2*]\n" + " class Y {}\n" + " }\n" + @@ -590,13 +590,13 @@ "package a;\n" + "public class X {\n" + " public void foo(){\n" + - "[*1*]@AnAnnotation[*1*] [*2*]@AnAnnotation2(value=\"b\")[*2*] class Y {\n" + + "[*1*]@AnAnnotation(value=$missing$)[*1*] [*2*]@AnAnnotation2(value=\"b\")[*2*] class Y {\n" + " }\n" + " }\n" + "}\n" + "\n" + "===== Details =====\n" + - "1:MARKER_ANNOTATION,[53,13],,,[ANNOTATION,La/X$115$Y;@La/AnAnnotation;,]\n" + + "1:NORMAL_ANNOTATION,[53,20],,RECOVERED,[ANNOTATION,La/X$115$Y;@La/AnAnnotation;,]\n" + "2:NORMAL_ANNOTATION,[79,25],,,[ANNOTATION,La/X$115$Y;@La/AnAnnotation2;,]\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 4)\n" + @@ -705,20 +705,20 @@ ASTResult result = this.buildMarkedAST( "/Converter15/src/a/X.java", "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*]([*3*]name1=[*3*])\n" + + "[*1*][*2*]@AnAnnotation([*3*]name1=[*3*][*2*])\n" + "public class X {\n" + "}[*1*]\n"); assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*] public class X {\n" + + "[*1*][*2*]@AnAnnotation([*3*]name1=$missing$[*3*])[*2*] public class X {\n" + "}[*1*]\n" + "\n" + "===== Details =====\n" + - "1:TYPE_DECLARATION,[11,40],,MALFORMED|RECOVERED,[TYPE,La/X;,]\n" + - "2:MARKER_ANNOTATION,[11,13],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + - "3:No corresponding node\n" + + "1:TYPE_DECLARATION,[11,40],,MALFORMED,[TYPE,La/X;,]\n" + + "2:NORMAL_ANNOTATION,[11,20],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "3:MEMBER_VALUE_PAIR,[25,6],,RECOVERED,[N/A]\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 2)\n" + " @AnAnnotation(name1=)\n" + @@ -831,19 +831,20 @@ ASTResult result = this.buildMarkedAST( "/Converter15/src/a/X.java", "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*](value=@AnAnnotation2(value=))\n" + + "[*1*][*2*]@AnAnnotation(value=[*2*][*3*]@AnAnnotation2(value=[*3*]))\n" + "public class X {\n" + "}[*1*]\n"); assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*] public class X {\n" + + "[*1*][*2*]@AnAnnotation(value=$missing$)[*2*] public class X {\n" + "}[*1*]\n" + "\n" + "===== Details =====\n" + "1:TYPE_DECLARATION,[11,62],,MALFORMED|RECOVERED,[TYPE,La/X;,]\n" + - "2:MARKER_ANNOTATION,[11,13],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "2:NORMAL_ANNOTATION,[11,20],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "3:No corresponding node\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 2)\n" + " @AnAnnotation(value=@AnAnnotation2(value=))\n" + @@ -874,21 +875,22 @@ ASTResult result = this.buildMarkedAST( "/Converter15/src/a/X.java", "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*](value1=,[*3*]value=[*4*]@AnAnnotation2(value=\"b\")[*4*][*3*])\n" + + "[*1*][*2*]@AnAnnotation([*3*]value1=[*3*][*2*],[*4*]value=[*5*]@AnAnnotation2(value=\"b\")[*5*][*4*])\n" + "public class X {\n" + "}[*1*]\n"); assertASTResult( "===== AST =====\n" + "package a;\n" + - "[*1*][*2*]@AnAnnotation[*2*] [*4*]@AnAnnotation2(value=\"b\")[*4*] public class X {\n" + + "[*1*][*2*]@AnAnnotation([*3*]value1=$missing$[*3*])[*2*] [*5*]@AnAnnotation2(value=\"b\")[*5*] public class X {\n" + "}[*1*]\n" + "\n" + "===== Details =====\n" + - "1:TYPE_DECLARATION,[11,73],,MALFORMED|RECOVERED,[TYPE,La/X;,]\n" + - "2:MARKER_ANNOTATION,[11,13],,,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + - "4:NORMAL_ANNOTATION,[39,25],,,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + - "3:No corresponding node\n" + + "1:TYPE_DECLARATION,[11,73],,MALFORMED,[TYPE,La/X;,]\n" + + "2:NORMAL_ANNOTATION,[11,21],,RECOVERED,[ANNOTATION,La/X;@La/AnAnnotation;,]\n" + + "3:MEMBER_VALUE_PAIR,[25,7],,RECOVERED,[N/A]\n" + + "5:NORMAL_ANNOTATION,[39,25],,,[ANNOTATION,La/X;@La/AnAnnotation2;,]\n" + + "4:No corresponding node\n" + "===== Problems =====\n" + "1. ERROR in /Converter15/src/a/X.java (at line 2)\n" + " @AnAnnotation(value1=,value=@AnAnnotation2(value=\"b\"))\n" + Index: src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java,v retrieving revision 1.64 diff -u -r1.64 CompilationUnitTests.java --- src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java 9 Apr 2008 14:23:09 -0000 1.64 +++ src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java 6 May 2008 17:32:06 -0000 @@ -823,7 +823,22 @@ "@MyAnnot([unknown]{})\n", annotations); } - +/* + * Ensure that the recovered annotation is correct + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=228464 ) + */ +public void testAnnotations27() throws CoreException { + createWorkingCopy( + "package p;\n" + + "@MyAnnot(name=)\n" + + "public class Y {\n" + + "}" + ); + IAnnotation[] annotations = this.workingCopy.getType("Y").getAnnotations(); + assertAnnotationsEqual( + "@MyAnnot(name=)\n", + annotations); +} /* * Ensures that getFullyQualifiedName() behaves correctly for a top level source type */ Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v retrieving revision 1.149 diff -u -r1.149 JavaSearchBugsTests.java --- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 25 Apr 2008 13:20:43 -0000 1.149 +++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 6 May 2008 17:32:11 -0000 @@ -10003,6 +10003,39 @@ } /** + * @bug 228464: Annotation.getMemberValuePairs() empty for single attribute with empty value + * @test Ensure that annotation are correctly recovered + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=228464" + */ +public void testBug228464() throws CoreException { + workingCopies = new ICompilationUnit[1]; + workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/Test.java", + "public class Test {\n" + + " void m() {\n" + + " @TestAnnotation(name=) Test iii;\n" + + " }\n" + + "\n" + + "}\n" + ); + this.resultCollector.showSelection = true; + IType type = workingCopies[0].getType("Test"); + search(type, REFERENCES, getJavaSearchWorkingCopiesScope()); + + IAnnotation[] annotations = new IAnnotation[0]; + if (resultCollector.match != null && + resultCollector.match instanceof ReferenceMatch) { + IJavaElement element = ((ReferenceMatch)resultCollector.match).getLocalElement(); + if (element instanceof ILocalVariable) { + annotations = ((ILocalVariable)element).getAnnotations(); + } + } + + assertAnnotationsEqual( + "@TestAnnotation(name=)\n", + annotations); +} + +/** * @bug 228852: classes opened via Open Type not found * @test Ensure that types found in an internal jar exist when using a workspace scope * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=228852"