jdk-24/langtools/test/jdk/javadoc/tool/modules/ModuleTestBase.java

392 lines
13 KiB
Java
Raw Normal View History

/*
* Copyright (c) 2016, 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.
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleElementVisitor9;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import toolbox.JavadocTask;
import toolbox.Task;
import toolbox.Task.Expect;
import toolbox.TestRunner;
import toolbox.ToolBox;
import static toolbox.Task.OutputKind.*;
/**
* Base class for module tests.
*/
public class ModuleTestBase extends TestRunner {
// Field Separator
private static final String FS = " ";
protected ToolBox tb;
private final Class<?> docletClass;
private Task.Result currentTask = null;
ModuleTestBase() {
super(System.err);
tb = new ToolBox();
ClassLoader cl = ModuleTestBase.class.getClassLoader();
try {
docletClass = cl.loadClass("ModuleTestBase$ModulesTesterDoclet");
} catch (ClassNotFoundException cfe) {
throw new Error(cfe);
}
}
/**
* Execute methods annotated with @Test, and throw an exception if any
* errors are reported..
*
* @throws Exception if any errors occurred
*/
protected void runTests() throws Exception {
runTests(m -> new Object[] { Paths.get(m.getName()) });
}
Task.Result execTask(String... args) {
return execTask0(false, args);
}
Task.Result execNegativeTask(String... args) {
return execTask0(true, args);
}
private Task.Result execTask0(boolean isNegative, String... args) {
JavadocTask et = new JavadocTask(tb, Task.Mode.API);
et.docletClass(docletClass);
//Arrays.asList(args).forEach((a -> System.err.println("arg: " + a)));
System.err.println(Arrays.asList(args));
currentTask = isNegative
? et.options(args).run(Expect.FAIL)
: et.options(args).run();
return currentTask;
}
Path[] findHtmlFiles(Path... paths) throws IOException {
return tb.findFiles(".html", paths);
}
boolean grep(String regex, Path file) throws Exception {
List<String> lines = tb.readAllLines(file);
List<String> foundList = tb.grep(regex, lines);
return !foundList.isEmpty();
}
String normalize(String in) {
return in.replace('\\', '/');
}
void checkModulesSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Specified", ElementKind.MODULE, arg);
}
}
void checkPackagesSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Specified", ElementKind.PACKAGE, arg);
}
}
void checkTypesSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Specified", ElementKind.CLASS, arg);
}
}
void checkModulesIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Included", ElementKind.MODULE, arg);
}
}
void checkPackagesIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Included", ElementKind.PACKAGE, arg);
}
}
void checkTypesIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Included", ElementKind.CLASS, arg);
}
}
void checkMembersSelected(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
}
}
void checkModuleMode(String mode) throws Exception {
assertPresent("^ModuleMode" + FS + mode);
}
void checkStringPresent(String regex) throws Exception {
assertPresent(regex);
}
void checkDocletOutputPresent(String category, ElementKind kind, String regex) throws Exception {
assertPresent("^" + category + " " + kind.toString() + " " + regex);
}
void assertPresent(String regex) throws Exception {
assertPresent(regex, STDOUT);
}
void assertErrorPresent(String regex) throws Exception {
assertPresent(regex, Task.OutputKind.DIRECT);
}
void assertPresent(String regex, Task.OutputKind kind) throws Exception {
List<String> foundList = tb.grep(regex, currentTask.getOutputLines(kind));
if (foundList.isEmpty()) {
dumpDocletDiagnostics();
throw new Exception(regex + " not found in: " + kind);
}
}
void dumpDocletDiagnostics() {
for (Task.OutputKind kind : Task.OutputKind.values()) {
String output = currentTask.getOutput(kind);
if (output != null && !output.isEmpty()) {
System.err.println("<" + kind + ">");
System.err.println(output);
}
}
}
void checkModulesNotSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Specified", ElementKind.MODULE, arg);
}
}
void checkPackagesNotSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Specified", ElementKind.PACKAGE, arg);
}
}
void checkTypesNotSpecified(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Specified", ElementKind.CLASS, arg);
}
}
void checkModulesNotIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Included", ElementKind.MODULE, arg);
}
}
void checkPackagesNotIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Included", ElementKind.PACKAGE, arg);
}
}
void checkTypesNotIncluded(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Included", ElementKind.CLASS, arg);
}
}
void checkMembersNotSelected(String... args) throws Exception {
for (String arg : args) {
checkDocletOutputAbsent("Selected", ElementKind.METHOD, arg);
}
}
void checkStringAbsent(String regex) throws Exception {
assertAbsent(regex);
}
void checkDocletOutputAbsent(String category, ElementKind kind, String regex) throws Exception {
assertAbsent("^" + category + FS + kind.toString() + FS + regex);
}
void assertAbsent(String regex) throws Exception {
List<String> foundList = tb.grep(regex, currentTask.getOutputLines(STDOUT));
if (!foundList.isEmpty()) {
dumpDocletDiagnostics();
throw new Exception(regex + " found in: " + STDOUT);
}
}
public static class ModulesTesterDoclet implements Doclet {
StringWriter sw = new StringWriter();
PrintWriter ps = new PrintWriter(sw);
// csv style output, for simple regex verification
void printDataSet(String header, Set<? extends Element> set) {
for (Element e : set) {
ps.print(header);
new SimpleElementVisitor9<Void, Void>() {
@Override
public Void visitModule(ModuleElement e, Void p) {
ps.print(FS);
ps.print(e.getKind());
ps.print(FS);
ps.println(e.getQualifiedName());
return null;
}
@Override
public Void visitPackage(PackageElement e, Void p) {
ps.print(FS);
ps.print(e.getKind());
ps.print(FS);
ps.println(e.getQualifiedName());
return null;
}
@Override
public Void visitType(TypeElement e, Void p) {
ps.print(FS);
ps.print(ElementKind.CLASS);
ps.print(FS);
ps.println(e.getQualifiedName());
return null;
}
@Override
protected Void defaultAction(Element e, Void p) {
Element encl = e.getEnclosingElement();
CharSequence fqn = new SimpleElementVisitor9<CharSequence, Void>() {
@Override
public CharSequence visitModule(ModuleElement e, Void p) {
return e.getQualifiedName();
}
@Override
public CharSequence visitType(TypeElement e, Void p) {
return e.getQualifiedName();
}
@Override
public CharSequence visitPackage(PackageElement e, Void p) {
return e.getQualifiedName();
}
}.visit(encl);
ps.print(FS);
ps.print(ElementKind.METHOD); // always METHOD
ps.print(FS);
ps.print(fqn);
ps.print(".");
ps.println(e.getSimpleName());
return null;
}
}.visit(e);
}
}
@Override
public boolean run(DocletEnvironment docenv) {
ps.println("ModuleMode" + FS + docenv.getModuleMode());
printDataSet("Specified", docenv.getSpecifiedElements());
printDataSet("Included", docenv.getIncludedModuleElements());
printDataSet("Included", docenv.getIncludedPackageElements());
printDataSet("Included", docenv.getIncludedTypeElements());
printDataSet("Selected", getAllSelectedElements(docenv));
System.out.println(sw);
return true;
}
Set<Element> getAllSelectedElements(DocletEnvironment docenv) {
Set<Element> result = new TreeSet<Element>((Element e1, Element e2) -> {
// some grouping by kind preferred
int rc = e1.getKind().compareTo(e2.getKind());
if (rc != 0) return rc;
rc = e1.toString().compareTo(e2.toString());
if (rc != 0) return rc;
return Integer.compare(e1.hashCode(), e2.hashCode());
});
for (ModuleElement me : docenv.getIncludedModuleElements()) {
addEnclosedElements(docenv, result, me);
}
for (PackageElement pe : docenv.getIncludedPackageElements()) {
addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
addEnclosedElements(docenv, result, pe);
}
for (TypeElement te : docenv.getIncludedTypeElements()) {
addEnclosedElements(docenv, result, te);
}
return result;
}
void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) {
List<? extends Element> elems = docenv.getSelectedElements(e.getEnclosedElements());
result.addAll(elems);
for (TypeElement t : ElementFilter.typesIn(elems)) {
addEnclosedElements(docenv, result, t);
}
}
@Override
public Set<Doclet.Option> getSupportedOptions() {
return Collections.emptySet();
}
@Override
public void init(Locale locale, Reporter reporter) {}
@Override
public String getName() {
return "ModulesTesterDoclet";
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}
}