### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core 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.75 diff -u -r1.75 AbstractCommentParser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 15 May 2008 17:45:49 -0000 1.75 +++ compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 20 Jun 2008 10:04:24 -0000 @@ -1005,74 +1005,94 @@ this.identifierPtr = -1; this.identifierLengthPtr = -1; } - + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=233428 + boolean tokenizeWhiteSpace = this.scanner.tokenizeWhiteSpace; // remember current whitespace policy + int dotEndPosition = -1; + // Scan tokens int primitiveToken = -1; int parserKind = this.kind & PARSER_KIND; - nextToken : for (int iToken = 0; ; iToken++) { - int token = readTokenSafely(); - switch (token) { - case TerminalTokens.TokenNameIdentifier : - if (((iToken & 1) != 0)) { // identifiers must be odd tokens + try { + nextToken : for (int iToken = 0; ; iToken++) { + int token = readTokenSafely(); + switch (token) { + case TerminalTokens.TokenNameIdentifier : + if (((iToken & 1) != 0)) { // identifiers must be odd tokens + break nextToken; + } + pushIdentifier(iToken == 0, false); + consumeToken(); + if (iToken == 0) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=233428 + // tokenize whitespaces after first identifier + this.scanner.tokenizeWhiteSpace = parserKind != COMPLETION_PARSER && parserKind != TEXT_VERIF && // filter on parsers + (this.tagValue == TAG_SEE_VALUE || this.tagValue == TAG_LINK_VALUE); // filter on tags + } + break; + + case TerminalTokens.TokenNameDOT : + if ((iToken & 1) == 0) { // dots must be even tokens + throw new InvalidInputException(); + } + dotEndPosition = this.scanner.currentPosition; + consumeToken(); + break; + + case TerminalTokens.TokenNamevoid : + case TerminalTokens.TokenNameboolean : + case TerminalTokens.TokenNamebyte : + case TerminalTokens.TokenNamechar : + case TerminalTokens.TokenNamedouble : + case TerminalTokens.TokenNamefloat : + case TerminalTokens.TokenNameint : + case TerminalTokens.TokenNamelong : + case TerminalTokens.TokenNameshort : + if (iToken > 0) { + throw new InvalidInputException(); + } + pushIdentifier(true, false); + primitiveToken = token; + consumeToken(); break nextToken; - } - pushIdentifier(iToken == 0, false); - consumeToken(); - break; - - case TerminalTokens.TokenNameDOT : - if ((iToken & 1) == 0) { // dots must be even tokens - throw new InvalidInputException(); - } - consumeToken(); - break; - - case TerminalTokens.TokenNamevoid : - case TerminalTokens.TokenNameboolean : - case TerminalTokens.TokenNamebyte : - case TerminalTokens.TokenNamechar : - case TerminalTokens.TokenNamedouble : - case TerminalTokens.TokenNamefloat : - case TerminalTokens.TokenNameint : - case TerminalTokens.TokenNamelong : - case TerminalTokens.TokenNameshort : - if (iToken > 0) { - throw new InvalidInputException(); - } - pushIdentifier(true, false); - primitiveToken = token; - consumeToken(); - break nextToken; - - default : - if (iToken == 0) { - if (this.identifierPtr>=0) { - this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; + + default : + if (iToken == 0) { + if (this.identifierPtr>=0) { + this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; + } + return null; } - return null; - } - if ((iToken & 1) == 0) { // cannot leave on a dot - switch (parserKind) { - case COMPLETION_PARSER: - if (this.identifierPtr>=0) { - this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; - } - return syntaxRecoverQualifiedName(primitiveToken); - case DOM_PARSER: - if (this.currentTokenType != -1) { - // Reset position: we want to rescan last token - this.index = this.tokenPreviousPosition; - this.scanner.currentPosition = this.tokenPreviousPosition; - this.currentTokenType = -1; - } - // fall through default case to raise exception - default: - throw new InvalidInputException(); + if ((iToken & 1) == 0) { // cannot leave on a dot + switch (parserKind) { + case COMPLETION_PARSER: + if (this.identifierPtr>=0) { + this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; + } + return syntaxRecoverQualifiedName(primitiveToken); + case DOM_PARSER: + if (this.currentTokenType != -1) { + // Reset position: we want to rescan last token + this.index = this.tokenPreviousPosition; + this.scanner.currentPosition = this.tokenPreviousPosition; + this.currentTokenType = -1; + } + // fall through default case to raise exception + default: + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=233428 + // set the correct position before throwing the exception + if (this.scanner.tokenizeWhiteSpace) this.scanner.currentPosition = dotEndPosition; + throw new InvalidInputException(); + } } - } - break nextToken; + break nextToken; + } } } + finally { + // recover whitespace policy + this.scanner.tokenizeWhiteSpace = tokenizeWhiteSpace; + } // Reset position: we want to rescan last token if (parserKind != COMPLETION_PARSER && this.currentTokenType != -1) { this.index = this.tokenPreviousPosition; @@ -1158,6 +1178,9 @@ case TerminalTokens.TokenNameIdentifier : if (typeRef == null) { typeRefStartPosition = this.scanner.getCurrentTokenStartPosition(); + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=233428 + // update current position before parsing the qualified name + currentPosition = typeRefStartPosition; typeRef = parseQualifiedName(true); if (this.abort) return false; // May be aborted by specialized parser break; #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.45 diff -u -r1.45 JavadocBugsTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 6 Jun 2008 06:48:50 -0000 1.45 +++ src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java 20 Jun 2008 10:04:26 -0000 @@ -1865,12 +1865,12 @@ new String[] { "Test.java", "/**\n" + - " * Comment with no error: {@link java.lang.\n" + - " * Object valid} because it\'s not on first line\n" + + " * Comment with no error: {@link java.lang.Object\n" + + " * valid} because it\'s not on first line\n" + " */\n" + "public class Test {\n" + - " /** Comment previously with error: {@link java.lang.\n" + - " * Object valid} because tag is on comment very first line\n" + + " /** Comment previously with error: {@link java.lang.Object\n" + + " * valid} because tag is on comment very first line\n" + " */\n" + " void foo() {}\n" + "}\n" @@ -7414,4 +7414,166 @@ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError ); } + /** + * @bug 233428: [javadoc] syntax of qualified references in @see and @link tags + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=233428" + */ + public void testBug233428a() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * Sample invalid link {@link java.lang. String label}\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + runConformTest(true, units, + "----------\n" + + "1. WARNING in pkg\\X.java (at line 5)\n" + + " * Sample invalid link {@link java.lang. String label}\n" + + " ^^^^^^^^^^\n" + + "Javadoc: Invalid reference\n" + + "----------\n", + null, null, + JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings); + } + public void testBug233428b() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * Sample invalid link {@link java.lang. String label}\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + // expect no warning when not validation is off + reportInvalidJavadoc = CompilerOptions.IGNORE; + runConformTest(units); + } + public void testBug233428c() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * Sample valid link {@link java.lang.String label}\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + // no warning expected: valid link + runConformTest(units); + } + public void testBug233428d() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * @see java.lang. String label\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + runConformTest(true, units, + "----------\n" + + "1. WARNING in pkg\\X.java (at line 5)\n" + + " * @see java.lang. String label\n" + + " ^^^^^^^^^^\n" + + "Javadoc: Invalid reference\n" + + "----------\n", + null, null, + JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings); + } + public void testBug233428e() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * @see java.lang. String label\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.IGNORE; + // expect no warning when not validation is off + runConformTest(units); + } + public void testBug233428f() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * @see java.lang.String label\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + // no warning expected: valid link + runConformTest(units); + } + public void testBug233428g() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * @throws java.lang. Exception\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + // no warning expected: valid link + runConformTest(units); + } + public void testBug233428h() { + String[] units = new String[] { + "pkg/X.java", + "package pkg;\n" + + "\n" + + "public class X {\n" + + " /**\n" + + " * @see java.lang .String label\n" + + " */\n" + + " public void foo() { \n" + + " \n" + + " }\n" + + "}\n" + }; + reportInvalidJavadoc = CompilerOptions.WARNING; + // valid syntax : java.lang .String + runConformTest(units); + } } \ No newline at end of file