--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Sep 25 14:04:24 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Sep 25 22:26:42 2013 -0700
@@ -136,6 +136,7 @@
doclet.Groupname_already_used=In -group option, groupname already used: {0}
doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference.
doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants.
+doclet.value_tag_invalid_use=@value tag cannot be used here.
doclet.dest_dir_create=Creating destination directory: "{0}"
doclet.in={0} in {1}
doclet.Use_Table_Summary=Use table, listing {0}, and an explanation
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java Wed Sep 25 14:04:24 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java Wed Sep 25 22:26:42 2013 -0700
@@ -105,7 +105,9 @@
}
/**
- * Given the name of the field, return the corresponding FieldDoc.
+ * Given the name of the field, return the corresponding FieldDoc. Return null
+ * due to invalid use of value tag if the name is null or empty string and if
+ * the value tag is not used on a field.
*
* @param config the current configuration of the doclet.
* @param tag the value tag.
@@ -114,10 +116,8 @@
* it is assumed that the field is in the current class.
*
* @return the corresponding FieldDoc. If the name is null or empty string,
- * return field that the value tag was used in.
- *
- * @throws DocletAbortException if the value tag does not specify a name to
- * a value field and it is not used within the comments of a valid field.
+ * return field that the value tag was used in. Return null if the name is null
+ * or empty string and if the value tag is not used on a field.
*/
private FieldDoc getFieldDoc(Configuration config, Tag tag, String name) {
if (name == null || name.length() == 0) {
@@ -125,8 +125,9 @@
if (tag.holder() instanceof FieldDoc) {
return (FieldDoc) tag.holder();
} else {
- //This should never ever happen.
- throw new DocletAbortException("should not happen");
+ // If the value tag does not specify a parameter which is a valid field and
+ // it is not used within the comments of a valid field, return null.
+ return null;
}
}
StringTokenizer st = new StringTokenizer(name, "#");
@@ -165,9 +166,15 @@
FieldDoc field = getFieldDoc(
writer.configuration(), tag, tag.text());
if (field == null) {
- //Reference is unknown.
- writer.getMsgRetriever().warning(tag.holder().position(),
- "doclet.value_tag_invalid_reference", tag.text());
+ if (tag.text().isEmpty()) {
+ //Invalid use of @value
+ writer.getMsgRetriever().warning(tag.holder().position(),
+ "doclet.value_tag_invalid_use");
+ } else {
+ //Reference is unknown.
+ writer.getMsgRetriever().warning(tag.holder().position(),
+ "doclet.value_tag_invalid_reference", tag.text());
+ }
} else if (field.constantValue() != null) {
return writer.valueTagOutput(field,
field.constantValueExpression(),
--- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Wed Sep 25 14:04:24 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Wed Sep 25 22:26:42 2013 -0700
@@ -23,13 +23,12 @@
/*
* @test
- * @bug 4764045
+ * @bug 4764045 8004825
* @summary This test ensures that the value tag works in all
* use cases. The explainations for each test case are written below.
* @author jamieh
* @library ../lib/
- * @build JavadocTester
- * @build TestValueTag
+ * @build JavadocTester TestValueTag
* @run main TestValueTag
*/
@@ -41,8 +40,14 @@
//Javadoc arguments.
private static final String[] ARGS =
new String[] {
+ "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag",
+ "todo", "pkg1", "pkg2"
+ };
+
+ private static final String[] ARGS1 =
+ new String[] {
"-Xdoclint:none",
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag",
+ "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, "-tag",
"todo", "pkg1", "pkg2"
};
@@ -91,16 +96,58 @@
{BUG_ID + FS + "pkg1" + FS + "CustomTagUsage.html",
"<dt><span class=\"strong\">Todo:</span></dt>" + NL +
"<dd>the value of this constant is 55.</dd>"},
+ //Test @value errors printed dues to invalid use or when used with
+ //non-constant or with bad references.
+ {ERROR_OUTPUT,"error: value does not refer to a constant" + NL +
+ " * Result: {@value TEST_12_ERROR}"
+ },
+ {ERROR_OUTPUT,"error: {@value} not allowed here" + NL +
+ " * Result: {@value}"
+ },
+ {ERROR_OUTPUT,"error: value does not refer to a constant" + NL +
+ " * Result: {@value NULL}"
+ },
+ {ERROR_OUTPUT,"error: {@value} not allowed here" + NL +
+ " * Invalid (null): {@value}"
+ },
+ {ERROR_OUTPUT,"error: {@value} not allowed here" + NL +
+ " * Invalid (non-constant field): {@value}"
+ },
+ {ERROR_OUTPUT,"error: value does not refer to a constant" + NL +
+ " * Here is a bad value reference: {@value UnknownClass#unknownConstant}"
+ },
+ {ERROR_OUTPUT,"error: reference not found" + NL +
+ " * Here is a bad value reference: {@value UnknownClass#unknownConstant}"
+ },
+ {ERROR_OUTPUT,"error: {@value} not allowed here" + NL +
+ " * @todo the value of this constant is {@value}"
+ }
+ };
+ private static final String[][] TEST1 = {
//Test @value warning printed when used with non-constant.
{WARNING_OUTPUT,"warning - @value tag (which references nonConstant) " +
"can only be used in constants."
},
+ {WARNING_OUTPUT,"warning - @value tag (which references NULL) " +
+ "can only be used in constants."
+ },
+ {WARNING_OUTPUT,"warning - @value tag (which references TEST_12_ERROR) " +
+ "can only be used in constants."
+ },
//Test warning printed for bad reference.
{WARNING_OUTPUT,"warning - UnknownClass#unknownConstant (referenced by " +
"@value tag) is an unknown reference."
},
+ //Test warning printed for invalid use of @value.
+ {WARNING_OUTPUT,"warning - @value tag cannot be used here."
+ }
};
- private static final String[][] NEGATED_TEST = NO_TEST;
+ private static final String[][] NEGATED_TEST = {
+ //Base case: using @value on a constant.
+ {BUG_ID + FS + "pkg1" + FS + "Class1.html",
+ "Result: <a href=\"../pkg1/Class1.html#TEST_12_ERROR\">\"Test 12 " +
+ "generates an error message\"</a>"},
+ };
/**
* The entry point of the test.
@@ -109,9 +156,18 @@
public static void main(String[] args) {
TestValueTag tester = new TestValueTag();
run(tester, ARGS, TEST, NEGATED_TEST);
+ checkForException(tester);
+ run(tester, ARGS1, TEST1, NO_TEST);
+ checkForException(tester);
tester.printSummary();
}
+ public static void checkForException(TestValueTag tester) {
+ if (tester.getErrorOutput().contains("DocletAbortException")) {
+ throw new AssertionError("javadoc threw DocletAbortException");
+ }
+ }
+
/**
* {@inheritDoc}
*/
--- a/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java Wed Sep 25 14:04:24 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java Wed Sep 25 22:26:42 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,16 @@
public static final String TEST_11_PASSES = "Test 11 passes";
/**
+ * Invalid (non-constant field): {@value}
+ */
+ public static String TEST_12_ERROR = "Test 12 generates an error message";
+
+ /**
+ * Invalid (null): {@value}
+ */
+ public static final String NULL = null;
+
+ /**
* Result: {@value TEST_3_PASSES}
*/
public int field;
@@ -60,6 +70,21 @@
public void method() {}
/**
+ * Result: {@value TEST_12_ERROR}
+ */
+ public void invalidValueTag1() {}
+
+ /**
+ * Result: {@value}
+ */
+ public void invalidValueTag2() {}
+
+ /**
+ * Result: {@value NULL}
+ */
+ public void testNullConstant() {}
+
+ /**
* Result: {@value pkg1.Class1#TEST_6_PASSES}
*/
public class NestedClass{}