8188035: JavaFileManager.listLocationsForModules does not always reflect values set through StandardJavaFileManager.setLocationForModule.
authorjlahoda
Thu, 19 Oct 2017 10:59:02 +0200
changeset 47363 77c792d06646
parent 47362 e729cef2af4b
child 47364 6b3389375f31
8188035: JavaFileManager.listLocationsForModules does not always reflect values set through StandardJavaFileManager.setLocationForModule. Summary: Prepending explictely set module locations in listLocationsForModules. Reviewed-by: jjg
src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
test/langtools/tools/javac/file/SetLocationForModule.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu Oct 19 09:53:53 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu Oct 19 10:59:02 2017 +0200
@@ -88,7 +88,7 @@
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.jvm.ModuleNameReader;
-import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Iterators;
 import com.sun.tools.javac.util.Pair;
 import com.sun.tools.javac.util.StringUtils;
 
@@ -964,6 +964,7 @@
         private final String name;
         private final String moduleName;
         private final boolean output;
+        boolean explicit;
         Collection<Path> searchPath;
 
         ModuleLocationHandler(LocationHandler parent, String name, String moduleName,
@@ -1083,6 +1084,14 @@
         Set<Location> locations() {
             return Collections.unmodifiableSet(nameMap.values().stream().collect(Collectors.toSet()));
         }
+
+        Set<Location> explicitLocations() {
+            return Collections.unmodifiableSet(nameMap.entrySet()
+                                                      .stream()
+                                                      .filter(e -> e.getValue().explicit)
+                                                      .map(e -> e.getValue())
+                                                      .collect(Collectors.toSet()));
+        }
     }
 
     /**
@@ -1119,10 +1128,20 @@
 
         @Override
         Iterable<Set<Location>> listLocationsForModules() {
+            Set<Location> explicitLocations = moduleTable != null ?
+                    moduleTable.explicitLocations() : Collections.emptySet();
+            Iterable<Set<Location>> explicitLocationsList = !explicitLocations.isEmpty()
+                    ? Collections.singletonList(explicitLocations)
+                    : Collections.emptyList();
+
             if (searchPath == null)
-                return Collections.emptyList();
+                return explicitLocationsList;
 
-            return ModulePathIterator::new;
+            Iterable<Set<Location>> searchPathLocations =
+                    () -> new ModulePathIterator();
+            return () -> Iterators.createCompoundIterator(Arrays.asList(explicitLocationsList,
+                                                                        searchPathLocations),
+                                                          Iterable::iterator);
         }
 
         @Override
@@ -1159,6 +1178,7 @@
                 l.searchPath = checkedPaths;
                 moduleTable.updatePaths(l);
             }
+            l.explicit = true;
         }
 
         private List<Path> checkPaths(Iterable<? extends Path> paths) throws IOException {
--- a/test/langtools/tools/javac/file/SetLocationForModule.java	Thu Oct 19 09:53:53 2017 +0200
+++ b/test/langtools/tools/javac/file/SetLocationForModule.java	Thu Oct 19 10:59:02 2017 +0200
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8173914
+ * @bug 8173914 8188035
  * @summary JavaFileManager.setLocationForModule
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -42,8 +42,10 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
 import javax.tools.JavaFileManager.Location;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
@@ -112,14 +114,35 @@
             checkEqual("override setting 1",
                     fm.getLocationAsPaths(m), override1);
 
+            checkEqual("override setting 1b",
+                       fm.getLocationAsPaths(fm.listLocationsForModules(locn).iterator().next().iterator().next()),
+                       override1);
+
+            try (StandardJavaFileManager fm2 = comp.getStandardFileManager(null, null, null)) {
+                fm2.setLocationForModule(locn, "m", List.of(override1));
+                checkEqual("override setting 2",
+                           fm2.getLocationAsPaths(m), override1);
+
+                checkEqual("override setting 2b",
+                           fm2.getLocationAsPaths(fm2.listLocationsForModules(locn).iterator().next().iterator().next()),
+                           override1);
+            }
+
             Path override2 = Files.createDirectories(base.resolve("override2"));
             fm.setLocationFromPaths(m, List.of(override2));
-            checkEqual("override setting 2",
+            checkEqual("override setting 3",
                     fm.getLocationAsPaths(m), override2);
 
             Path modules2 = Files.createDirectories(base.resolve("modules2"));
+            new JavacTask(tb)
+                    .outdir(modules2)
+                    .options("--module-source-path", src.toString())
+                    .files(tb.findJavaFiles(src))
+                    .run();
             fm.setLocationFromPaths(locn, List.of(modules2));
 
+            m = fm.getLocationForModule(locn, "m");
+
             checkEqual("updated setting",
                     fm.getLocationAsPaths(m), modules2.resolve("m"));
         }
@@ -147,6 +170,10 @@
             checkEqual("override setting 1",
                     fm.getLocationAsPaths(m), override1);
 
+            checkEqual("override setting 1b",
+                       fm.getLocationAsPaths(fm.listLocationsForModules(locn).iterator().next().iterator().next()),
+                       override1);
+
             Path override2 = Files.createDirectories(base.resolve("override2"));
             tb.writeJavaFiles(override2, "module m { }");
             fm.setLocationFromPaths(m, List.of(override2));
@@ -159,6 +186,8 @@
 //            fm.setLocationFromPaths(locn, List.of(src2));
             fm.handleOption("--module-source-path", List.of(src2.toString()).iterator());
 
+            m = fm.getLocationForModule(locn, "m");
+
             checkEqual("updated setting",
                     fm.getLocationAsPaths(m), src2.resolve("m"));
         }
@@ -181,6 +210,10 @@
             checkEqual("override setting 1",
                     fm.getLocationAsPaths(m), override1);
 
+            checkEqual("override setting 1b",
+                       fm.getLocationAsPaths(fm.listLocationsForModules(locn).iterator().next().iterator().next()),
+                       override1);
+
             Path override2 = Files.createDirectories(base.resolve("override2"));
             fm.setLocationFromPaths(m, List.of(override2));
             checkEqual("override setting 2",
@@ -189,6 +222,8 @@
             Path out2 = Files.createDirectories(base.resolve("out2"));
             fm.setLocationFromPaths(locn, List.of(out2));
 
+            m = fm.getLocationForModule(locn, "m");
+
             checkEqual("updated setting",
                     fm.getLocationAsPaths(m), out2.resolve("m"));
         }
@@ -259,6 +294,10 @@
             checkEqual("override setting 1",
                     fm.getLocationAsPaths(javaCompiler), override1);
 
+            checkEqual("override setting 1b",
+                       fm.getLocationAsPaths(findLocation(fm, fm.listLocationsForModules(locn), "java.compiler")),
+                       override1);
+
             Path override2 = Files.createDirectories(base.resolve("override2"));
             fm.setLocationFromPaths(javaCompiler, List.of(override2));
             checkEqual("override setting 2",
@@ -266,6 +305,22 @@
         }
     }
 
+    private Location findLocation(JavaFileManager fm, Iterable<Set<Location>> locations, String moduleName) {
+        for (Set<Location> locs : locations) {
+            for (Location loc : locs) {
+                try {
+                    if (moduleName.equals(fm.inferModuleName(loc))) {
+                        return loc;
+                    }
+                } catch (IOException ex) {
+                    throw new IllegalStateException(ex);
+                }
+            }
+        }
+
+        throw new IllegalStateException();
+    }
+
     @Test
     public void testTemplate(Path base) {
         // set a top default
@@ -302,7 +357,7 @@
     void checkEqual(String message, Iterable<? extends Path> found, Path... expect) {
         List<Path> fList = asList(found);
         List<Path> eList = List.of(expect);
-        if (!Objects.equals(fList, fList)) {
+        if (!Objects.equals(fList, eList)) {
             error(message + ": lists not equal\n"
                     + "expect: " + eList + "\n"
                     + " found: " + fList);