# HG changeset patch # User jjg # Date 1492463767 25200 # Node ID aec722d1b53803bfff43c99045bb479ae856eaa5 # Parent 53c70300430626f54038e18bb964f40df9f72207 8178509: MODULE_SOURCE_PATH: Implement missing methods 8178493: StandardJavaFileManager: Clarify/document the use of IllegalStateException Reviewed-by: jlahoda diff -r 53c703004306 -r aec722d1b538 langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java --- 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 diff -r 53c703004306 -r aec722d1b538 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java --- 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 paths; ModuleSourcePathLocationHandler() { super(StandardLocation.MODULE_SOURCE_PATH, @@ -1368,11 +1369,15 @@ } Map> map = new LinkedHashMap<>(); + List 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> map) { moduleTable = new ModuleTable(); map.forEach((modName, modPath) -> { boolean hasModuleInfo = modPath.stream().anyMatch(checkModuleInfo); @@ -1509,12 +1523,25 @@ @Override Collection 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 files) throws IOException { - throw new UnsupportedOperationException(); + Map> map = new LinkedHashMap<>(); + List newPaths = new ArrayList<>(); + for (Path file : files) { + add(map, file, null); + newPaths.add(file); + } + + initModuleTable(map); + paths = Collections.unmodifiableList(newPaths); } @Override diff -r 53c703004306 -r aec722d1b538 langtools/test/tools/javac/modules/ModuleSourcePathTest.java --- 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 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 locn, List ref) throws Exception { + List list = asList(locn); + if (!list.equals(ref)) { + out.println("expect: " + ref); + out.println(" found: " + list); + throw new Exception("location not as expected"); + } + } + + private List asList(Iterable iter) { + List list = new ArrayList<>(); + for (T item : iter) { + list.add(item); + } + return list; + } } diff -r 53c703004306 -r aec722d1b538 langtools/test/tools/lib/toolbox/JavacTask.java --- 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);