### Eclipse Workspace Patch 1.0 #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.60 diff -u -r1.60 JavadocBugsTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 24 Mar 2009 08:51:00 -0000 1.60 +++ src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 12 Apr 2009 17:41:15 -0000 @@ -3318,23 +3318,33 @@ * @see 73995 */ public void testBug73995() { - runConformTest( + runNegativeTest( new String[] { "X.java", - "public class X {\n" + + "public class X extends Base {\n" + " /**\n" + " * @return {@link Object} \n" + " */\n" + " public int foo1() {return 0; }\n" + - " /** @return {@inheritedDoc} */\n" + + " /** @return {@inheritDoc} */\n" + " public int foo2() {return 0; }\n" + " /**\n" + " * @return\n" + " * {@unknown_tag}\n" + " */\n" + " public int foo3() {return 0; }\n" + - "}\n" - } + "}\n" + + "class Base {\n" + + "/** return \"The foo2 value\" */" + + "public int foo2(){return 0;}\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " * {@unknown_tag}\n" + + " ^^^^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" ); } @@ -8487,4 +8497,122 @@ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError ); } +/** + * @bug 267833:[javadoc] Custom tags should not be allowed for inline tags + * @test Ensure that a warning is raised when customs tags are used as inline tags + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=267833" + */ +public void testBug267833() { + runNegativeTest( + new String[] { + "X.java", + "/**\n" + + "* Invalid custom tag {@custom \"Invalid\"} \n" + + "* @custom \"Valid\"\n" + + "*/\n" + + "public class X {\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 2)\n" + + " * Invalid custom tag {@custom \"Invalid\"} \n" + + " ^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + ); +} +/** + * Additional test for bug 267833 + * @test Ensure that a warning is raised when block tags are used as inline tags. + */ +public void testBug267833_2() { + runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + "/** \n" + + "* Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + "* and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + "* and more {@since 1.0}, {@serial 0L}, {@serialData data}, {@serialField field}" + + "* @param i\n" + + "* @return value\n" + + "* @throws NullPointerException \n" + + "*/\n" + + "public int foo(int i) {\n" + + " return 0;\n" + + "}\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " * Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + " ^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " * Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + " ^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "3. ERROR in X.java (at line 3)\n" + + " * Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "4. ERROR in X.java (at line 3)\n" + + " * Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "5. ERROR in X.java (at line 3)\n" + + " * Description {@see value} , {@return value}, {@since value}, {@param i}, {@throws NullPointerException}\n" + + " ^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "6. ERROR in X.java (at line 4)\n" + + " * and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + " ^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "7. ERROR in X.java (at line 4)\n" + + " * and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + " ^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "8. ERROR in X.java (at line 4)\n" + + " * and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + " ^^^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "9. ERROR in X.java (at line 4)\n" + + " * and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + " ^^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "10. ERROR in X.java (at line 4)\n" + + " * and more {@author jay}, {@category cat}, {@deprecated}, {@exception Exception}, {@version 1.1}\n" + + " ^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "11. ERROR in X.java (at line 5)\n" + + " * and more {@since 1.0}, {@serial 0L}, {@serialData data}, {@serialField field}* @param i\n" + + " ^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "12. ERROR in X.java (at line 5)\n" + + " * and more {@since 1.0}, {@serial 0L}, {@serialData data}, {@serialField field}* @param i\n" + + " ^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "13. ERROR in X.java (at line 5)\n" + + " * and more {@since 1.0}, {@serial 0L}, {@serialData data}, {@serialField field}* @param i\n" + + " ^^^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n" + + "14. ERROR in X.java (at line 5)\n" + + " * and more {@since 1.0}, {@serial 0L}, {@serialData data}, {@serialField field}* @param i\n" + + " ^^^^^^^^^^^\n" + + "Javadoc: Unexpected tag\n" + + "----------\n"); +} + } \ No newline at end of file #P org.eclipse.jdt.core 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.77 diff -u -r1.77 JavadocParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 24 Mar 2009 08:51:02 -0000 1.77 +++ compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 12 Apr 2009 17:41:55 -0000 @@ -508,13 +508,13 @@ boolean valid = false; switch (firstChar) { case 'a': - if (length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName, 0, length)) { this.tagValue = TAG_AUTHOR_VALUE; this.tagWaitingForDescription = this.tagValue; } break; case 'c': - if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName, 0, length)) { this.tagValue = TAG_CATEGORY_VALUE; valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec } else if (length == TAG_CODE_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_CODE, tagName, 0, length)) { @@ -523,7 +523,7 @@ } break; case 'd': - if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName, 0, length)) { this.deprecated = true; valid = true; this.tagValue = TAG_DEPRECATED_VALUE; @@ -536,7 +536,7 @@ } break; case 'e': - if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName, 0, length)) { this.tagValue = TAG_EXCEPTION_VALUE; valid = parseThrows(); } @@ -595,46 +595,39 @@ } break; case 'p': - if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName, 0, length)) { this.tagValue = TAG_PARAM_VALUE; valid = parseParam(); } break; case 'r': - if (length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName, 0, length)) { this.tagValue = TAG_RETURN_VALUE; valid = parseReturn(); } break; case 's': - if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName, 0, length)) { - if (this.inlineTagStarted) { - // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290 - // Cannot have @see inside inline comment - valid = false; - if (this.reportProblems) { - this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); - } - } else { + if (!this.inlineTagStarted) { + if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName, 0, length)) { this.tagValue = TAG_SEE_VALUE; valid = parseReference(); - } - } else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName, 0, length)) { - this.tagValue = TAG_SERIAL_VALUE; - this.tagWaitingForDescription = this.tagValue; - } else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName, 0, length)) { - this.tagValue = TAG_SERIAL_DATA_VALUE; - this.tagWaitingForDescription = this.tagValue; - } else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName, 0, length)) { - this.tagValue = TAG_SERIAL_FIELD_VALUE; - this.tagWaitingForDescription = this.tagValue; - } else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) { - this.tagValue = TAG_SINCE_VALUE; - this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName, 0, length)) { + this.tagValue = TAG_SERIAL_VALUE; + this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName, 0, length)) { + this.tagValue = TAG_SERIAL_DATA_VALUE; + this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName, 0, length)) { + this.tagValue = TAG_SERIAL_FIELD_VALUE; + this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) { + this.tagValue = TAG_SINCE_VALUE; + this.tagWaitingForDescription = this.tagValue; + } } break; case 't': - if (length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName, 0, length)) { + if (!this.inlineTagStarted && length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName, 0, length)) { this.tagValue = TAG_THROWS_VALUE; valid = parseThrows(); } @@ -664,7 +657,7 @@ if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); } } - } else if (length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName, 0, length)) { + } else if (!this.inlineTagStarted && length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName, 0, length)) { this.tagValue = TAG_VERSION_VALUE; this.tagWaitingForDescription = this.tagValue; } else { @@ -679,6 +672,10 @@ if (this.tagValue != TAG_OTHERS_VALUE && !this.inlineTagStarted) { this.lastBlockTagValue = this.tagValue; } + if (this.inlineTagStarted && this.reportProblems + && (this.tagValue >= JAVADOC_TAG_TYPE.length || JAVADOC_TAG_TYPE[this.tagValue] != TAG_TYPE_INLINE)) { + this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); + } return valid; } Index: compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java,v retrieving revision 1.88 diff -u -r1.88 AbstractCommentParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 24 Mar 2009 08:51:03 -0000 1.88 +++ compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 12 Apr 2009 17:41:48 -0000 @@ -40,6 +40,38 @@ protected final static int ARGUMENT_TYPE_RECOVERY = 3; protected final static int EMPTY_ARGUMENT_RECOVERY = 4; + public static short[] JAVADOC_TAG_TYPE = {}; + + static { + JAVADOC_TAG_TYPE = new short[TAG_NAMES.length]; + nextTag:for (short index=0; index < JAVADOC_TAG_TYPE.length; index++) { + char[] tagName = TAG_NAMES[index]; + for (short i=0; i < BLOCK_TAGS.length; i++) { + for (short j=0; j < BLOCK_TAGS[i].length; j++) { + // Compare the string here + if ((tagName.length > 0 && BLOCK_TAGS[i][j].length > 0) && tagName[0] == BLOCK_TAGS[i][j][0] + && tagName.length == BLOCK_TAGS[i][j].length + && CharOperation.equals(BLOCK_TAGS[i][j], tagName)) { + JAVADOC_TAG_TYPE[index] = TAG_TYPE_BLOCK; + continue nextTag; + } + } + } + for (short i=0; i < INLINE_TAGS.length; i++) { + for (short j=0; j < INLINE_TAGS[i].length; j++) { + // Compare the string here + if ((tagName.length > 0 && INLINE_TAGS[i][j].length > 0) && tagName[0] == INLINE_TAGS[i][j][0] + && tagName.length == INLINE_TAGS[i][j].length + && CharOperation.equals(INLINE_TAGS[i][j], tagName)) { + JAVADOC_TAG_TYPE[index] = TAG_TYPE_INLINE; + continue nextTag; + } + } + } + JAVADOC_TAG_TYPE[index] = TAG_TYPE_NONE; + } + } + // Parse infos public Scanner scanner; public char[] source; Index: compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java,v retrieving revision 1.18 diff -u -r1.18 JavadocTagConstants.java --- compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java 2 Sep 2008 08:09:13 -0000 1.18 +++ compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java 12 Apr 2009 17:41:55 -0000 @@ -170,6 +170,10 @@ public final static int BLOCK_TAGS_LENGTH = BLOCK_TAGS.length; public final static int ALL_TAGS_LENGTH = BLOCK_TAGS_LENGTH+INLINE_TAGS_LENGTH; + public final static short TAG_TYPE_NONE = 0; + public final static short TAG_TYPE_INLINE = 1; + public final static short TAG_TYPE_BLOCK = 2; + /* * Tags usage */