8178509: MODULE_SOURCE_PATH: Implement missing methods
8178493: StandardJavaFileManager: Clarify/document the use of IllegalStateException
Reviewed-by: jlahoda
--- a/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java Fri Apr 14 17:23:55 2017 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java Mon Apr 17 14:16:07 2017 -0700
@@ -364,7 +364,8 @@
* @return a list of files or {@code null} if this location has no
* associated search path
* @throws IllegalStateException if any element of the search path
- * cannot be converted to a {@linkplain File}.
+ * cannot be converted to a {@linkplain File}, or if the search path
+ * cannot be represented as a simple series of files.
*
* @see #setLocation
* @see Path#toFile
@@ -382,6 +383,8 @@
* @param location a location
* @return a list of paths or {@code null} if this location has no
* associated search path
+ * @throws IllegalStateException if the search path cannot be represented
+ * as a simple series of paths.
*
* @see #setLocationFromPaths
* @since 9
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Fri Apr 14 17:23:55 2017 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Mon Apr 17 14:16:07 2017 -0700
@@ -1349,6 +1349,7 @@
private class ModuleSourcePathLocationHandler extends BasicLocationHandler {
private ModuleTable moduleTable;
+ private List<Path> paths;
ModuleSourcePathLocationHandler() {
super(StandardLocation.MODULE_SOURCE_PATH,
@@ -1368,11 +1369,15 @@
}
Map<String, List<Path>> map = new LinkedHashMap<>();
+ List<Path> noSuffixPaths = new ArrayList<>();
+ boolean anySuffix = false;
final String MARKER = "*";
for (String seg: segments) {
int markStart = seg.indexOf(MARKER);
if (markStart == -1) {
- add(map, getPath(seg), null);
+ Path p = getPath(seg);
+ add(map, p, null);
+ noSuffixPaths.add(p);
} else {
if (markStart == 0 || !isSeparator(seg.charAt(markStart - 1))) {
throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
@@ -1387,11 +1392,20 @@
throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
} else {
suffix = getPath(seg.substring(markEnd + 1));
+ anySuffix = true;
}
add(map, prefix, suffix);
+ if (suffix == null) {
+ noSuffixPaths.add(prefix);
+ }
}
}
+ initModuleTable(map);
+ paths = anySuffix ? null : noSuffixPaths;
+ }
+
+ private void initModuleTable(Map<String, List<Path>> map) {
moduleTable = new ModuleTable();
map.forEach((modName, modPath) -> {
boolean hasModuleInfo = modPath.stream().anyMatch(checkModuleInfo);
@@ -1509,12 +1523,25 @@
@Override
Collection<Path> getPaths() {
- throw new UnsupportedOperationException();
+ if (paths == null) {
+ // This may occur for a complex setting with --module-source-path option
+ // i.e. one that cannot be represented by a simple series of paths.
+ throw new IllegalStateException("paths not available");
+ }
+ return paths;
}
@Override
void setPaths(Iterable<? extends Path> files) throws IOException {
- throw new UnsupportedOperationException();
+ Map<String, List<Path>> map = new LinkedHashMap<>();
+ List<Path> newPaths = new ArrayList<>();
+ for (Path file : files) {
+ add(map, file, null);
+ newPaths.add(file);
+ }
+
+ initModuleTable(map);
+ paths = Collections.unmodifiableList(newPaths);
}
@Override
--- a/langtools/test/tools/javac/modules/ModuleSourcePathTest.java Fri Apr 14 17:23:55 2017 -0700
+++ b/langtools/test/tools/javac/modules/ModuleSourcePathTest.java Mon Apr 17 14:16:07 2017 -0700
@@ -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
@@ -37,11 +37,18 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
import toolbox.JavacTask;
import toolbox.Task;
import toolbox.ToolBox;
@@ -442,6 +449,76 @@
}
}
+ @Test
+ public void setLocation(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src.resolve("m1x"), "module m1x { }", "package a; class A { }");
+ Path modules = base.resolve("modules");
+ tb.createDirectories(modules);
+
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
+ fm.setLocationFromPaths(StandardLocation.MODULE_SOURCE_PATH, List.of(src));
+ new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .fileManager(fm)
+ .outdir(modules)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ checkFiles(modules.resolve("m1x/module-info.class"), modules.resolve("m1x/a/A.class"));
+ }
+ }
+
+ @Test
+ public void getLocation_valid(Path base) throws Exception {
+ Path src1 = base.resolve("src1");
+ tb.writeJavaFiles(src1.resolve("m1x"), "module m1x { }", "package a; class A { }");
+ Path src2 = base.resolve("src2");
+ tb.writeJavaFiles(src1.resolve("m2x"), "module m2x { }", "package b; class B { }");
+
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
+ fm.setLocationFromPaths(StandardLocation.MODULE_SOURCE_PATH, List.of(src1, src2));
+ checkLocation(fm.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH), List.of(src1, src2));
+ }
+ }
+
+ @Test
+ public void getLocation_ISA(Path base) throws Exception {
+ Path src1 = base.resolve("src1");
+ tb.writeJavaFiles(src1.resolve("m1x"), "module m1x { }", "package a; class A { }");
+ Path src2 = base.resolve("src2");
+ tb.writeJavaFiles(src2.resolve("m2x").resolve("extra"), "module m2x { }", "package b; class B { }");
+ Path modules = base.resolve("modules");
+ tb.createDirectories(modules);
+
+ String FS = File.separator;
+ String PS = File.pathSeparator;
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
+ fm.handleOption("--module-source-path",
+ List.of(src1 + PS + src2 + FS + "*" + FS + "extra").iterator());
+
+ try {
+ Iterable<? extends Path> paths = fm.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH);
+ out.println("result: " + asList(paths));
+ throw new Exception("expected IllegalStateException not thrown");
+ } catch (IllegalStateException e) {
+ out.println("Exception thrown, as expected: " + e);
+ }
+
+ // even if we can't do getLocation for the MODULE_SOURCE_PATH, we should be able
+ // to do getLocation for the modules, which will additionally confirm the option
+ // was effective as intended.
+ Location locn1 = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, "m1x");
+ checkLocation(fm.getLocationAsPaths(locn1), List.of(src1.resolve("m1x")));
+ Location locn2 = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, "m2x");
+ checkLocation(fm.getLocationAsPaths(locn2), List.of(src2.resolve("m2x").resolve("extra")));
+ }
+ }
+
private void generateModules(Path base, String... paths) throws IOException {
for (int i = 0; i < paths.length; i++) {
String moduleName = "m" + i + "x";
@@ -455,8 +532,25 @@
private void checkFiles(Path... files) throws Exception {
for (Path file : files) {
if (!Files.exists(file)) {
- throw new Exception("File not exists: " + file);
+ throw new Exception("File not found: " + file);
}
}
}
+
+ private void checkLocation(Iterable<? extends Path> locn, List<Path> ref) throws Exception {
+ List<Path> list = asList(locn);
+ if (!list.equals(ref)) {
+ out.println("expect: " + ref);
+ out.println(" found: " + list);
+ throw new Exception("location not as expected");
+ }
+ }
+
+ private <T> List<T> asList(Iterable<? extends T> iter) {
+ List<T> list = new ArrayList<>();
+ for (T item : iter) {
+ list.add(item);
+ }
+ return list;
+ }
}
--- a/langtools/test/tools/lib/toolbox/JavacTask.java Fri Apr 14 17:23:55 2017 -0700
+++ b/langtools/test/tools/lib/toolbox/JavacTask.java Mon Apr 17 14:16:07 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -287,10 +287,13 @@
rc = runAPI(direct.pw);
break;
case CMDLINE:
+ if (fileManager != null) {
+ throw new IllegalStateException("file manager set in CMDLINE mode");
+ }
rc = runCommand(direct.pw);
break;
default:
- throw new IllegalStateException();
+ throw new IllegalStateException("unknown mode " + mode);
}
} catch (IOException e) {
toolBox.out.println("Exception occurred: " + e);