Wed, 25 Sep 2013 22:26:42 -0700
8004825: javadoc crash DocletAbortException
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Sep 25 14:04:24 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Sep 25 22:26:42 2013 -0700 1.3 @@ -136,6 +136,7 @@ 1.4 doclet.Groupname_already_used=In -group option, groupname already used: {0} 1.5 doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference. 1.6 doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants. 1.7 +doclet.value_tag_invalid_use=@value tag cannot be used here. 1.8 doclet.dest_dir_create=Creating destination directory: "{0}" 1.9 doclet.in={0} in {1} 1.10 doclet.Use_Table_Summary=Use table, listing {0}, and an explanation
2.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java Wed Sep 25 14:04:24 2013 -0700 2.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java Wed Sep 25 22:26:42 2013 -0700 2.3 @@ -105,7 +105,9 @@ 2.4 } 2.5 2.6 /** 2.7 - * Given the name of the field, return the corresponding FieldDoc. 2.8 + * Given the name of the field, return the corresponding FieldDoc. Return null 2.9 + * due to invalid use of value tag if the name is null or empty string and if 2.10 + * the value tag is not used on a field. 2.11 * 2.12 * @param config the current configuration of the doclet. 2.13 * @param tag the value tag. 2.14 @@ -114,10 +116,8 @@ 2.15 * it is assumed that the field is in the current class. 2.16 * 2.17 * @return the corresponding FieldDoc. If the name is null or empty string, 2.18 - * return field that the value tag was used in. 2.19 - * 2.20 - * @throws DocletAbortException if the value tag does not specify a name to 2.21 - * a value field and it is not used within the comments of a valid field. 2.22 + * return field that the value tag was used in. Return null if the name is null 2.23 + * or empty string and if the value tag is not used on a field. 2.24 */ 2.25 private FieldDoc getFieldDoc(Configuration config, Tag tag, String name) { 2.26 if (name == null || name.length() == 0) { 2.27 @@ -125,8 +125,9 @@ 2.28 if (tag.holder() instanceof FieldDoc) { 2.29 return (FieldDoc) tag.holder(); 2.30 } else { 2.31 - //This should never ever happen. 2.32 - throw new DocletAbortException("should not happen"); 2.33 + // If the value tag does not specify a parameter which is a valid field and 2.34 + // it is not used within the comments of a valid field, return null. 2.35 + return null; 2.36 } 2.37 } 2.38 StringTokenizer st = new StringTokenizer(name, "#"); 2.39 @@ -165,9 +166,15 @@ 2.40 FieldDoc field = getFieldDoc( 2.41 writer.configuration(), tag, tag.text()); 2.42 if (field == null) { 2.43 - //Reference is unknown. 2.44 - writer.getMsgRetriever().warning(tag.holder().position(), 2.45 - "doclet.value_tag_invalid_reference", tag.text()); 2.46 + if (tag.text().isEmpty()) { 2.47 + //Invalid use of @value 2.48 + writer.getMsgRetriever().warning(tag.holder().position(), 2.49 + "doclet.value_tag_invalid_use"); 2.50 + } else { 2.51 + //Reference is unknown. 2.52 + writer.getMsgRetriever().warning(tag.holder().position(), 2.53 + "doclet.value_tag_invalid_reference", tag.text()); 2.54 + } 2.55 } else if (field.constantValue() != null) { 2.56 return writer.valueTagOutput(field, 2.57 field.constantValueExpression(),
3.1 --- a/test/com/sun/javadoc/testValueTag/TestValueTag.java Wed Sep 25 14:04:24 2013 -0700 3.2 +++ b/test/com/sun/javadoc/testValueTag/TestValueTag.java Wed Sep 25 22:26:42 2013 -0700 3.3 @@ -23,13 +23,12 @@ 3.4 3.5 /* 3.6 * @test 3.7 - * @bug 4764045 3.8 + * @bug 4764045 8004825 3.9 * @summary This test ensures that the value tag works in all 3.10 * use cases. The explainations for each test case are written below. 3.11 * @author jamieh 3.12 * @library ../lib/ 3.13 - * @build JavadocTester 3.14 - * @build TestValueTag 3.15 + * @build JavadocTester TestValueTag 3.16 * @run main TestValueTag 3.17 */ 3.18 3.19 @@ -41,8 +40,14 @@ 3.20 //Javadoc arguments. 3.21 private static final String[] ARGS = 3.22 new String[] { 3.23 + "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag", 3.24 + "todo", "pkg1", "pkg2" 3.25 + }; 3.26 + 3.27 + private static final String[] ARGS1 = 3.28 + new String[] { 3.29 "-Xdoclint:none", 3.30 - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag", 3.31 + "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, "-tag", 3.32 "todo", "pkg1", "pkg2" 3.33 }; 3.34 3.35 @@ -91,16 +96,58 @@ 3.36 {BUG_ID + FS + "pkg1" + FS + "CustomTagUsage.html", 3.37 "<dt><span class=\"strong\">Todo:</span></dt>" + NL + 3.38 "<dd>the value of this constant is 55.</dd>"}, 3.39 + //Test @value errors printed dues to invalid use or when used with 3.40 + //non-constant or with bad references. 3.41 + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + 3.42 + " * Result: {@value TEST_12_ERROR}" 3.43 + }, 3.44 + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + 3.45 + " * Result: {@value}" 3.46 + }, 3.47 + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + 3.48 + " * Result: {@value NULL}" 3.49 + }, 3.50 + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + 3.51 + " * Invalid (null): {@value}" 3.52 + }, 3.53 + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + 3.54 + " * Invalid (non-constant field): {@value}" 3.55 + }, 3.56 + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + 3.57 + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" 3.58 + }, 3.59 + {ERROR_OUTPUT,"error: reference not found" + NL + 3.60 + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" 3.61 + }, 3.62 + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + 3.63 + " * @todo the value of this constant is {@value}" 3.64 + } 3.65 + }; 3.66 + private static final String[][] TEST1 = { 3.67 //Test @value warning printed when used with non-constant. 3.68 {WARNING_OUTPUT,"warning - @value tag (which references nonConstant) " + 3.69 "can only be used in constants." 3.70 }, 3.71 + {WARNING_OUTPUT,"warning - @value tag (which references NULL) " + 3.72 + "can only be used in constants." 3.73 + }, 3.74 + {WARNING_OUTPUT,"warning - @value tag (which references TEST_12_ERROR) " + 3.75 + "can only be used in constants." 3.76 + }, 3.77 //Test warning printed for bad reference. 3.78 {WARNING_OUTPUT,"warning - UnknownClass#unknownConstant (referenced by " + 3.79 "@value tag) is an unknown reference." 3.80 }, 3.81 + //Test warning printed for invalid use of @value. 3.82 + {WARNING_OUTPUT,"warning - @value tag cannot be used here." 3.83 + } 3.84 }; 3.85 - private static final String[][] NEGATED_TEST = NO_TEST; 3.86 + private static final String[][] NEGATED_TEST = { 3.87 + //Base case: using @value on a constant. 3.88 + {BUG_ID + FS + "pkg1" + FS + "Class1.html", 3.89 + "Result: <a href=\"../pkg1/Class1.html#TEST_12_ERROR\">\"Test 12 " + 3.90 + "generates an error message\"</a>"}, 3.91 + }; 3.92 3.93 /** 3.94 * The entry point of the test. 3.95 @@ -109,9 +156,18 @@ 3.96 public static void main(String[] args) { 3.97 TestValueTag tester = new TestValueTag(); 3.98 run(tester, ARGS, TEST, NEGATED_TEST); 3.99 + checkForException(tester); 3.100 + run(tester, ARGS1, TEST1, NO_TEST); 3.101 + checkForException(tester); 3.102 tester.printSummary(); 3.103 } 3.104 3.105 + public static void checkForException(TestValueTag tester) { 3.106 + if (tester.getErrorOutput().contains("DocletAbortException")) { 3.107 + throw new AssertionError("javadoc threw DocletAbortException"); 3.108 + } 3.109 + } 3.110 + 3.111 /** 3.112 * {@inheritDoc} 3.113 */
4.1 --- a/test/com/sun/javadoc/testValueTag/pkg1/Class1.java Wed Sep 25 14:04:24 2013 -0700 4.2 +++ b/test/com/sun/javadoc/testValueTag/pkg1/Class1.java Wed Sep 25 22:26:42 2013 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -45,6 +45,16 @@ 4.11 public static final String TEST_11_PASSES = "Test 11 passes"; 4.12 4.13 /** 4.14 + * Invalid (non-constant field): {@value} 4.15 + */ 4.16 + public static String TEST_12_ERROR = "Test 12 generates an error message"; 4.17 + 4.18 + /** 4.19 + * Invalid (null): {@value} 4.20 + */ 4.21 + public static final String NULL = null; 4.22 + 4.23 + /** 4.24 * Result: {@value TEST_3_PASSES} 4.25 */ 4.26 public int field; 4.27 @@ -60,6 +70,21 @@ 4.28 public void method() {} 4.29 4.30 /** 4.31 + * Result: {@value TEST_12_ERROR} 4.32 + */ 4.33 + public void invalidValueTag1() {} 4.34 + 4.35 + /** 4.36 + * Result: {@value} 4.37 + */ 4.38 + public void invalidValueTag2() {} 4.39 + 4.40 + /** 4.41 + * Result: {@value NULL} 4.42 + */ 4.43 + public void testNullConstant() {} 4.44 + 4.45 + /** 4.46 * Result: {@value pkg1.Class1#TEST_6_PASSES} 4.47 */ 4.48 public class NestedClass{}