HEAD - 247037 (Srikanth's fix)
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java
index de31e7a..4ba32ae 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocBugsTest.java
@@ -1729,9 +1729,12 @@
* Bug 51606: [Javadoc] Compiler should complain when tag name is not correct
* @see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51606">51606</a>
*/
+// Cleaned up this test as part of fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037
+// We should not complain about the missing @param tag for Y.foo at all, since the comments are
+// automatically inherited.
public void testBug51606() {
this.reportMissingJavadocTags = CompilerOptions.ERROR;
- runNegativeTest(
+ runConformTest(
new String[] {
"X.java",
"public class X {\n" +
@@ -1751,13 +1754,7 @@
" }\n" +
"}\n"
},
- "----------\n" +
- "1. ERROR in Y.java (at line 5)\n" +
- " public void foo(int a, int b) {\n" +
- " ^\n" +
- "Javadoc: Missing tag for parameter b\n" +
- "----------\n",
- JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
+ ""
);
}
public void testBug51606a() {
@@ -8321,4 +8318,173 @@
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, make sure that we complain when @inheritdoc
+// is used where it is outlawed by the specs. This test verifies that we complain when @inheritDoc
+// is used with classes and interfaces.
+public void testBug247037() {
+ this.reportMissingJavadocTags = CompilerOptions.ERROR;
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "/**\n" +
+ " * {@inheritDoc}\n" + // error, cannot be applied to a class
+ " */\n" +
+ "public class X {\n" +
+ "}\n" +
+ "/**\n" +
+ " * {@inheritDoc}\n" + // error, cannot be applied to interfaces.
+ " */" +
+ "interface Blah {\n" +
+ " void BlahBlah();\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " * {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 7)\n" +
+ " * {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n",
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
+ );
+}
+
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, make sure that we complain when @inheritdoc
+//is used where it is outlawed by the specs. Here we test that when @inheritDoc is applied to a
+// field or constructor, we complain.
+public void testBug247037b() {
+ this.reportMissingJavadocTags = CompilerOptions.ERROR;
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " /**\n" +
+ " * {@inheritDoc}\n" + // error, cannot be applied to a field
+ " */\n" +
+ " public int field = 10;\n" +
+ " /**\n" +
+ " * @param x {@inheritDoc}\n" + // error, cannot be applied to a constructor
+ " */\n" +
+ " Y(int x) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " * {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " * @param x {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n",
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
+ );
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, make sure that we complain when @inheritdoc
+//is used where it is outlawed by the specs. In this test we test the use of @inheritedDoc in some
+// block tags.
+public void testBug247037c() {
+ this.reportMissingJavadocTags = CompilerOptions.ERROR;
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " /**\n" +
+ " * @since 1.0\n" +
+ " * @return Blah\n" +
+ " * @param blah Blah Blah\n" +
+ " * @throws Exception When something is wrong\n" +
+ " */\n" +
+ " public int m(int blah) throws Exception {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " /**\n" +
+ " * @param blah {@inheritDoc}\n" +
+ " * @return {@inheritDoc}\n" +
+ " * @since {@inheritDoc}\n" + // error, cannot be used in @since
+ " * @author {@inheritDoc}\n" + // error, cannot be used in @author
+ " * @see {@inheritDoc}\n" + // error, cannot be used in @see
+ " * @throws Exception {@inheritDoc}\n" +
+ " * @exception Exception {@inheritDoc}\n" +
+ " */\n" +
+ " public int m(int blah) throws Exception {\n" +
+ " return 1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 16)\n" +
+ " * @since {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 17)\n" +
+ " * @author {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 18)\n" +
+ " * @see {@inheritDoc}\n" +
+ " ^^^\n" +
+ "Javadoc: Missing reference\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 18)\n" +
+ " * @see {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n",
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
+ );
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, make sure that we complain when @inheritdoc
+// is used where it is outlawed by the specs. Test to verify that every bad use of @inheritDoc triggers
+// a message from the compiler
+public void testBug247037d() {
+ this.reportMissingJavadocTags = CompilerOptions.ERROR;
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " /**\n" +
+ " * @param blah {@inheritDoc}\n" + // error n() doesn't override anything.
+ " * @return {@inheritDoc}\n" + // error, n() doesn't override anything
+ " * @author {@inheritDoc}\n" + // error, cannot be used in @author
+ " */\n" +
+ " public int n(int blah) {\n" +
+ " return 1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " * @param blah {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " * @return {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " * @author {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n",
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
+ );
+}
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_5.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_5.java
index 346960b..0ae00ef 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_5.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_1_5.java
@@ -3863,4 +3863,71 @@
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError
);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, verify that we complain about @inheritDoc
+ // being used in package level javadoc.
+ public void testBug247037a() {
+ runNegativeTest(
+ new String[] {
+ "pack/package-info.java",
+ "/**\n" +
+ " * {@inheritDoc}\n" +
+ " * @since {@inheritDoc}\n" +
+ " * @blah {@inheritDoc}\n" +
+ " */\n" +
+ "package pack;\n"
+ },
+ "----------\n" +
+ "1. ERROR in pack\\package-info.java (at line 2)\n" +
+ " * {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in pack\\package-info.java (at line 3)\n" +
+ " * @since {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "3. ERROR in pack\\package-info.java (at line 4)\n" +
+ " * @blah {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n"
+ );
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, verify that we complain about @inheritDoc
+ // being used in package level javadoc (variation)
+ public void testBug247037b() {
+ runNegativeTest(
+ new String[] {
+ "pack/package-info.java",
+ "/**\n" +
+ " * @return {@inheritDoc}\n" +
+ " * @param blah {@inheritDoc}\n" +
+ " */\n" +
+ "package pack;\n"
+ },
+ "----------\n" +
+ "1. ERROR in pack\\package-info.java (at line 2)\n" +
+ " * @return {@inheritDoc}\n" +
+ " ^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "2. ERROR in pack\\package-info.java (at line 2)\n" +
+ " * @return {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "3. ERROR in pack\\package-info.java (at line 3)\n" +
+ " * @param blah {@inheritDoc}\n" +
+ " ^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n" +
+ "4. ERROR in pack\\package-info.java (at line 3)\n" +
+ " * @param blah {@inheritDoc}\n" +
+ " ^^^^^^^^^^\n" +
+ "Javadoc: Unexpected tag\n" +
+ "----------\n"
+ );
+ }
}
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index c9f0897..40a6ca7 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -49,7 +49,9 @@
<h2>What's new in this drop</h2>
<h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244406">244406</a>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247037">247037</a>
+[javadoc] compiler should issue warning for {@inheritDoc} at illegal location
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244406">244406</a>
[buildpath] Internal jars refered with OS path are shown as non-Java resources
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269476">269476</a>
testInitJDTPlugin() seems to leak several DeltaProcessor and JavaModelManager
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index eb61408..20c88d9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -27,7 +27,7 @@
public TypeReference[] exceptionReferences; // @throws, @exception
public JavadocReturnStatement returnStatement; // @return
public Expression[] seeReferences; // @see
- public long inheritedPositions = -1;
+ public long[] inheritedPositions = null;
// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
// Store param references for tag with invalid syntax
public JavadocSingleNameReference[] invalidParameters; // @param
@@ -184,7 +184,16 @@
* Resolve type javadoc
*/
public void resolve(ClassScope scope) {
-
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc tag cannot
+ // be used in the documentation comment for a class or interface.
+ if (this.inheritedPositions != null) {
+ int length = this.inheritedPositions.length;
+ for (int i = 0; i < length; ++i) {
+ int start = (int) (this.inheritedPositions[i] >>> 32);
+ int end = (int) this.inheritedPositions[i];
+ scope.problemReporter().javadocUnexpectedTag(start, end);
+ }
+ }
// @param tags
int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
for (int i = 0; i < paramTagsSize; i++) {
@@ -303,11 +312,14 @@
}
// Store if a reference exists to an overriden method/constructor or the method is in a local type,
- boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != -1) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
- if (!overriding && this.inheritedPositions != -1) {
- int start = (int) (this.inheritedPositions >>> 32);
- int end = (int) this.inheritedPositions;
- methScope.problemReporter().javadocUnexpectedTag(start, end);
+ boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != null) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
+ if (!overriding && this.inheritedPositions != null) {
+ int length = this.inheritedPositions.length;
+ for (int i = 0; i < length; ++i) {
+ int start = (int) (this.inheritedPositions[i] >>> 32);
+ int end = (int) this.inheritedPositions[i];
+ methScope.problemReporter().javadocUnexpectedTag(start, end);
+ }
}
// @param tags
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index 0b578cb..57d4ba9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -51,9 +51,13 @@
public boolean reportProblems;
protected long complianceLevel;
protected long sourceLevel;
+
+ // Support for {@inheritDoc}
+ protected long [] inheritedPositions;
+ protected int inheritedPositionsPtr;
+ private final static int INHERITED_POSITIONS_ARRAY_INCREMENT = 4;
// Results
- protected long inheritedPositions;
protected boolean deprecated;
protected Object returnStatement;
@@ -74,6 +78,7 @@
protected boolean abort = false;
protected int kind;
protected int tagValue = NO_TAG_VALUE;
+ protected int lastBlockTagValue = NO_TAG_VALUE;
// Line pointers
private int linePtr, lastLinePtr;
@@ -129,7 +134,8 @@
this.inlineTagStart = -1;
this.lineStarted = false;
this.returnStatement = null;
- this.inheritedPositions = -1;
+ this.inheritedPositions = null;
+ this.lastBlockTagValue = NO_TAG_VALUE;
this.deprecated = false;
this.lastLinePtr = getLineNumber(this.javadocEnd);
this.textStart = -1;
@@ -1467,6 +1473,21 @@
return token;
}
+ protected void recordInheritedPosition(long position) {
+ if (this.inheritedPositions == null) {
+ this.inheritedPositions = new long[INHERITED_POSITIONS_ARRAY_INCREMENT];
+ this.inheritedPositionsPtr = 0;
+ } else {
+ if (this.inheritedPositionsPtr == this.inheritedPositions.length) {
+ System.arraycopy(
+ this.inheritedPositions, 0,
+ this.inheritedPositions = new long[this.inheritedPositionsPtr + INHERITED_POSITIONS_ARRAY_INCREMENT], 0,
+ this.inheritedPositionsPtr);
+ }
+ }
+ this.inheritedPositions[this.inheritedPositionsPtr++] = position;
+ }
+
/*
* Refresh start position and length of an inline tag.
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index 19c842d..8e5b709 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -543,15 +543,26 @@
break;
case 'i':
if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName, 0, length)) {
- // inhibits inherited flag when tags have been already stored
- // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
- // Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
- // was encountered in comment. But it cannot be the case for COMPILER_PARSER
- // and so is enough as it is only this parser which signals the missing tag warnings...
- if (this.astPtr==-1) {
- this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc usage is illegal
+ // outside of few block tags and the main description.
+ switch (this.lastBlockTagValue) {
+ case TAG_RETURN_VALUE:
+ case TAG_THROWS_VALUE:
+ case TAG_EXCEPTION_VALUE:
+ case TAG_PARAM_VALUE:
+ case NO_TAG_VALUE: // Still in main description
+ valid = true;
+ if (this.reportProblems) {
+ recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
+ }
+ break;
+ default:
+ valid = false;
+ if (this.reportProblems) {
+ this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart,
+ this.tagSourceEnd);
+ }
}
- valid = true;
this.tagValue = TAG_INHERITDOC_VALUE;
}
break;
@@ -665,6 +676,9 @@
break;
}
this.textStart = this.index;
+ if (this.tagValue != TAG_OTHERS_VALUE && !this.inlineTagStarted) {
+ this.lastBlockTagValue = this.tagValue;
+ }
return valid;
}
@@ -860,6 +874,11 @@
this.tagWaitingForDescription = NO_TAG_VALUE;
// Set positions
+ if (this.inheritedPositions != null && this.inheritedPositionsPtr != this.inheritedPositions.length) {
+ // Compact array by shrinking.
+ System.arraycopy(this.inheritedPositions, 0,
+ this.inheritedPositions = new long[this.inheritedPositionsPtr], 0, this.inheritedPositionsPtr);
+ }
this.docComment.inheritedPositions = this.inheritedPositions;
this.docComment.valuePositions = this.validValuePositions != -1 ? this.validValuePositions : this.invalidValuePositions;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
index d6c3533..1c01cf4 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
@@ -420,13 +420,8 @@
break;
case 'i':
if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) {
- // inhibits inherited flag when tags have been already stored
- // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
- // Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
- // was encountered in comment. But it cannot be the case for COMPILER_PARSER
- // and so is enough as it is only this parser which signals the missing tag warnings...
- if (this.astPtr==-1) {
- this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+ if (this.reportProblems) {
+ recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
}
this.tagValue = TAG_INHERITDOC_VALUE;
} else {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java
index 154701b..dcdd100 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java
@@ -493,13 +493,8 @@
break;
case 'i':
if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) {
- // inhibits inherited flag when tags have been already stored
- // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
- // Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
- // was encountered in comment. But it cannot be the case for COMPILER_PARSER
- // and so is enough as it is only this parser which signals the missing tag warnings...
- if (this.astPtr==-1) {
- this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+ if (this.reportProblems) {
+ recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
}
valid = true;
this.tagValue = TAG_INHERITDOC_VALUE;