1 /*
   2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8025091 8198890
  27  * @summary Verify the presence visible members in the case of
  28  *          member hiding and overridding.
  29  * @library /tools/lib ../../lib
  30  * @modules jdk.javadoc/jdk.javadoc.internal.tool
  31  * @build javadoc.tester.* toolbox.ToolBox builder.ClassBuilder
  32  * @run main TestVisibleMembers
  33  */
  34 
  35 import java.nio.file.Path;
  36 import java.nio.file.Paths;
  37 
  38 import builder.AbstractBuilder;
  39 import builder.AbstractBuilder.Comment.Kind;
  40 import builder.ClassBuilder;
  41 import builder.ClassBuilder.*;
  42 
  43 import toolbox.ToolBox;
  44 import builder.ClassBuilder;
  45 
  46 import javadoc.tester.JavadocTester;
  47 
  48 public class TestVisibleMembers extends JavadocTester {
  49 
  50     final ToolBox tb;
  51     public static void main(String... args) throws Exception {
  52         TestVisibleMembers tester = new TestVisibleMembers();
  53         tester.runTests(m -> new Object[] { Paths.get(m.getName()) });
  54     }
  55 
  56     TestVisibleMembers() {
  57         tb = new ToolBox();
  58     }
  59 
  60     @Test
  61     public void testChronoDiamondLeafDetail(Path base) throws Exception {
  62         Path srcDir = base.resolve("src");
  63         emitChronoDiamondLeaf(srcDir);
  64 
  65         Path outDir = base.resolve("out");
  66         javadoc("-d", outDir.toString(),
  67                 "-html5",
  68                 "--override-methods=detail",
  69                 "-sourcepath", srcDir.toString(),
  70                 "p");
  71         checkExit(Exit.OK);
  72 
  73         checkOrder("p/C.html", "METHOD SUMMARY",
  74                 "boolean", "equals", "java.lang.Object", "Method equals in p.C",
  75                 "C", "with", "java.lang.Object", "obj",  "Method with in p.C",
  76                 "C", "with", "java.lang.Object", "obj", "long", "lvalue", "Method with in p.C",
  77                 "METHOD DETAIL");
  78         checkOutput("p/C.html", false, "BImpl");
  79 
  80         checkOrder("p/E.html", "METHOD SUMMARY",
  81                 "boolean", "equals", "java.lang.Object", "Method equals in p.E",
  82                 "C", "with", "java.lang.Object", "Method with in p.E",
  83                 "C", "with", "java.lang.Object", "obj", "long", "lvalue", "Method with in p.E",
  84                 "METHOD DETAIL");
  85         checkOutput("p/E.html", false, "EImpl");
  86     }
  87 
  88     @Test
  89     public void testChronoDiamondLeafSummary(Path base) throws Exception {
  90         Path srcDir = base.resolve("src");
  91         emitChronoDiamondLeaf(srcDir);
  92 
  93         Path outDir = base.resolve("out-member");
  94         javadoc("-d", outDir.toString(),
  95                 "-html5",
  96                 "--override-methods=summary",
  97                 "-sourcepath", srcDir.toString(),
  98                 "p");
  99         checkExit(Exit.OK);
 100 
 101         checkOrder("p/C.html", "METHOD SUMMARY",
 102                 "boolean", "equals", "java.lang.Object", "Method equals in p.C",
 103                 "C", "with", "java.lang.Object", "obj", "Method with in p.C",
 104                 "C", "with", "java.lang.Object", "obj", "long", "lvalue", "Method with in p.C",
 105                 "METHOD DETAIL");
 106         checkOutput("p/C.html", false, "BImpl");
 107 
 108         checkOrder("p/E.html", "METHOD SUMMARY",
 109                 "boolean", "equals", "java.lang.Object", "Method equals in p.E",
 110                 "C", "with", "java.lang.Object", "Method with in p.E",
 111                 "C", "with", "java.lang.Object", "long", "lvalue", "Method with in p.E",
 112                 "METHOD DETAIL");
 113         checkOutput("p/E.html", false, "EImpl");
 114     }
 115 
 116     // see j.t.TemporalAdjuster
 117     void emitChronoDiamondLeaf(Path srcDir) throws Exception {
 118 
 119         // Interface A
 120         MethodBuilder mbWith1 = MethodBuilder
 121                 .parse("default Object with(Object obj) {return null;}");
 122         MethodBuilder mbWith2 = MethodBuilder
 123                 .parse("default Object with(Object obj, long lvalue) {return null;}");
 124 
 125         new ClassBuilder(tb, "p.A")
 126                 .setModifiers("public", "interface")
 127                 .addMembers(mbWith1, mbWith2)
 128                 .write(srcDir);
 129 
 130         // Interface B
 131         mbWith1.setComments("{@inheritDoc}", "@param obj an object",
 132                 "@return something");
 133 
 134         mbWith2.setComments("{@inheritDoc}", "@param obj an object",
 135                 "@param lvalue an lvalue", "@return something");
 136 
 137         new ClassBuilder(tb, "p.B")
 138                 .setModifiers( "public", "interface")
 139                 .setExtends("A")
 140                 .addMembers(mbWith1, mbWith2)
 141                 .write(srcDir);
 142 
 143         // Class BImpl
 144         MethodBuilder mb31 = MethodBuilder.parse("C with(Object obj) {return null;}");
 145         MethodBuilder mb32 = MethodBuilder.parse("C with(Object obj, Long lobj) {return null;}");
 146         new ClassBuilder(tb, "p.BImpl<C extends B>")
 147                 .setModifiers( "abstract", "class")
 148                 .addImplements("B")
 149                 .addMembers(mb31, mb32)
 150                 .write(srcDir);
 151 
 152         // Class C
 153         new ClassBuilder(tb, "p.C")
 154                 .setModifiers("public", "class")
 155                 .setExtends("BImpl")
 156                 .addMembers(mbWith1.setReturn("C")
 157                         .setModifiers("public")
 158                         .setComments(AbstractBuilder.Comment.Kind.AUTO))
 159                 .addMembers(mbWith2.setReturn("C")
 160                         .setModifiers("public")
 161                         .setComments(AbstractBuilder.Comment.Kind.AUTO))
 162                 .addMembers(MethodBuilder.parse("public boolean equals(Object obj) { return false;}"))
 163                 .write(srcDir);
 164 
 165         // Class EImpl
 166         MethodBuilder mb41 = MethodBuilder.parse("C with(Object obj) {return null;}")
 167                 .setComments(Kind.NO_API_COMMENT);
 168         MethodBuilder mb42 = MethodBuilder.parse("C with(Object obj, Long lobj) {return null;}");
 169         new ClassBuilder(tb, "p.EImpl<C extends B>")
 170                 .setModifiers( "abstract", "class")
 171                 .addImplements("B")
 172                 .addMembers(mb41, mb42)
 173                 .write(srcDir);
 174 
 175         // Class E
 176         MethodBuilder mb51 = MethodBuilder.parse("public C with(Object obj) {return null;}");
 177         MethodBuilder mb52 = MethodBuilder.parse("public C with(Object obj, long lvalue) {return null;}");
 178         MethodBuilder mb53 = MethodBuilder.parse("public boolean equals(Object obj) { return false;}");
 179         new ClassBuilder(tb, "p.E")
 180                 .setModifiers("public", "class")
 181                 .setExtends("EImpl")
 182                 .addMembers(mb51, mb52, mb53)
 183                 .write(srcDir);
 184     }
 185 
 186     @Test
 187     public void testNestedInterfaceDetail(Path base) throws Exception {
 188         Path srcDir = base.resolve("src");
 189         emitNestedInterface(srcDir);
 190 
 191         Path outDir = base.resolve("out");
 192         javadoc("-d", outDir.toString(),
 193                 "-html5",
 194                 "--override-methods=detail",
 195                 "-sourcepath", srcDir.toString(),
 196                 "p");
 197         checkExit(Exit.OK);
 198 
 199         checkOutput("p/TA.html", false, "getTA");
 200 
 201         checkOrder("p/Bar.html",
 202                 "doSomething()",
 203                 "getTA()");
 204     }
 205 
 206     @Test
 207     public void testNestedInterfaceSummary(Path base) throws Exception {
 208         Path srcDir = base.resolve("src");
 209         emitNestedInterface(srcDir);
 210 
 211         Path outDir = base.resolve("out");
 212         javadoc("-d", outDir.toString(),
 213                 "-html5",
 214                 "--override-methods=summary",
 215                 "-sourcepath", srcDir.toString(),
 216                 "p");
 217         checkExit(Exit.OK);
 218 
 219         checkOutput("p/TA.html", false, "getTA");
 220 
 221         checkOrder("p/Bar.html",
 222                 "doSomething()",
 223                 "getTA()");
 224 
 225         checkOrder("p/Foo.html",
 226                 "Methods declared in",
 227                 "Bar.html",
 228                 "getTA");
 229     }
 230 
 231     // See jx.s.TransferHandler
 232     void emitNestedInterface(Path srcDir) throws Exception {
 233 
 234         ClassBuilder innerI = new ClassBuilder(tb, "HasTA")
 235                 .setModifiers("interface");
 236         MethodBuilder interfaceMethod = MethodBuilder.parse("public TA getTa();")
 237                 .setComments(Kind.NO_API_COMMENT);
 238         innerI.addMembers(interfaceMethod);
 239 
 240         new ClassBuilder(tb, "p.TA")
 241                 .setModifiers("public", "class")
 242                 .addImplements("java.io.Serializable")
 243                 .addNestedClasses(innerI)
 244                 .write(srcDir);
 245 
 246         new ClassBuilder(tb, "p.Foo")
 247                 .setModifiers("public", "class")
 248                 .setExtends("Bar")
 249                 .write(srcDir);
 250 
 251         new ClassBuilder(tb, "p.Bar")
 252                 .setModifiers("public", "abstract", "class")
 253                 .addImplements("TA.HasTA")
 254                 .addMembers(
 255                     MethodBuilder.parse("public void doSomething(){}"),
 256                     MethodBuilder.parse("public TA getTA(){return null;}")
 257                 ).write(srcDir);
 258     }
 259 
 260     @Test
 261     public void testStreamsMissingLinksDetail(Path base) throws Exception {
 262         Path srcDir = base.resolve("src");
 263         emitStreamsMissingLinks(srcDir);
 264 
 265         Path outDir = base.resolve("out");
 266         javadoc("-d", outDir.toString(),
 267                 "-html5",
 268                 "--override-methods=detail",
 269                 "-sourcepath", srcDir.toString(),
 270                 "p");
 271         checkExit(Exit.OK);
 272 
 273         checkOrder("p/C.html",
 274                 "METHOD DETAIL",
 275                 "public", "void", "method",
 276                 "See Also:",
 277                 "sub()",
 278                 "sub1()");
 279 
 280         checkOrder("p/ILong.html",
 281                 "METHOD DETAIL",
 282                 "default", "void", "forEach", "java.util.function.Consumer",
 283                 "java.lang.Long", "action",
 284                 "Do you see me", "#forEach(java.util.function.LongConsumer)",
 285                 "forEach(LongConsumer)",
 286                 "END OF CLASS DATA");
 287 
 288         checkOrder("p/IImpl.html",
 289                 "METHOD DETAIL",
 290                 "Method sub in p.IImpl",
 291                 "Specified by:", "I.html", "II.html",
 292                 "END OF CLASS DATA");
 293     }
 294 
 295     @Test
 296     public void testStreamsMissingLinksSummary(Path base) throws Exception {
 297         Path srcDir = base.resolve("src");
 298         emitStreamsMissingLinks(srcDir);
 299 
 300         Path outDir = base.resolve("out");
 301         javadoc("-d", outDir.toString(),
 302                 "-html5",
 303                 "--override-methods=summary",
 304                 "-sourcepath", srcDir.toString(),
 305                 "p");
 306         checkExit(Exit.OK);
 307 
 308         checkOrder("p/C.html",
 309                 "METHOD DETAIL",
 310                 "public", "void", "method", "See Also:", "sub()", "I.sub1()",
 311                 "public", "void", "m", "Method in C. See", "I.length()"
 312                 );
 313 
 314         checkOrder("p/ILong.html",
 315                 "METHOD DETAIL",
 316                 "default", "void", "forEach", "java.util.function.Consumer",
 317                 "java.lang.Long", "action",
 318                 "Do you see me", "QLong.html#forEach(Q)",
 319                 "QLong.forEach(LongConsumer)",
 320                 "END OF CLASS DATA");
 321 
 322         checkOrder("p/IImpl.html",
 323                 "METHOD DETAIL",
 324                 "Method sub in p.IImpl",
 325                 "Specified by:", "I.html",
 326                 "END OF CLASS DATA");
 327 
 328         checkUnique("p/IImpl.html", "Specified by:");
 329     }
 330 
 331     // see j.u.Spliterator
 332     void emitStreamsMissingLinks(Path srcDir) throws Exception {
 333         new ClassBuilder(tb, "p.I")
 334                 .setModifiers("public", "interface")
 335                 .addMembers(
 336                         MethodBuilder.parse("public I sub();"),
 337                         MethodBuilder.parse("public I sub1();"),
 338                         MethodBuilder.parse("public int length();")
 339                 ).write(srcDir);
 340 
 341         new ClassBuilder(tb, "p.A")
 342                 .setModifiers("abstract", "class")
 343                 .addImplements("I")
 344                 .addMembers(
 345                         MethodBuilder.parse("public I sub() {}"),
 346                         MethodBuilder.parse("public I sub1() {}"),
 347                         MethodBuilder.parse("public int length(){return 0;}")
 348                                 .setComments(Kind.NO_API_COMMENT),
 349                         MethodBuilder.parse("public void m(){}")
 350                         .setComments("Method in C. See {@link #length()}.")
 351                 ).write(srcDir);
 352 
 353         new ClassBuilder(tb, "p.C")
 354                 .setModifiers("public", "class")
 355                 .setExtends("A").addImplements("I")
 356                 .addMembers(
 357                         MethodBuilder.parse("public I sub() {return null;}"),
 358                         MethodBuilder.parse("public I sub1() {return null;}")
 359                                 .setComments(Kind.INHERIT_DOC),
 360                         MethodBuilder.parse(" public void method() {}")
 361                                 .setComments("A method ", "@see #sub", "@see #sub1"),
 362                         MethodBuilder.parse("public int length(){return 1;}")
 363                                 .setComments(Kind.NO_API_COMMENT)
 364                 ).write(srcDir);
 365 
 366         new ClassBuilder(tb, "p.II")
 367                 .setModifiers("public", "interface")
 368                 .setExtends("I")
 369                 .addMembers(
 370                         MethodBuilder.parse("default public I sub() {return null;}")
 371                             .setComments(Kind.NO_API_COMMENT)
 372                 ).write(srcDir);
 373 
 374         new ClassBuilder(tb, "p.IImpl")
 375                 .setModifiers("public", "class")
 376                 .addImplements("II")
 377                 .addMembers(
 378                     MethodBuilder.parse("public I sub() {return null;}")
 379                 ).write(srcDir);
 380 
 381         new ClassBuilder(tb, "p.QLong<P, Q, R>")
 382                 .setModifiers("public interface")
 383                 .addMembers(
 384                         MethodBuilder.parse("default void forEach(Q action) {}")
 385                 ).write(srcDir);
 386 
 387         new ClassBuilder(tb, "p.ILong")
 388                 .addImports("java.util.function.*")
 389                 .setModifiers("public", "interface")
 390                 .setExtends("QLong<Long, LongConsumer, Object>")
 391                 .addMembers(
 392                         MethodBuilder.parse("default void forEach(LongConsumer action) {}")
 393                             .setComments(Kind.NO_API_COMMENT),
 394                         MethodBuilder.parse("default void forEach(Consumer<Long> action) {}")
 395                             .setComments("Do you see me {@link #forEach(LongConsumer)} ?")
 396                 ).write(srcDir);
 397     }
 398 
 399     @Test
 400     public void testVisibleMemberTableDetail(Path base) throws Exception {
 401         Path srcDir = base.resolve("src");
 402         emitVisibleMemberTable(srcDir);
 403 
 404         Path outDir = base.resolve("out");
 405         javadoc("-d", outDir.toString(),
 406                 "-html5",
 407                 "--override-methods=detail",
 408                 "-sourcepath", srcDir.toString(),
 409                 "p");
 410         checkExit(Exit.OK);
 411 
 412         checkOrder("p/C.html",
 413                 "METHOD DETAIL",
 414                 "public", "void", "m", "Method m in p.B",
 415                 "public", "void", "n", "Method n in p.A",
 416                 "public", "void", "o", "Description copied from class:", ">A<", "Method o in p.A",
 417                 "public", "void", "p", "Method p in p.B",
 418                 "END OF CLASS DATA");
 419 
 420         checkOutput("p/C.html", false,
 421                 "Overrides",
 422                 "Methods declared in class p");
 423 
 424         checkOrder("p/D.html",
 425                 "METHOD SUMMARY",
 426                 "void", "m", "Method m in p.D",
 427                 "void", "n", "Method n in p.D",
 428                 "void", "o", "Method o in p.D",
 429                 "void", "p", "Method p in p.D",
 430                 "CONSTRUCTOR DETAIL");
 431 
 432         checkOutput("p/D.html", false,
 433                 "Description copied from class:",
 434                 "Overrides",
 435                 "Methods declared in class p");
 436 
 437         checkOrder("p/E.html",
 438                 "METHOD SUMMARY",
 439                 "void", "m", "Method m in p.B",
 440                 "void", "n", "Method n in p.A",
 441                 "void", "o", "Method o in p.A",
 442                 "void", "p", "Method p in p.B",
 443                 "CONSTRUCTOR DETAIL");
 444 
 445         checkOutput("p/E.html", false,
 446                 "Description copied from class:",
 447                 "Overrides",
 448                 "Methods declared in class p");
 449     }
 450 
 451     @Test
 452     public void testVisibleMemberTableSummary(Path base) throws Exception {
 453         Path srcDir = base.resolve("src");
 454         emitVisibleMemberTable(srcDir);
 455 
 456         Path outDir = base.resolve("out");
 457         javadoc("-d", outDir.toString(),
 458                 "-html5",
 459                 "--override-methods=summary",
 460                 "-sourcepath", srcDir.toString(),
 461                 "p");
 462         checkExit(Exit.OK);
 463 
 464         checkOrder("p/C.html",
 465                 "METHOD SUMMARY",
 466                 "void", "m", "Method m in p.B",
 467                 "void", "n", "Method n in p.A",
 468                 "void", "o", "Method o in p.A",
 469                 "void", "p", "Method p in p.B",
 470                 "CONSTRUCTOR DETAIL");
 471 
 472         checkOrder("p/C.html",
 473                 "METHOD DETAIL",
 474                 "public", "void", "m", "Method m in p.B",
 475                 "public", "void", "n", "Method n in p.A",
 476                 "public", "void", "o", "Description copied from class:", ">A<", "Method o in p.A",
 477                 "public", "void", "p", "Method p in p.B",
 478                 "END OF CLASS DATA");
 479 
 480         checkOutput("p/C.html", false,
 481                 "Overrides",
 482                 "Methods declared in class p");
 483 
 484         checkOrder("p/D.html",
 485                 "METHOD SUMMARY",
 486                 "void", "m", "Method m in p.D",
 487                 "void", "n", "Method n in p.D",
 488                 "void", "o", "Method o in p.D",
 489                 "void", "p", "Method p in p.D",
 490                 "CONSTRUCTOR DETAIL");
 491 
 492         checkOutput("p/D.html", false,
 493                 "Description copied from class:",
 494                 "Overrides",
 495                 "Methods declared in class p");
 496 
 497         checkOrder("p/E.html",
 498                 "METHOD SUMMARY",
 499                 "void", "m", "Method m in p.B",
 500                 "void", "n", "Method n in p.A",
 501                 "void", "o", "Method o in p.A",
 502                 "void", "p", "Method p in p.B",
 503                 "CONSTRUCTOR DETAIL");
 504 
 505         checkOutput("p/E.html", false,
 506                 "Description copied from class:",
 507                 "Overrides",
 508                 "Methods declared in class p");
 509 
 510     }
 511 
 512     // emit a matrix of method variants
 513     void emitVisibleMemberTable(Path srcDir) throws Exception {
 514         new ClassBuilder(tb, "p.A")
 515                 .setModifiers("public", "class")
 516                 .addMembers(
 517                         MethodBuilder.parse("public void m() {}"),
 518                         MethodBuilder.parse("public void n() {}"),
 519                         MethodBuilder.parse("public void o() {}")
 520                 ).write(srcDir);
 521 
 522         new ClassBuilder(tb, "p.B")
 523                 .setModifiers("class")
 524                 .setExtends("A")
 525                 .addMembers(
 526                         MethodBuilder.parse("public void m() {}"),
 527                         MethodBuilder.parse("public void n() {}")
 528                                 .setComments(Kind.INHERIT_DOC),
 529                         MethodBuilder.parse("public void o() {}")
 530                         .setComments(Kind.NO_API_COMMENT),
 531                         MethodBuilder.parse("public void p() {}")
 532                 ).write(srcDir);
 533 
 534         new ClassBuilder(tb, "p.C")
 535                 .setModifiers("public", "class")
 536                 .setExtends("B")
 537                 .addMembers(
 538                         MethodBuilder.parse("public void m() {}")
 539                                 .setComments(Kind.NO_API_COMMENT),
 540                         MethodBuilder.parse("public void n() {}")
 541                                 .setComments(Kind.NO_API_COMMENT),
 542                         MethodBuilder.parse("public void o() {}")
 543                                 .setComments(Kind.NO_API_COMMENT),
 544                         MethodBuilder.parse("public void p() {}")
 545                                 .setComments(Kind.NO_API_COMMENT)
 546                 ).write(srcDir);
 547 
 548         new ClassBuilder(tb, "p.D")
 549                 .setModifiers("public", "class")
 550                 .setExtends("B")
 551                 .addMembers(
 552                         MethodBuilder.parse("public void m() {}"),
 553                         MethodBuilder.parse("public void n() {}"),
 554                         MethodBuilder.parse("public void o() {}"),
 555                         MethodBuilder.parse("public void p() {}")
 556                 ).write(srcDir);
 557 
 558         new ClassBuilder(tb, "p.E")
 559                 .setModifiers("public", "class")
 560                 .setExtends("B")
 561                 .addMembers(
 562                         MethodBuilder.parse("public void m() {}")
 563                                 .setComments(Kind.INHERIT_DOC),
 564                         MethodBuilder.parse("public void n() {}")
 565                                 .setComments(Kind.INHERIT_DOC),
 566                         MethodBuilder.parse("public void o() {}")
 567                                 .setComments(Kind.INHERIT_DOC),
 568                         MethodBuilder.parse("public void p() {}")
 569                                 .setComments(Kind.INHERIT_DOC)
 570                 ).write(srcDir);
 571     }
 572 
 573     @Test
 574     public void testHiddenMembersDetail(Path base) throws Exception {
 575         Path srcDir = base.resolve("src");
 576         emitHiddenMembers(srcDir);
 577 
 578         Path outDir = base.resolve("out");
 579         javadoc("-d", outDir.toString(),
 580                 "-html5",
 581                 "--override-methods=detail",
 582                 "-sourcepath", srcDir.toString(),
 583                 "p");
 584         checkExit(Exit.OK);
 585 
 586         checkOrder("p/C1.html",
 587                 "FIELD SUMMARY",
 588                 "Fields inherited from interface", "I1", "field2",
 589                 "Fields inherited from interface", "I2", "field2",
 590                 "Fields inherited from interface", "I3", "field",
 591                 "METHOD SUMMARY",
 592                 "Methods inherited from interface", "I1", "method2",
 593                 "Methods inherited from interface", "I2", "method2",
 594                 "Methods inherited from interface", "I3", "method",
 595                 "CONSTRUCTOR DETAIL");
 596 
 597         checkOrder("p/C2.html",
 598                 "FIELD SUMMARY",
 599                 "int", "field", "Field field in p.C2",
 600                 "Fields inherited from interface", "I1", "field2",
 601                 "Fields inherited from interface", "I2", "field2",
 602                 "METHOD SUMMARY",
 603                 "void", "method", "Method method in p.C2",
 604                 "void", "method2", "Method method2 in p.C2");
 605 
 606     }
 607 
 608     @Test
 609     public void testHiddenMembersSummary(Path base) throws Exception {
 610         Path srcDir = base.resolve("src");
 611         emitHiddenMembers(srcDir);
 612 
 613         Path outDir = base.resolve("out");
 614         javadoc("-d", outDir.toString(),
 615                 "-html5",
 616                 "--override-methods=summary",
 617                 "-sourcepath", srcDir.toString(),
 618                 "p");
 619         checkExit(Exit.OK);
 620 
 621         checkOrder("p/C1.html",
 622                 "Field Summary",
 623                 "Fields declared in interface", "I1", "field2",
 624                 "Fields declared in interface", "I2", "field2",
 625                 "Fields declared in interface", "I3", "field",
 626                 "Method Summary",
 627                 "Methods declared in interface", "I1", "method2",
 628                 "Methods declared in interface", "I2", "method2",
 629                 "Methods declared in interface", "I3", "method",
 630                 "Constructor Detail");
 631 
 632         checkOrder("p/C2.html",
 633                 "Field Summary",
 634                 "int", "field", "Field field in p.C2",
 635                 "Fields declared in interface", "I1", "field2",
 636                 "Fields declared in interface", "I2", "field2",
 637                 "Method Summary",
 638                 "void", "method", "Method method in p.C2",
 639                 "void", "method2", "Method method2 in p.C2");
 640 
 641     }
 642 
 643     void emitHiddenMembers(Path srcDir) throws Exception {
 644         new ClassBuilder(tb, "p.I1")
 645                 .setModifiers("public", "interface")
 646                 .addMembers(
 647                         FieldBuilder.parse("public static int field = 3;"),
 648                         FieldBuilder.parse("public static int field2 = 3;"),
 649                         MethodBuilder.parse("public void method();"),
 650                         MethodBuilder.parse("public void method2();"),
 651                         MethodBuilder.parse("public static void staticMethod() {}")
 652                 ).write(srcDir);
 653 
 654         new ClassBuilder(tb, "p.I2")
 655                 .setModifiers("public", "interface")
 656                 .addMembers(
 657                         FieldBuilder.parse("public static int field = 3;"),
 658                         FieldBuilder.parse("public static int field2 = 3;"),
 659                         MethodBuilder.parse("public void method();"),
 660                         MethodBuilder.parse("public void method2();"),
 661                         MethodBuilder.parse("public static void staticMethod() {}")
 662                 ).write(srcDir);
 663 
 664         new ClassBuilder(tb, "p.I3")
 665                 .setExtends("I1, I2")
 666                 .setModifiers("public", "interface")
 667                 .addMembers(
 668                         FieldBuilder.parse("public static int field = 3;"),
 669                         MethodBuilder.parse("public void method();"),
 670                         MethodBuilder.parse("public static void staticMethod() {}")
 671                 ).write(srcDir);
 672 
 673         new ClassBuilder(tb, "p.C1")
 674                 .setModifiers("public", "abstract", "class")
 675                 .addImplements("I3")
 676                 .write(srcDir);
 677 
 678         new ClassBuilder(tb, "p.C2")
 679                 .setExtends("C1")
 680                 .setModifiers("public", "abstract", "class")
 681                 .addMembers(
 682                         FieldBuilder.parse("public int field;"),
 683                         MethodBuilder.parse("public void method(){}"),
 684                         MethodBuilder.parse("public void method2(){}")
 685                 ).write(srcDir);
 686     }
 687 }