### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java,v retrieving revision 1.48 diff -u -r1.48 Javadoc.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 13 Oct 2006 19:20:46 -0000 1.48 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java 17 Nov 2006 16:07:12 -0000 @@ -30,6 +30,9 @@ // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600 // Store param references for tag with invalid syntax public JavadocSingleNameReference[] invalidParameters; // @param + // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399 + // Store value tag positions + public long valuePositions = -1; public Javadoc(int sourceStart, int sourceEnd) { this.sourceStart = sourceStart; @@ -219,6 +222,12 @@ for (int i = 0; i < seeTagsLength; i++) { resolveReference(this.seeReferences[i], scope); } + + // @value tag + boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; + if (!source15 && this.valuePositions != -1) { + scope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions); + } } /* @@ -228,8 +237,10 @@ // get method declaration AbstractMethodDeclaration methDecl = methScope.referenceMethod(); - boolean overriding = methDecl == null || methDecl.binding == null ? false : !methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) != 0); - + boolean overriding = methDecl == null /* field declaration */ || methDecl.binding == null /* compiler error */ + ? false : + !methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) != 0); + // @see tags int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length; boolean superRef = false; @@ -317,6 +328,12 @@ // @throws/@exception tags resolveThrowsTags(methScope, reportMissing); + // @value tag + boolean source15 = methScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; + if (!source15 && methDecl != null && this.valuePositions != -1) { + methScope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions); + } + // Resolve param tags with invalid syntax int length = this.invalidParameters == null ? 0 : this.invalidParameters.length; for (int i = 0; i < length; i++) { Index: compiler/org/eclipse/jdt/core/compiler/IProblem.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java,v retrieving revision 1.183 diff -u -r1.183 IProblem.java --- compiler/org/eclipse/jdt/core/compiler/IProblem.java 9 Nov 2006 21:15:04 -0000 1.183 +++ compiler/org/eclipse/jdt/core/compiler/IProblem.java 17 Nov 2006 16:07:11 -0000 @@ -780,6 +780,11 @@ * Javadoc comments */ /** + * Problem warned on duplicated tag. + * @since 3.3 + */ + int JavadocDuplicateTag = Javadoc + Internal + 464; + /** * Problem signaled on an hidden reference due to a too low visibility level. * @since 3.3 */ Index: compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties,v retrieving revision 1.212 diff -u -r1.212 messages.properties --- compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 9 Nov 2006 21:15:04 -0000 1.212 +++ compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 17 Nov 2006 16:07:15 -0000 @@ -363,6 +363,7 @@ 460 = Empty block should be documented ### DOC +464 = Unexpected duplicated tag @{0} 465 = ''{0}'' visibility for malformed doc comments hides this ''{1}'' reference 466 = Invalid member type qualification 467 = Missing identifier Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v retrieving revision 1.326 diff -u -r1.326 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 9 Nov 2006 21:15:04 -0000 1.326 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 17 Nov 2006 16:07:15 -0000 @@ -198,6 +198,7 @@ return CompilerOptions.UnusedLabel; case IProblem.JavadocUnexpectedTag: + case IProblem.JavadocDuplicateTag: case IProblem.JavadocDuplicateReturnTag: case IProblem.JavadocInvalidThrowsClass: case IProblem.JavadocInvalidSeeReference: @@ -3589,6 +3590,15 @@ public void javadocDuplicatedReturnTag(int sourceStart, int sourceEnd){ this.handle(IProblem.JavadocDuplicateReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd); } +public void javadocDuplicatedTag(char[] tagName, int sourceStart, int sourceEnd){ + String[] arguments = new String[] { new String(tagName) }; + this.handle( + IProblem.JavadocDuplicateTag, + arguments, + arguments, + sourceStart, + sourceEnd); +} public void javadocDuplicatedThrowsClassName(TypeReference typeReference, int modifiers) { int severity = computeSeverity(IProblem.JavadocDuplicateThrowsClassName); if (severity == ProblemSeverities.Ignore) return; Index: compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java,v retrieving revision 1.57 diff -u -r1.57 JavadocParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 23 Oct 2006 16:45:42 -0000 1.57 +++ compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 17 Nov 2006 16:07:12 -0000 @@ -30,6 +30,10 @@ private int invalidParamReferencesPtr = -1; private ASTNode[] invalidParamReferencesStack; + // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399 + // Store value tag positions + private long validValuePositions, invalidValuePositions; + public JavadocParser(Parser sourceParser) { super(sourceParser); this.kind = COMPIL_PARSER | TEXT_VERIF; @@ -47,6 +51,8 @@ this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr]; this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1; this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr]; + this.validValuePositions = -1; + this.invalidValuePositions = -1; // Init javadoc if necessary if (this.checkDocComment) { @@ -540,15 +546,28 @@ } break; case 'v': - if (this.sourceLevel >= ClassFileConstants.JDK1_5 && length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) { + if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) { this.tagValue = TAG_VALUE_VALUE; - if (this.inlineTagStarted) { - valid = parseReference(); - } else { - valid = false; - if (this.reportProblems) { - this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); + if (this.sourceLevel >= ClassFileConstants.JDK1_5) { + if (this.inlineTagStarted) { + valid = parseReference(); + } else { + valid = false; + if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); + } + } + if (this.validValuePositions == -1) { + if (this.invalidValuePositions != -1) { + if (this.reportProblems) this.sourceParser.problemReporter().javadocDuplicatedTag(tagName, (int) (this.invalidValuePositions>>>32), (int) this.invalidValuePositions); } + if (valid) { + this.validValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd; + this.invalidValuePositions = -1; + } else { + this.invalidValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd; + } + } else { + if (this.reportProblems) this.sourceParser.problemReporter().javadocDuplicatedTag(tagName, this.tagSourceStart, this.tagSourceEnd); } } else { createTag(); @@ -720,8 +739,9 @@ */ protected void updateDocComment() { - // Set inherited positions + // Set positions this.docComment.inheritedPositions = this.inheritedPositions; + this.docComment.valuePositions = this.validValuePositions != -1 ? this.validValuePositions : this.invalidValuePositions; // Set return node if present if (this.returnStatement != null) { #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java,v retrieving revision 1.28 diff -u -r1.28 JavadocBugsTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 10 Nov 2006 17:40:03 -0000 1.28 +++ src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 17 Nov 2006 16:07:19 -0000 @@ -2900,36 +2900,91 @@ } /** - * Bug 70892: [1.5][Javadoc] Compiler should parse reference for inline tag @value - * @see 70892 - * These two tests should pass whatever the source level... + * @bug 70892: [1.5][Javadoc] Compiler should parse reference for inline tag @value + * @test Ensure that reference in tag {@value} is only verified when source level >= 1.5 + * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=70892" */ - public void testBug70892conform1() { - runConformTest( - new String[] { - "X.java", - "/**\n" + - " * {@value}\n" + - " * {@value }\n" + - " * {@value #field}\n" + - " */\n" + - "public class X {\n" + - " static int field;\n" + - "}\n" - } - ); - } - public void testBug70892conform2() { + public void testBug70892a() { runConformTest( new String[] { "X.java", "public class X {\n" + - " /**{@value #field}*/\n" + - " static int field;\n" + - "}\n" + " /**\n" + + " * {@value}\n" + + " */\n" + + " static int field1;\n" + + " /**\n" + + " * {@value }\n" + + " */\n" + + " static int field2;\n" + + " /**\n" + + " * {@value #field}\n" + + " */\n" + + " static int field;\n" + + "}\n" } ); } + public void testBug70892b() { + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " /**\n" + + " * {@value \"invalid\"}\n" + + " */\n" + + " final static int field1 = 1;\n" + + " /**\n" + + " * {@value invalid} invalid\n" + + " */\n" + + " final static int field2 = 2;\n" + + " /**\n" + + " * {@value #field}\n" + + " */\n" + + " final static int field3 = 3;\n" + + " /**\n" + + " * {@value #foo}\n" + + " */\n" + + " final static int field4 = 4;\n" + + " /**\n" + + " * {@value #foo()}\n" + + " */\n" + + " final static int field5 = 5;\n" + + " void foo() {}\n" + + "}\n" + }; + if (this.complianceLevel.equals(COMPLIANCE_1_3) || this.complianceLevel.equals(COMPLIANCE_1_4)) { + runConformTest(testFiles); + } else { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 3)\r\n" + + " * {@value \"invalid\"}\r\n" + + " ^^^^^^^^^\n" + + "Javadoc: Only static field reference is allowed for @value tag\n" + + "----------\n" + + "2. ERROR in X.java (at line 7)\r\n" + + " * {@value invalid} invalid\r\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Javadoc: Only static field reference is allowed for @value tag\n" + + "----------\n" + + "3. ERROR in X.java (at line 11)\r\n" + + " * {@value #field}\r\n" + + " ^^^^^\n" + + "Javadoc: field cannot be resolved or is not a field\n" + + "----------\n" + + "4. ERROR in X.java (at line 15)\r\n" + + " * {@value #foo}\r\n" + + " ^^^\n" + + "Javadoc: Only static field reference is allowed for @value tag\n" + + "----------\n" + + "5. ERROR in X.java (at line 19)\r\n" + + " * {@value #foo()}\r\n" + + " ^^^^^\n" + + "Javadoc: Only static field reference is allowed for @value tag\n" + + "----------\n" + ); + } + } /** * Bug 73348: [Javadoc] Missing description for return tag is not always warned @@ -4815,4 +4870,180 @@ "----------\n" ); } + + /** + * @bug 153399: [javadoc] JDT Core should warn if the @value tag is not used correctly + * @test Ensure that {@value} tag is well warned when not used correctly + * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=153399" + */ + public void testBug153399a() { + String[] testFiles = new String[] { + "X.java", + "public class X { \n" + + " /**\n" + + " * {@value #MY_VALUE}\n" + + " */\n" + + " public final static int MY_VALUE = 0; \n" + + " /**\n" + + " * {@value #MY_VALUE}\n" + + " */\n" + + " public void foo() {}\n" + + " /**\n" + + " * {@value #MY_VALUE}\n" + + " */\n" + + " class Sub {} \n" + + "}\n" + }; + if (complianceLevel.equals(COMPLIANCE_1_3) || complianceLevel.equals(COMPLIANCE_1_4)) { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " * {@value #MY_VALUE}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " * {@value #MY_VALUE}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + ); + } else { + runConformTest(testFiles); + } + } + public void testBug153399b() { + String[] testFiles = new String[] { + "X.java", + "public class X { \n" + + " /**\n" + + " * {@value}\n" + + " */\n" + + " public final static int MY_VALUE = 0; \n" + + " /**\n" + + " * {@value}\n" + + " */\n" + + " public void foo() {}\n" + + " /**\n" + + " * {@value}\n" + + " */\n" + + " class Sub {} \n" + + "}\n" + }; + if (complianceLevel.equals(COMPLIANCE_1_3) || complianceLevel.equals(COMPLIANCE_1_4)) { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " * {@value}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " * {@value}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + ); + } else { + runConformTest(testFiles); + } + } + public void testBug153399c() { + String[] testFiles = new String[] { + "p1/X.java", + "package p1;\n" + + "public class X {\n" + + " /**\n" + + " * @return a\n" + + " */\n" + + " boolean get() {\n" + + " return false;\n" + + " }\n" + + "}\n" + }; + runConformTest(testFiles); + } + public void testBug153399d() { + String[] testFiles = new String[] { + "X.java", + "public class X { \n" + + " /**\n" + + " * {@value #MY_VALUE}\n" + + " * {@value}\n" + + " * {@value Invalid}\n" + + " */\n" + + " public final static int MY_VALUE = 0; \n" + + "}\n" + }; + if (complianceLevel.equals(COMPLIANCE_1_3) || complianceLevel.equals(COMPLIANCE_1_4)) { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " * {@value #MY_VALUE}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " * {@value}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + ); + } else { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " * {@value}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " * {@value Invalid}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + + "3. ERROR in X.java (at line 5)\n" + + " * {@value Invalid}\n" + + " ^^^^^^^^\n" + + "Javadoc: Invalid reference\n" + + "----------\n" + ); + } + } + public void testBug153399e() { + String[] testFiles = new String[] { + "X.java", + "public class X { \n" + + " /**\n" + + " * {@value Invalid}\n" + + " * {@value #MY_VALUE}\n" + + " */\n" + + " public final static int MY_VALUE = 0; \n" + + "}\n" + }; + if (complianceLevel.equals(COMPLIANCE_1_3) || complianceLevel.equals(COMPLIANCE_1_4)) { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " * {@value Invalid}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + ); + } else { + runNegativeTest(testFiles, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " * {@value Invalid}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected duplicated tag @value\n" + + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " * {@value Invalid}\n" + + " ^^^^^^^^\n" + + "Javadoc: Invalid reference\n" + + "----------\n" + ); + } + } } Index: src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_4.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_4.java,v retrieving revision 1.28 diff -u -r1.28 JavadocTest_1_4.java --- src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_4.java 4 Jul 2006 10:03:46 -0000 1.28 +++ src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_4.java 17 Nov 2006 16:07:21 -0000 @@ -82,55 +82,6 @@ this.reportMissingJavadocComments = CompilerOptions.IGNORE; } - /** - * Test fix for bug 70892: [1.5][Javadoc] Compiler should parse reference for inline tag @value - * @see 70892 - * These two tests pass for 1.3 or 1.4 source level but should fail for 1.5 - * @see JavadocTest_1_5 - */ - public void test001() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - reportMissingJavadocComments = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid\"}\n" + - " * {@value invalid} invalid\n" + - " * {@value #field}\n" + - " * {@value #foo}\n" + - " * {@value #foo()}\n" + - " */\n" + - "public class X {\n" + - " int field;\n" + - " void foo() {}\n" + - "}\n" - }, - "" // No failure in fact... - ); - } - public void test002() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - reportMissingJavadocComments = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid}\n" + - " * {@value invalid70892 - * These two tests pass for 1.3 or 1.4 source level but should fail for 1.5 - * @see JavadocTest_1_5 - */ - public void test001() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - reportMissingJavadocComments = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid\"}\n" + - " * {@value invalid} invalid\n" + - " * {@value #field}\n" + - " * {@value #foo}\n" + - " * {@value #foo()}\n" + - " */\n" + - "public class X {\n" + - " int field;\n" + - " void foo() {}\n" + - "}\n" - }, - "" // No failure in fact... - ); - } - public void test002() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - reportMissingJavadocComments = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid}\n" + - " * {@value invalid70892 - * These two tests fail for 1.5 source level but should pass for 1.3 or 1.4 - * @see JavadocTest_1_4 - */ - public void test001() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid\"}\n" + - " * {@value invalid} invalid\n" + - " * {@value #field}\n" + - " * {@value #foo}\n" + - " * {@value #foo()}\n" + - " */\n" + - "public class X {\n" + - " int field;\n" + - " void foo() {}\n" + - "}\n" - }, - "----------\n" + - "1. ERROR in X.java (at line 2)\n" + - " * {@value \"invalid\"}\n" + - " ^^^^^^^^^\n" + - "Javadoc: Only static field reference is allowed for @value tag\n" + - "----------\n" + - "2. ERROR in X.java (at line 3)\n" + - " * {@value invalid} invalid\n" + - " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Javadoc: Only static field reference is allowed for @value tag\n" + - "----------\n" + - "3. ERROR in X.java (at line 4)\n" + - " * {@value #field}\n" + - " ^^^^^\n" + - "Javadoc: Only static field reference is allowed for @value tag\n" + - "----------\n" + - "4. ERROR in X.java (at line 5)\n" + - " * {@value #foo}\n" + - " ^^^\n" + - "Javadoc: Only static field reference is allowed for @value tag\n" + - "----------\n" + - "5. ERROR in X.java (at line 6)\n" + - " * {@value #foo()}\n" + - " ^^^^^\n" + - "Javadoc: Only static field reference is allowed for @value tag\n" + - "----------\n" - ); - } - public void test002() { - reportMissingJavadocTags = CompilerOptions.IGNORE; - runNegativeTest( - new String[] { - "X.java", - "/**\n" + - " * {@value \"invalid}\n" + - " * {@value invalidinvalid70891 * These two tests fail for 1.5 source level but should pass for 1.3 or 1.4