8175560: Drop String pkgName from javax.tools.JavaFileManager.getLocationForModule(Location location, JavaFileObject fo, String pkgName)
authorjlahoda
Mon, 06 Mar 2017 13:17:33 +0100
changeset 44063 5f0cf4126949
parent 44062 9a579f258574
child 44064 ca20a5923619
8175560: Drop String pkgName from javax.tools.JavaFileManager.getLocationForModule(Location location, JavaFileObject fo, String pkgName) Reviewed-by: jjg
langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java
langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java
langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java
langtools/test/tools/javac/api/TestClientCodeWrapper.java
langtools/test/tools/javac/file/ModuleAndPackageLocations.java
langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java
--- a/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Mon Mar 06 13:17:33 2017 +0100
@@ -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
@@ -177,8 +177,8 @@
      * @since 9
      * @spec JPMS
      */
-    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        return fileManager.getLocationForModule(location, fo, pkgName);
+    public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
+        return fileManager.getLocationForModule(location, fo);
     }
 
     /**
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Mon Mar 06 13:17:33 2017 +0100
@@ -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
@@ -480,20 +480,16 @@
     }
 
     /**
-     * Gets a location for the module containing a specific file representing a Java
-     * source or class, to be found within a location, which may be either
+     * Gets a location for the module containing a specific file
+     * to be found within a location, which may be either
      * a module-oriented location or an output location.
      * The result will be an output location if the given location is
      * an output location, or it will be a package-oriented location.
      *
-     * @apiNote the package name is used to identify the position of the file object
-     * within the <em>module/package/class</em> hierarchy identified by by the location.
-     *
      * @implSpec This implementation throws {@code UnsupportedOperationException}.
      *
      * @param location the module-oriented location
      * @param fo the file
-     * @param pkgName the package name for the class(es) defined in this file
      * @return the module containing the file
      *
      * @throws IOException if an I/O error occurred
@@ -503,7 +499,7 @@
      * @since 9
      * @spec JPMS
      */
-    default Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+    default Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
         throw new UnsupportedOperationException();
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Mon Mar 06 13:17:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -359,9 +359,9 @@
         }
 
         @Override @DefinedBy(Api.COMPILER)
-        public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
             try {
-                return clientJavaFileManager.getLocationForModule(location, unwrap(fo), pkgName);
+                return clientJavaFileManager.getLocationForModule(location, unwrap(fo));
             } catch (ClientCodeException e) {
                 throw e;
             } catch (RuntimeException | Error e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Mar 06 13:17:33 2017 +0100
@@ -369,7 +369,7 @@
                     Location msplocn = getModuleLocation(tree);
                     Location plocn = fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) ?
                             fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
-                                                             tree.sourcefile, getPackageName(tree)) :
+                                                             tree.sourcefile) :
                             null;
 
                     if (plocn != null) {
@@ -385,6 +385,13 @@
                             }
                         }
                     } else if (msplocn != null) {
+                        if (tree.getModuleDecl() != null) {
+                            JavaFileObject canonical =
+                                    fileManager.getJavaFileForInput(msplocn, "module-info", Kind.SOURCE);
+                            if (canonical == null || !fileManager.isSameFile(canonical, tree.sourcefile)) {
+                                log.error(tree.pos(), Errors.ModuleNotFoundOnModuleSourcePath);
+                            }
+                        }
                         Name name = names.fromString(fileManager.inferModuleName(msplocn));
                         ModuleSymbol msym;
                         JCModuleDecl decl = tree.getModuleDecl();
@@ -512,8 +519,7 @@
 
             try {
                 Location loc =
-                        fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
-                                                         fo, getPackageName(tree));
+                        fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH, fo);
 
                 if (loc != null) {
                     override.add(fileManager.inferModuleName(loc));
@@ -532,15 +538,6 @@
         }
     }
 
-    private String getPackageName(JCCompilationUnit tree) {
-        if (tree.getModuleDecl() != null) {
-            return null;
-        } else {
-            JCPackageDecl pkg = tree.getPackage();
-            return (pkg == null) ? "" : TreeInfo.fullName(pkg.pid).toString();
-        }
-    }
-
     /**
      * Determine the location for the module on the module source path
      * or source output directory which contains a given CompilationUnit.
@@ -552,18 +549,15 @@
      * @throws IOException if there is a problem while searching for the module.
      */
     private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
-        String pkgName = getPackageName(tree);
         JavaFileObject fo = tree.sourcefile;
 
         Location loc =
-                fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
-                                                 fo, (pkgName == null) ? null : pkgName);
+                fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, fo);
         if (loc == null) {
             Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ?
                     StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT;
             loc =
-                fileManager.getLocationForModule(sourceOutput,
-                                                 fo, (pkgName == null) ? null : pkgName);
+                fileManager.getLocationForModule(sourceOutput, fo);
         }
         return loc;
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Mar 06 13:17:33 2017 +0100
@@ -977,31 +977,13 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+    public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
         checkModuleOrientedOrOutputLocation(location);
         if (!(fo instanceof PathFileObject))
             return null;
-        int depth = 1; // allow 1 for filename
-        if (pkgName != null && !pkgName.isEmpty()) {
-            depth += 1;
-            for (int i = 0; i < pkgName.length(); i++) {
-                switch (pkgName.charAt(i)) {
-                    case '/': case '.':
-                        depth++;
-                }
-            }
-        }
         Path p = Locations.normalize(((PathFileObject) fo).path);
-        int fc = p.getNameCount();
-        if (depth < fc) {
-            Path root = p.getRoot();
-            Path subpath = p.subpath(0, fc - depth);
-            Path dir = (root == null) ? subpath : root.resolve(subpath);
-            // need to find dir in location
-            return locations.getLocationForModule(location, dir);
-        } else {
-            return null;
-        }
+            // need to find p in location
+        return locations.getLocationForModule(location, p);
     }
 
     @Override @DefinedBy(Api.COMPILER)
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Mar 06 13:17:33 2017 +0100
@@ -60,6 +60,7 @@
 import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.Set;
+import java.util.function.Predicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -438,7 +439,7 @@
         /**
          * @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
          */
-        Location getLocationForModule(Path dir) throws IOException  {
+        Location getLocationForModule(Path file) throws IOException  {
             return null;
         }
 
@@ -588,8 +589,8 @@
         }
 
         @Override
-        Location getLocationForModule(Path dir) {
-            return (moduleTable == null) ? null : moduleTable.get(dir);
+        Location getLocationForModule(Path file) {
+            return (moduleTable == null) ? null : moduleTable.get(file);
         }
 
         private boolean listed;
@@ -986,7 +987,16 @@
         }
 
         ModuleLocationHandler get(Path path) {
-            return pathMap.get(path);
+            while (path != null) {
+                ModuleLocationHandler l = pathMap.get(path);
+
+                if (l != null)
+                    return l;
+
+                path = path.getParent();
+            }
+
+            return null;
         }
 
         void clear() {
@@ -1385,12 +1395,19 @@
 
             moduleTable = new ModuleTable();
             map.forEach((modName, modPath) -> {
-                String locnName = location.getName() + "[" + modName + "]";
-                ModuleLocationHandler l = new ModuleLocationHandler(this, locnName, modName,
-                        modPath, false);
-                moduleTable.add(l);
+                boolean hasModuleInfo = modPath.stream().anyMatch(checkModuleInfo);
+                if (hasModuleInfo) {
+                    String locnName = location.getName() + "[" + modName + "]";
+                    ModuleLocationHandler l = new ModuleLocationHandler(this, locnName, modName,
+                            modPath, false);
+                    moduleTable.add(l);
+                }
             });
         }
+        //where:
+            private final Predicate<Path> checkModuleInfo =
+                    p -> Files.exists(p.resolve("module-info.java"));
+
 
         private boolean isSeparator(char ch) {
             // allow both separators on Windows
@@ -1537,8 +1554,8 @@
         }
 
         @Override
-        Location getLocationForModule(Path dir) {
-            return (moduleTable == null) ? null : moduleTable.get(dir);
+        Location getLocationForModule(Path file) {
+            return (moduleTable == null) ? null : moduleTable.get(file);
         }
 
         @Override
@@ -1644,9 +1661,9 @@
         }
 
         @Override
-        Location getLocationForModule(Path dir) throws IOException {
+        Location getLocationForModule(Path file) throws IOException {
             initSystemModules();
-            return moduleTable.get(dir);
+            return moduleTable.get(file);
         }
 
         @Override
@@ -1724,6 +1741,8 @@
                 return false;
             }
 
+            moduleTable.clear();
+
             // Allow an extended syntax for --patch-module consisting of a series
             // of values separated by NULL characters. This is to facilitate
             // supporting deferred file manager options on the command line.
@@ -1775,8 +1794,8 @@
         }
 
         @Override
-        Location getLocationForModule(Path dir) throws IOException {
-            return moduleTable.get(dir);
+        Location getLocationForModule(Path file) throws IOException {
+            return moduleTable.get(file);
         }
 
         @Override
@@ -1857,9 +1876,9 @@
         return (h == null ? null : h.getLocationForModule(name));
     }
 
-    Location getLocationForModule(Location location, Path dir) throws IOException {
+    Location getLocationForModule(Location location, Path file) throws IOException {
         LocationHandler h = getHandler(location);
-        return (h == null ? null : h.getLocationForModule(dir));
+        return (h == null ? null : h.getLocationForModule(file));
     }
 
     void setLocationForModule(Location location, String moduleName,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Mon Mar 06 13:17:33 2017 +0100
@@ -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
@@ -204,8 +204,8 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        return super.getLocationForModule(location, locUnwrap(fo), pkgName);
+    public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
+        return super.getLocationForModule(location, locUnwrap(fo));
     }
 
     private static String packageNameFromFileName(String fn) {
--- a/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java	Mon Mar 06 13:17:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -686,11 +686,10 @@
 
             @Override @DefinedBy(Api.COMPILER)
             public Location getLocationForModule(Location location,
-                                                 JavaFileObject fo,
-                                                 String pkgName) throws IOException {
+                                                 JavaFileObject fo) throws IOException {
                 return fo == file
                         ? PATCH_LOCATION
-                        : super.getLocationForModule(location, fo, pkgName);
+                        : super.getLocationForModule(location, fo);
             }
 
             @Override @DefinedBy(Api.COMPILER)
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Mon Mar 06 13:17:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -545,8 +545,8 @@
     }
 
     @Override
-    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        return stdFileManager.getLocationForModule(location, fo, pkgName);
+    public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
+        return stdFileManager.getLocationForModule(location, fo);
     }
 
     @Override
--- a/langtools/test/tools/javac/api/TestClientCodeWrapper.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/test/tools/javac/api/TestClientCodeWrapper.java	Mon Mar 06 13:17:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -407,9 +407,9 @@
         }
 
         @Override
-        public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
             throwUserExceptionIfNeeded(fileManagerMethod, "getLocationForModule");
-            return super.getLocationForModule(location, fo, pkgName);
+            return super.getLocationForModule(location, fo);
         }
 
         @Override
--- a/langtools/test/tools/javac/file/ModuleAndPackageLocations.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/test/tools/javac/file/ModuleAndPackageLocations.java	Mon Mar 06 13:17:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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,7 +23,7 @@
 
 /**
  * @test
- * @bug 8171005
+ * @bug 8171005 8175560
  * @summary Verify behavior of JavaFileManager methods w.r.t. module/package oriented locations
  * @library /tools/lib
  * @modules java.compiler
@@ -99,7 +99,7 @@
             Location cOutput = fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, "c");
             JavaFileObject testFO = fm.getJavaFileForOutput(cOutput, "test.Test", Kind.CLASS, null);
             testFO.openOutputStream().close();
-            Location cOutput2 = fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, testFO, "test");
+            Location cOutput2 = fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, testFO);
 
             if (cOutput != cOutput2) {
                 throw new AssertionError("Unexpected location: " + cOutput2 + ", expected: " +cOutput);
@@ -117,7 +117,7 @@
             assertRefused(() -> fm.getJavaFileForOutput(StandardLocation.MODULE_SOURCE_PATH, "", Kind.SOURCE, null));
             assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, "test"));
             JavaFileObject out = fm.getJavaFileForInput(StandardLocation.CLASS_OUTPUT, "test.Test", Kind.CLASS);
-            assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, out, "test"));
+            assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, out));
             assertRefused(() -> fm.inferBinaryName(StandardLocation.MODULE_PATH, out));
             assertRefused(() -> fm.inferModuleName(StandardLocation.MODULE_SOURCE_PATH));
             assertRefused(() -> fm.list(StandardLocation.MODULE_SOURCE_PATH, "test", EnumSet.allOf(Kind.class), false));
@@ -131,10 +131,10 @@
             Path msp1 = msp.resolve("1");
             Path msp2 = msp.resolve("2");
 
-            Files.createDirectories(msp1.resolve("a"));
+            touch(msp1.resolve("a/module-info.java"));
             Files.createDirectories(msp1.resolve("b"));
-            Files.createDirectories(msp2.resolve("b"));
-            Files.createDirectories(msp2.resolve("c"));
+            touch(msp2.resolve("b/module-info.java"));
+            touch(msp2.resolve("c/module-info.java"));
 
             Path mp  = base.resolve("mp");
             Path mp1 = mp.resolve("1");
@@ -210,4 +210,4 @@
     }
 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java	Fri Mar 03 15:43:08 2017 -0800
+++ b/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java	Mon Mar 06 13:17:33 2017 +0100
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8165102
+ * @bug 8165102 8175560
  * @summary incorrect message from javac
  * @library /tools/lib
  * @modules
@@ -50,6 +50,27 @@
     public void testModuleNotInModuleSrcPath(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m = src.resolve("m");
+        Files.createDirectories(m);
+        Path extra = base.resolve("m");
+        tb.writeJavaFiles(extra, "module m {}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics", "--module-source-path", src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(extra))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.contains("module-info.java:1:1: compiler.err.module.not.found.on.module.source.path"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testModuleNotInPackageHierarchy(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path m = src.resolve("m");
         Path extra = m.resolve("extra");
         tb.writeJavaFiles(extra, "module m {}");
         Path classes = base.resolve("classes");