8025272: doclint needs to check for valid usage of @value tag
Reviewed-by: bpatel
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Sep 24 10:51:28 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Sep 24 11:46:25 2013 -0700
@@ -44,6 +44,7 @@
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
+import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic.Kind;
@@ -822,10 +823,33 @@
@Override
public Void visitValue(ValueTree tree, Void ignore) {
+ ReferenceTree ref = tree.getReference();
+ if (ref == null || ref.getSignature().isEmpty()) {
+ if (!isConstant(env.currElement))
+ env.messages.error(REFERENCE, tree, "dc.value.not.allowed.here");
+ } else {
+ Element e = env.trees.getElement(new DocTreePath(getCurrentPath(), ref));
+ if (!isConstant(e))
+ env.messages.error(REFERENCE, tree, "dc.value.not.a.constant");
+ }
+
markEnclosingTag(Flag.HAS_INLINE_TAG);
return super.visitValue(tree, ignore);
}
+ private boolean isConstant(Element e) {
+ if (e == null)
+ return false;
+
+ switch (e.getKind()) {
+ case FIELD:
+ Object value = ((VariableElement) e).getConstantValue();
+ return (value != null); // can't distinguish "not a constant" from "constant is null"
+ default:
+ return false;
+ }
+ }
+
@Override
public Void visitVersion(VersionTree tree, Void ignore) {
warnIfEmpty(tree, tree.getBody());
--- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Tue Sep 24 10:51:28 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Tue Sep 24 11:46:25 2013 -0700
@@ -68,6 +68,8 @@
dc.tag.unknown = unknown tag: {0}
dc.text.not.allowed = text not allowed in <{0}> element
dc.unexpected.comment=documentation comment not expected here
+dc.value.not.allowed.here='{@value}' not allowed here
+dc.value.not.a.constant=value does not refer to a constant
dc.main.ioerror=IO error: {0}
dc.main.no.files.given=No files given
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/ValueTest.java Tue Sep 24 11:46:25 2013 -0700
@@ -0,0 +1,67 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8025272
+ * @summary doclint needs to check for valid usage of at-value tag
+ * @build DocLintTester
+ * @run main DocLintTester -ref ValueTest.out ValueTest.java
+ */
+
+/** */
+public class ValueTest {
+ /*
+ * Tests for {@value} without a reference
+ */
+
+ /** valid: {@value} */
+ public static final boolean cBoolean = false;
+
+ /** valid: {@value} */
+ public static final byte cByte = 0;
+
+ /** valid: {@value} */
+ public static final short cShort = 0;
+
+ /** valid: {@value} */
+ public static final int cInt = 0;
+
+ /** valid: {@value} */
+ public static final long cLong = 0L;
+
+ /** valid: {@value} */
+ public static final float cFloat = 0.0f;
+
+ /** valid: {@value} */
+ public static final double cDouble = 0.0;
+
+ /** valid: {@value} */
+ public static final String cString = "";
+
+ /** invalid class C: {@value} */
+ public class C { }
+
+ /** invalid enum E: {@value} */
+ public enum E {
+ /** invalid enum constant E1: {@value} */
+ E1
+ }
+
+ /** invalid field 1: {@value} */
+ public int f1;
+
+ /** invalid field 2: {@value} */
+ public int f2 = 3;
+
+
+ /*
+ * Tests for {@value} with a reference
+ */
+
+ /** valid: {@value Integer#SIZE} */
+ public int intRef;
+
+ /** invalid method: {@value Object#toString} */
+ public int badMethod;
+
+ /** invalid enum constant: {@value Thread.State#NEW} */
+ public int badEnum;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/ValueTest.out Tue Sep 24 11:46:25 2013 -0700
@@ -0,0 +1,22 @@
+ValueTest.java:39: error: {@value} not allowed here
+ /** invalid class C: {@value} */
+ ^
+ValueTest.java:42: error: {@value} not allowed here
+ /** invalid enum E: {@value} */
+ ^
+ValueTest.java:44: error: {@value} not allowed here
+ /** invalid enum constant E1: {@value} */
+ ^
+ValueTest.java:48: error: {@value} not allowed here
+ /** invalid field 1: {@value} */
+ ^
+ValueTest.java:51: error: {@value} not allowed here
+ /** invalid field 2: {@value} */
+ ^
+ValueTest.java:62: error: value does not refer to a constant
+ /** invalid method: {@value Object#toString} */
+ ^
+ValueTest.java:65: error: value does not refer to a constant
+ /** invalid enum constant: {@value Thread.State#NEW} */
+ ^
+7 errors