8173596: JavaCompiler.CompilationTask should support addModules
Reviewed-by: ksrini, jlahoda
--- a/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -121,7 +121,20 @@
*/
interface DocumentationTask extends Callable<Boolean> {
/**
- * Set the locale to be applied when formatting diagnostics and
+ * Adds root modules to be taken into account during module
+ * resolution.
+ * Invalid module names may cause either
+ * {@code IllegalArgumentException} to be thrown,
+ * or diagnostics to be reported when the task is started.
+ * @param moduleNames the names of the root modules
+ * @throws IllegalArgumentException may be thrown for some
+ * invalid module names
+ * @throws IllegalStateException if the task has started
+ */
+ void addModules(Iterable<String> moduleNames);
+
+ /**
+ * Sets the locale to be applied when formatting diagnostics and
* other localized data.
*
* @param locale the locale to apply; {@code null} means apply no
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -25,7 +25,6 @@
package javax.tools;
-import java.io.File;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
@@ -296,6 +295,18 @@
* {@linkplain #setProcessors setProcessors} method.
*/
interface CompilationTask extends Callable<Boolean> {
+ /**
+ * Adds root modules to be taken into account during module
+ * resolution.
+ * Invalid module names may cause either
+ * {@code IllegalArgumentException} to be thrown,
+ * or diagnostics to be reported when the task is started.
+ * @param moduleNames the names of the root modules
+ * @throws IllegalArgumentException may be thrown for some
+ * invalid module names
+ * @throws IllegalStateException if the task has started
+ */
+ void addModules(Iterable<String> moduleNames);
/**
* Sets processors (for annotation processing). This will
@@ -307,7 +318,7 @@
void setProcessors(Iterable<? extends Processor> processors);
/**
- * Set the locale to be applied when formatting diagnostics and
+ * Sets the locale to be applied when formatting diagnostics and
* other localized data.
*
* @param locale the locale to apply; {@code null} means apply no
@@ -330,6 +341,7 @@
* in user code.
* @throws IllegalStateException if called more than once
*/
+ @Override
Boolean call();
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -155,6 +155,11 @@
}
@Override @DefinedBy(Api.COMPILER)
+ public void addModules(Iterable<String> moduleNames) {
+ throw new IllegalStateException();
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
public void setProcessors(Iterable<? extends Processor> processors) {
throw new IllegalStateException();
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -33,17 +33,12 @@
import javax.annotation.processing.Processor;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.ElementFilter;
import javax.tools.*;
-import javax.tools.JavaFileObject.Kind;
import com.sun.source.tree.*;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.main.*;
@@ -82,6 +77,7 @@
private ListBuffer<Env<AttrContext>> genList;
private final AtomicBoolean used = new AtomicBoolean();
private Iterable<? extends Processor> processors;
+ private ListBuffer<String> addModules = new ListBuffer<>();
protected JavacTaskImpl(Context context) {
super(context, true);
@@ -101,7 +97,7 @@
prepareCompiler(false);
if (compiler.errorCount() > 0)
return Main.Result.ERROR;
- compiler.compile(args.getFileObjects(), args.getClassNames(), processors);
+ compiler.compile(args.getFileObjects(), args.getClassNames(), processors, addModules);
return (compiler.errorCount() > 0) ? Main.Result.ERROR : Main.Result.OK; // FIXME?
}, Main.Result.SYSERR, Main.Result.ABNORMAL);
} finally {
@@ -114,6 +110,18 @@
}
@Override @DefinedBy(Api.COMPILER)
+ public void addModules(Iterable<String> moduleNames) {
+ Objects.requireNonNull(moduleNames);
+ // not mt-safe
+ if (used.get())
+ throw new IllegalStateException();
+ for (String m : moduleNames) {
+ Objects.requireNonNull(m);
+ addModules.add(m);
+ }
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
public void setProcessors(Iterable<? extends Processor> processors) {
Objects.requireNonNull(processors);
// not mt-safe
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Feb 15 14:12:29 2017 -0800
@@ -888,7 +888,7 @@
public void compile(List<JavaFileObject> sourceFileObject)
throws Throwable {
- compile(sourceFileObject, List.nil(), null);
+ compile(sourceFileObject, List.nil(), null, List.nil());
}
/**
@@ -898,10 +898,13 @@
* @param classnames class names to process for annotations
* @param processors user provided annotation processors to bypass
* discovery, {@code null} means that no processors were provided
+ * @param addModules additional root modules to be used during
+ * module resolution.
*/
public void compile(Collection<JavaFileObject> sourceFileObjects,
Collection<String> classnames,
- Iterable<? extends Processor> processors)
+ Iterable<? extends Processor> processors,
+ Collection<String> addModules)
{
if (!taskListener.isEmpty()) {
taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION));
@@ -932,6 +935,10 @@
}
}
+ for (String moduleName : addModules) {
+ modules.addExtraAddModules(moduleName);
+ }
+
// These method calls must be chained to avoid memory leaks
processAnnotations(
enterTrees(
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -304,7 +304,7 @@
}
try {
- comp.compile(args.getFileObjects(), args.getClassNames(), null);
+ comp.compile(args.getFileObjects(), args.getClassNames(), null, List.nil());
if (log.expectDiagKeys != null) {
if (log.expectDiagKeys.isEmpty()) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -25,15 +25,20 @@
package jdk.javadoc.internal.api;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Locale;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.tools.DocumentationTool.DocumentationTask;
import javax.tools.JavaFileObject;
+import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Options;
import jdk.javadoc.internal.tool.Start;
/**
@@ -53,6 +58,7 @@
private Iterable<String> options;
private Iterable<? extends JavaFileObject> fileObjects;
private Locale locale;
+ private List<String> addModules = new ArrayList<>();
public JavadocTaskImpl(Context context, Class<?> docletClass,
Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
@@ -72,6 +78,16 @@
this.locale = locale;
}
+ @Override
+ public void addModules(Iterable<String> moduleNames) {
+ nullCheck(moduleNames);
+ if (used.get())
+ throw new IllegalStateException();
+ for (String name : moduleNames) {
+ addModules.add(name);
+ }
+ }
+
public Boolean call() {
if (!used.getAndSet(true)) {
initContext();
@@ -89,6 +105,12 @@
private void initContext() {
//initialize compiler's default locale
context.put(Locale.class, locale);
+ if (!addModules.isEmpty()) {
+ String names = String.join(",", addModules);
+ Options opts = Options.instance(context);
+ String prev = opts.get(Option.ADD_MODULES);
+ opts.put(Option.ADD_MODULES, (prev == null) ? names : prev + "," + names);
+ }
}
private static <T> Iterable<T> nullCheck(Iterable<T> items) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/api/basic/AddModulesTest.java Wed Feb 15 14:12:29 2017 -0800
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 2017, 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 8173596
+ * @summary DocumentationTool.DocumentationTask should support addModules
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build APITest toolbox.JavacTask toolbox.ToolBox
+ * @run main AddModulesTest
+ */
+
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.DocumentationTool.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import toolbox.Assert;
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+/**
+ * Tests for DocumentationTask.addModules method.
+ */
+public class AddModulesTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new AddModulesTest().run();
+ }
+
+ private final ToolBox tb = new ToolBox();
+
+ /**
+ * Verify that addModules works as expected.
+ */
+ @Test
+ public void testAddModules() throws Exception {
+ Path base = Paths.get("testAddModules");
+ Path src = base.resolve("src");
+
+ // setup some utility modules
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports p1; }",
+ "package p1; public class C1 { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { exports p2; }",
+ "package p2; public class C2 { }");
+ Path modules = base.resolve("modules");
+ tb.createDirectories(modules);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(modules)
+ .files(tb.findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ // now test access to the modules
+ Path src2 = base.resolve("src2");
+ tb.writeJavaFiles(src2,
+ "public class Dummy { p1.C1 c1; p2.C2 c2; }");
+ Path api = base.resolve("api");
+ tb.createDirectories(api);
+
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
+ fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules));
+ fm.setLocationFromPaths(Location.DOCUMENTATION_OUTPUT, Arrays.asList(api));
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(tb.findJavaFiles(src2));
+
+ for (boolean useOption : new boolean[] { false, true }) {
+ System.err.println("Use --add-modules option: " + useOption);
+ StringWriter sw = new StringWriter();
+ DocumentationTask t = tool.getTask(sw, fm, null, null, null, files);
+ if (useOption) {
+ t.addModules(Arrays.asList("m1x", "m2x"));
+ }
+ String out;
+ boolean ok;
+ try {
+ ok = t.call();
+ } finally {
+ out = sw.toString();
+ System.err.println(out);
+ }
+ System.err.println("ok: " + ok);
+ boolean expectErrors = !useOption;
+ check(out, "package p1 is not visible", expectErrors);
+ check(out, "package p2 is not visible", expectErrors);
+ System.err.println();
+ }
+ }
+ }
+
+ void check(String out, String text, boolean expected) {
+ System.err.println("Checking for "
+ + (expected ? "expected" : "unexpected")
+ + " text: " + text);
+
+ if (expected) {
+ if (!out.contains(text)) {
+ error("expected text not found: " + text);
+ }
+ } else {
+ if (out.contains(text)) {
+ error("unexpected text found: " + text);
+ }
+ }
+ }
+}
+
--- a/langtools/test/tools/javac/modules/AddModulesTest.java Wed Feb 15 11:55:16 2017 -0800
+++ b/langtools/test/tools/javac/modules/AddModulesTest.java Wed Feb 15 14:12:29 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,17 +23,27 @@
/*
* @test
+ * @bug 8167975 8173596
* @summary Test the --add-modules option
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.Assert toolbox.ToolBox toolbox.JavacTask ModuleTestBase
* @run main AddModulesTest
*/
import java.nio.file.Path;
+import java.util.Arrays;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import toolbox.Assert;
import toolbox.JavacTask;
import toolbox.Task;
@@ -227,5 +237,46 @@
.run()
.writeAll();
}
+
+ @Test
+ public void testAddModulesAPI(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ // setup some utility modules
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports p1; }",
+ "package p1; public class C1 { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { exports p2; }",
+ "package p2; public class C2 { }");
+ Path modules = base.resolve("modules");
+ tb.createDirectories(modules);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(modules)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ // now test access to the modules
+ Path src2 = base.resolve("src2");
+ tb.writeJavaFiles(src2,
+ "class Dummy { p1.C1 c1; p2.C2 c2; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
+ fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules));
+ fm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Arrays.asList(classes));
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(src2));
+ CompilationTask t = c.getTask(null, fm, null, null, null, files);
+ t.addModules(Arrays.asList("m1x", "m2x"));
+ Assert.check(t.call());
+ }
+ }
}