/* * Copyright (c) 2003, 2015, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 4789689 4905985 4927164 4827184 4993906 5004549 7025314 7010344 8025633 8026567 * @summary Run Javadoc on a set of source files that demonstrate new * language features. Check the output to ensure that the new * language features are properly documented. * @author jamieh * @library ../lib * @modules jdk.javadoc * @build JavadocTester * @run main TestNewLanguageFeatures */ public class TestNewLanguageFeatures extends JavadocTester { public static void main(String... args) throws Exception { TestNewLanguageFeatures tester = new TestNewLanguageFeatures(); tester.runTests(); } @Test void test() { javadoc("-Xdoclint:none", "-d", "out", "-use", "-sourcepath", testSrc, "pkg", "pkg1", "pkg2"); checkExit(Exit.OK); checkEnums(); checkTypeParameters(); checkVarArgs(); checkAnnotationTypeUsage(); } //================================= // ENUM TESTING //================================= void checkEnums() { checkOutput("pkg/Coin.html", true, // Make sure enum header is correct. "Enum Coin", // Make sure enum signature is correct. "
public enum "
                + "Coin\n"
                + "extends java.lang.Enum<Coin>
", // Check for enum constant section "Enum Constants" + " ", // Detail for enum constant "Dime", // Automatically insert documentation for values() and valueOf(). "Returns an array containing the constants of this enum type,", "Returns the enum constant of this type with the specified name", "for (Coin c : Coin.values())", "Overloaded valueOf() method has correct documentation.", "Overloaded values method has correct documentation.", "
public static Coin" +
                " valueOf(java.lang.String name)
\n" + "
Returns the enum constant of this type with the specified name.\n" + "The string must match exactly an identifier used to declare an\n" + "enum constant in this type. (Extraneous whitespace characters are \n" + "not permitted.)
\n" + "
\n" + "
Parameters:
\n" + "
name - the name of the enum constant to be returned.
\n" + "
Returns:
\n" + "
the enum constant with the specified name
\n" + "
Throws:
\n" + "
java.lang.IllegalArgumentException - if this enum type has no " + "constant with the specified name
\n" + "
java.lang.NullPointerException - if the argument is null
"); // NO constructor section checkOutput("pkg/Coin.html", false, "

Constructor Summary

"); } //================================= // TYPE PARAMETER TESTING //================================= void checkTypeParameters() { checkOutput("pkg/TypeParameters.html", true, // Make sure the header is correct. "Class TypeParameters<E>", // Check class type parameters section. "
Type Parameters:
\n" + "
E - " + "the type parameter for this class.", // Type parameters in @see/@link "
\n" + "
See Also:
\n" + "
" + "" + "TypeParameters
\n" + "
", // Method that uses class type parameter. "(E param)", // Method type parameter section. "Type Parameters:\n" + "
T - This is the first " + "type parameter.
\n" + "
V - This is the second type " + "parameter.", // Signature of method with type parameters "public <T extends java.util.List,V> " + "java.lang.String[] methodThatHasTypeParameters", // Method that returns TypeParameters "E[]\n" + "" + "" + "methodThatReturnsTypeParameterA(E[] e)", "
public E[] "
                + "methodThatReturnsTypeParameterA(E[] e)
\n", "<T extends java.lang.Object & java.lang.Comparable<? super T>>" + "
T
\n" + "" + "" + "methodtThatReturnsTypeParametersB(java.util.Collection<? extends T> coll)\n" + "
Returns TypeParameters
\n", // Method takes a TypeVariable "<X extends java.lang.Throwable>
" + "E" + "
\n" + "" + "" + "orElseThrow(java.util.function.Supplier<? extends X> exceptionSupplier)" ); checkOutput("pkg/Wildcards.html", true, // Wildcard testing. "" + "TypeParameters<? super java.lang.String> a", "" + "TypeParameters<? extends java.lang.StringBuffer> b", "" + "TypeParameters c"); checkOutput(Output.OUT, true, // Bad type parameter warnings. "warning - @param argument " + "\"\" is not a type parameter name.", "warning - @param argument " + "\"\" is not a type parameter name."); // Signature of subclass that has type parameters. checkOutput("pkg/TypeParameterSubClass.html", true, "
public class TypeParameterSubClass<T extends "
                + "java.lang.String>\n"
                + "extends "
                + ""
                + "TypeParameterSuperClass<T>
"); // Interface generic parameter substitution // Signature of subclass that has type parameters. checkOutput("pkg/TypeParameters.html", true, "
\n" + "
All Implemented Interfaces:
\n" + "
" + "SubInterface<E>, SuperInterface<E>
\n" + "
"); checkOutput("pkg/SuperInterface.html", true, "
\n" + "
All Known Subinterfaces:
\n" + "
" + "SubInterface<V>
\n" + "
"); checkOutput("pkg/SubInterface.html", true, "
\n" + "
All Superinterfaces:
\n" + "
" + "SuperInterface<V>
\n" + "
"); //============================================================== // Handle multiple bounds. //============================================================== checkOutput("pkg/MultiTypeParameters.html", true, "public <T extends java.lang.Number & java.lang.Runnable> T foo(T t)"); //============================================================== // Test Class-Use Documentation for Type Parameters. //============================================================== // ClassUseTest1: checkOutput("pkg2/class-use/Foo.html", true, "Classes in pkg2 with type parameters of " + "type " + "Foo ", "ClassUseTest1<T extends " + "Foo" + " & " + "Foo2> ", "Methods in pkg2 with type parameters of " + "type Foo ", "ClassUseTest1." + "method" + "(T t) ", "Fields in pkg2 with type parameters of " + "type " + "Foo ", "td class=\"colFirst\">ParamTest" + "<Foo>" ); checkOutput("pkg2/class-use/ParamTest.html", true, "Fields in pkg2 declared as ParamTest" + " ", "ParamTest<Foo>" ); checkOutput("pkg2/class-use/Foo2.html", true, "Classes in pkg2 with type parameters of " + "type Foo2 " + "", "ClassUseTest1<T extends " + "Foo" + " & " + "Foo2> ", "Methods in pkg2 with type parameters of " + "type Foo2 " + "", "" + "ClassUseTest1.method" + "(T t) " ); // ClassUseTest2: > checkOutput("pkg2/class-use/ParamTest.html", true, "Classes in pkg2 with type parameters of " + "type ParamTest" + " ", "ClassUseTest2<T extends " + "" + "ParamTest<" + "Foo3>> ", "Methods in pkg2 with type parameters of " + "type ParamTest" + " ", "ClassUseTest2." + "method" + "(T t) ", "Fields in pkg2 declared as ParamTest" + " ", "ParamTest" + "<" + "Foo>", "Methods in pkg2 with type parameters of " + "type ParamTest" + " ", "<T extends ParamTest" + "<Foo3>>
ParamTest" + "<Foo3>
" ); checkOutput("pkg2/class-use/Foo3.html", true, "Classes in pkg2 with type parameters of " + "type " + "Foo3 ", "ClassUseTest2<T extends " + "" + "ParamTest<" + "Foo3>> ", "Methods in pkg2 with type parameters of " + "type Foo3 " + "", "ClassUseTest2." + "method" + "(T t) ", "Methods in pkg2 that return types with " + "arguments of type Foo3" + " ", "<T extends ParamTest<" + "Foo3" + ">>
ParamTest<Foo3>
" ); // ClassUseTest3: >> checkOutput("pkg2/class-use/ParamTest2.html", true, "Classes in pkg2 with type parameters of " + "type ParamTest2" + " ", "ClassUseTest3<T extends " + "" + "ParamTest2<java.util.List<? extends " + "" + "Foo4>>> ", "Methods in pkg2 with type parameters of " + "type ParamTest2" + " ", "ClassUseTest3" + ".method(T t) ", "<T extends " + "ParamTest2<java.util.List<? extends Foo4>" + ">>
ParamTest2<java.util.List" + "<? extends Foo4>>
" ); checkOutput("pkg2/class-use/Foo4.html", true, "Classes in pkg2 with type parameters of " + "type Foo4 " + "", "ClassUseTest3<T extends " + "" + "ParamTest2<java.util.List<? extends " + "" + "Foo4>>> ", "Methods in pkg2 with type parameters of " + "type Foo4 ", "ClassUseTest3." + "method(T t)" + " ", "Methods in pkg2 that return types with " + "arguments of type Foo4 ", "<T extends " + "ParamTest2<java.util.List<? extends Foo4>" + ">>
ParamTest2<java.util.List" + "<? extends Foo4>>
" ); // Type parameters in constructor and method args checkOutput("pkg2/class-use/Foo4.html", true, "Method parameters in pkg2 with type arguments of " + "type Foo4 " + "\n" + "\n" + "Modifier and Type\n" + "Method and Description\n" + "\n" + "\n" + "\n" + "void\n" + "ClassUseTest3." + "method(java." + "util.Set<Foo4> p) \n" + "\n" + "", "Constructor parameters in pkg2 with type arguments " + "of type Foo4 " + "" ); //================================= // TYPE PARAMETER IN INDEX //================================= checkOutput("index-all.html", true, "" + "method(Vector<Object>)" ); // TODO: duplicate of previous case; left in delibarately for now to simplify comparison testing //================================= // TYPE PARAMETER IN INDEX //================================= checkOutput("index-all.html", true, "" + "method(Vector<Object>)" ); // No type parameters in class frame. checkOutput("allclasses-frame.html", false, "" + "TypeParameters<E>" ); } //================================= // VAR ARG TESTING //================================= void checkVarArgs() { checkOutput("pkg/VarArgs.html", true, "(int... i)", "(int[][]... i)", "-int:A...-", "" + "TypeParameters... t"); } //================================= // ANNOTATION TYPE TESTING //================================= void checkAnnotationTypes() { checkOutput("pkg/AnnotationType.html", true, // Make sure the summary links are correct. "
  • Summary: 
  • \n" + "
  • Field | 
  • \n" + "
  • " + "Required | 
  • \n" + "
  • " + "Optional
  • ", // Make sure the detail links are correct. "
  • Detail: 
  • \n" + "
  • Field | 
  • \n" + "
  • Element
  • ", // Make sure the heading is correct. "Annotation Type AnnotationType", // Make sure the signature is correct. "public @interface AnnotationType", // Make sure member summary headings are correct. "

    Required Element Summary

    ", "

    Optional Element Summary

    ", // Make sure element detail heading is correct "Element Detail", // Make sure default annotation type value is printed when necessary. "
    \n" + "
    Default:
    \n" + "
    \"unknown\"
    \n" + "
    "); } //================================= // ANNOTATION TYPE USAGE TESTING //================================= void checkAnnotationTypeUsage() { checkOutput("pkg/package-summary.html", true, // PACKAGE "@AnnotationType(optional=\"Package Annotation\",\n" + " required=1994)"); checkOutput("pkg/AnnotationTypeUsage.html", true, // CLASS "
    @AnnotationType("
                    + "optional"
                    + "=\"Class Annotation\",\n"
                    + "                "
                    + "required=1994)\n"
                    + "public class "
                    + "AnnotationTypeUsage\n"
                    + "extends java.lang.Object
    ", // FIELD "
    @AnnotationType("
                    + "optional"
                    + "=\"Field Annotation\",\n"
                    + "                "
                    + "required=1994)\n"
                    + "public int field
    ", // CONSTRUCTOR "
    @AnnotationType("
                    + "optional"
                    + "=\"Constructor Annotation\",\n"
                    + "                "
                    + "required=1994)\n"
                    + "public AnnotationTypeUsage()
    ", // METHOD "
    @AnnotationType("
                    + "optional"
                    + "=\"Method Annotation\",\n"
                    + "                "
                    + "required=1994)\n"
                    + "public void method()
    ", // METHOD PARAMS "
    public void methodWithParams("
                    + ""
                    + "@AnnotationType("
                    + "optional=\"Parameter Annotation\",required=1994)\n"
                    + "                             int documented,\n"
                    + "                             int undocmented)
    ", // CONSTRUCTOR PARAMS "
    public AnnotationTypeUsage("
                    + "@AnnotationType("
                    + "optional=\"Constructor Param Annotation\",required=1994)\n"
                    + "                           int documented,\n"
                    + "                           int undocmented)
    "); //================================= // Annotatation Type Usage //================================= checkOutput("pkg/class-use/AnnotationType.html", true, "Packages with annotations of type " + "AnnotationType " + "", "Classes in pkg with annotations of type " + "AnnotationType ", "Fields in pkg with annotations of type " + "AnnotationType" + " ", "Methods in pkg with annotations of type " + "AnnotationType" + " ", "Method parameters in pkg with annotations of type " + "AnnotationType" + " ", "Constructors in pkg with annotations of type " + "AnnotationType" + " ", "Constructor parameters in pkg with annotations of " + "type AnnotationType " ); //============================================================== // ANNOTATION TYPE USAGE TESTING (When @Documented is omitted) //=============================================================== checkOutput("pkg/AnnotationTypeUsage.html", false, // CLASS "@AnnotationTypeUndocumented(optional=\"Class Annotation\",\n" + " required=1994)\n" + "public class AnnotationTypeUsage
    extends java.lang.Object
    ", // FIELD "@AnnotationTypeUndocumented(optional=\"Field Annotation\",\n" + " required=1994)\n" + "public int field", // CONSTRUCTOR "@AnnotationTypeUndocumented(optional=\"Constructor Annotation\",\n" + " required=1994)\n" + "public AnnotationTypeUsage()", // METHOD "@AnnotationTypeUndocumented(optional=\"Method Annotation\",\n" + " required=1994)\n" + "public void method()"); //================================= // Make sure annotation types do not // trigger this warning. //================================= checkOutput(Output.OUT, false, "Internal error: package sets don't match: [] with: null"); //================================= // ANNOTATION TYPE USAGE TESTING (All Different Types). //================================= checkOutput("pkg1/B.html", true, // Integer "d=3.14,", // Double "d=3.14,", // Boolean "b=true,", // String "s=\"sigh\",", // Class "c=Foo.class,", // Bounded Class "w=TypeParameterSubClass.class,", // Enum "e=Penny,", // Annotation Type "a=@AnnotationType(optional=\"foo\",required=1994),", // String Array "sa={\"up\",\"down\"},", // Primitive "primitiveClassTest=boolean.class,"); // XXX: Add array test case after this if fixed: //5020899: Incorrect internal representation of class-valued annotation elements // Make sure that annotations are surrounded by
     and 
    checkOutput("pkg1/B.html", true, "
    @A",
                    "public interface B
    "); } }