From c307391ab1f071b1473cd5f4c12437b8d5e0ca93 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 9 Aug 2023 21:17:10 +0000 Subject: [PATCH] 8307184: Incorrect/inconsistent specification and implementation for Elements.getDocComment Reviewed-by: vromero, jjg --- .../javax/lang/model/util/Elements.java | 32 ++- .../util/elements/TestGetDocComments.java | 191 ++++++++++++++++++ 2 files changed, 217 insertions(+), 6 deletions(-) create mode 100644 test/langtools/tools/javac/processing/model/util/elements/TestGetDocComments.java diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java index a4c4be0dcb0..d3326ba7018 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java @@ -283,15 +283,34 @@ public interface Elements { *

A documentation comment of an element is a comment that * begins with "{@code /**}", ends with a separate * "*/", and immediately precedes the element, - * ignoring white space. Therefore, a documentation comment + * ignoring white space, annotations, end-of-line-comments ({@code + * "//"} comments), and intermediate traditional comments + * ("/* ... */" comments) that are not doc comments. + * Therefore, a documentation comment * contains at least three "{@code *}" characters. The text * returned for the documentation comment is a processed form of - * the comment as it appears in source code. The leading "{@code /**}" - * and trailing "*/" are removed. For lines - * of the comment starting after the initial "{@code /**}", - * leading white space characters are discarded as are any + * the comment as it appears in source code: + *

+ * The processed lines are then * concatenated together (including line terminators) and * returned. * @@ -299,6 +318,7 @@ public interface Elements { * @return the documentation comment of the element, or {@code null} * if there is none * @jls 3.6 White Space + * @jls 3.7 Comments */ String getDocComment(Element e); diff --git a/test/langtools/tools/javac/processing/model/util/elements/TestGetDocComments.java b/test/langtools/tools/javac/processing/model/util/elements/TestGetDocComments.java new file mode 100644 index 00000000000..25a41b34205 --- /dev/null +++ b/test/langtools/tools/javac/processing/model/util/elements/TestGetDocComments.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023, 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 8307184 + * @summary Test basic operation of Elements.getDocComments + * @library /tools/lib /tools/javac/lib + * @build toolbox.ToolBox JavacTestingAbstractProcessor TestGetDocComments + * @compile -processor TestGetDocComments -proc:only TestGetDocComments.java + */ + +import java.io.Writer; +import java.util.*; +import java.util.function.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import toolbox.ToolBox; + +/** + * Test basic workings of Elements.getDocComments + */ +public class TestGetDocComments extends JavacTestingAbstractProcessor { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + boolean elementSeen = false; + + for (TypeElement typeRoot : ElementFilter.typesIn(roundEnv.getRootElements()) ) { + for (Element element : typeRoot.getEnclosedElements()) { + ExpectedComment expectedComment = element.getAnnotation(ExpectedComment.class); + if (expectedComment != null ) { + elementSeen = true; + String expectedCommentStr = expectedComment.value(); + String actualComment = elements.getDocComment(element); + + if (!expectedCommentStr.equals(actualComment)) { + messager.printError("Unexpected doc comment found", element); + (new ToolBox()).checkEqual(expectedCommentStr.lines().toList(), + actualComment.lines().toList()); + } + } + } + + if (!elementSeen) { + throw new RuntimeException("No elements seen."); + } + } + } + return true; + } + + @interface ExpectedComment { + String value(); + } + + // Basic processing of interior lines + /** + *Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + *eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + *enim ad minim veniam, quis nostrud exercitation ullamco laboris + *nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + *in reprehenderit in voluptate velit esse cillum dolore eu + *fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + *proident, sunt in culpa qui officia deserunt mollit anim id est + *laborum. + */ + @ExpectedComment(""" + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + """) + // End-of-line-style comment + @SuppressWarnings("") // A second preceding annotation + /* Traditional comment */ + private void foo() {return ;} + + + // Check removal of various *'s and space characters; + // use Unicode escape to test tab removal + /** +*Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +**eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut +***enim ad minim veniam, quis nostrud exercitation ullamco laboris +*****nisi ut aliquip ex ea commodo consequat. + \u0009*Duis aute irure dolor in reprehenderit in voluptate velit esse + **cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + ***cupidatat non proident, sunt in culpa qui officia deserunt mollit + *anim id est laborum. + */ + @ExpectedComment(""" + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis nostrud exercitation ullamco laboris + nisi ut aliquip ex ea commodo consequat. + Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit + anim id est laborum. + """) + @SuppressWarnings("") // A second preceding annotation + // End-of-line-style comment + /* + * Traditional comment over multiple lines. + */ + private void bar() {return ;} + + // Spaces _after_ the space-asterisk prefix are _not_ deleted. + /** + * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + * eiusmod tempor incididunt ut labore et dolore magna aliqua. + */ + @ExpectedComment( // Cannot used a text block here since leading spaces are removed + " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n" + + " eiusmod tempor incididunt ut labore et dolore magna aliqua.\n") + private void baz() {return ;} + + // Space after ** is removed, but not space before "*/" + /** Totality */ + @ExpectedComment("Totality ") // No newline + private void quux() {return ;} + + // Space after "**" is removed, but not trailing space later on the line + /** Totality\u0020 + */ + @ExpectedComment("Totality \n") + private void corge() {return ;} + + /** + * Totality */ + @ExpectedComment(" Totality ") // No newline + private void grault() {return ;} + + // Trailing space characters on first line + /** \u0009\u0020 + * Totality + */ + @ExpectedComment(" Totality\n") + private void wombat() {return ;} + + /** + */ + @ExpectedComment("") // No newline + private void empty() {return ;} + + /** + * tail */ + @ExpectedComment(" tail ") // No newline + private void tail() {return ;} + + /** + ****/ + @ExpectedComment("") // No newline + private void tail2() {return ;} + + // Testing of line terminators, javac implementation normalizes them: + // * newline: \u000A + // * carriage return: \u000D + // * * carriage return + newline: \u000D\u000A + /** + * Lorem\u000A\u000D\u000D\u000Aipsum + */ + @ExpectedComment(" Lorem\n\n\nipsum\n") + private void wombat2() {return ;} +}