8176327: javac produces wrong module-info jdk-9+167
authorjjg
Mon, 24 Apr 2017 14:59:43 -0700
changeset 5932f260f1a2acf6
parent 5931 3248e421620b
child 5933 7e0ac3c3eaba
child 5934 13f457e05af0
child 5941 c4129e2ec84f
8176327: javac produces wrong module-info
8178518: Add method JavaFileManager.contains
Reviewed-by: jlahoda
src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java
src/java.compiler/share/classes/javax/tools/JavaFileManager.java
src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java
src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java
src/jdk.compiler/share/classes/com/sun/tools/javac/api/WrappingJavaFileManager.java
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java
test/tools/doclint/ProvidesTest.java
test/tools/doclint/ProvidesTest.out
test/tools/doclint/UsesTest.java
test/tools/doclint/UsesTest.out
test/tools/javac/api/TestClientCodeWrapper.java
test/tools/javac/diags/examples/FileShouldBeOnSourcePathOrPatchPath/FileShouldBeOnSourcePathOrModulePath.java
test/tools/javac/diags/examples/FileShouldBeOnSourcePathOrPatchPath/sourcepath/module-info.java
test/tools/javac/file/ModuleAndPackageLocations.java
test/tools/javac/modules/ContainsTest.java
test/tools/javac/modules/SourcePathTest.java
test/tools/javac/modules/T8158224/T8158224.java
test/tools/javac/modules/T8158224/T8158224.out
     1.1 --- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Mon Apr 24 18:58:50 2017 +0200
     1.2 +++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Mon Apr 24 14:59:43 2017 -0700
     1.3 @@ -204,4 +204,11 @@
     1.4      public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
     1.5          return fileManager.listLocationsForModules(location);
     1.6      }
     1.7 +
     1.8 +    /**
     1.9 +     * @since 9
    1.10 +     */
    1.11 +    public boolean contains(Location location, FileObject fo) throws IOException {
    1.12 +        return fileManager.contains(location, fo);
    1.13 +    }
    1.14  }
     2.1 --- a/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Mon Apr 24 18:58:50 2017 +0200
     2.2 +++ b/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Mon Apr 24 14:59:43 2017 -0700
     2.3 @@ -566,4 +566,38 @@
     2.4          throw new UnsupportedOperationException();
     2.5      }
     2.6  
     2.7 +    /**
     2.8 +     * Determines whether or not a given file object is "contained in" a specified location.
     2.9 +     *
    2.10 +     * <p>For a package-oriented location, a file object is contained in the location if there exist
    2.11 +     * values for <i>packageName</i> and <i>relativeName</i> such that either of the following
    2.12 +     * calls would return the {@link #isSameFile same} file object:
    2.13 +     * <pre>
    2.14 +     *     getFileForInput(location, <i>packageName</i>, <i>relativeName</i>)
    2.15 +     *     getFileForOutput(location, <i>packageName</i>, <i>relativeName</i>, null)
    2.16 +     * </pre>
    2.17 +     *
    2.18 +     * <p>For a module-oriented location, a file object is contained in the location if there exists
    2.19 +     * a module that may be obtained by the call:
    2.20 +     * <pre>
    2.21 +     *     getLocationForModule(location, <i>moduleName</i>)
    2.22 +     * </pre>
    2.23 +     * such that the file object is contained in the (package-oriented) location for that module.
    2.24 +     *
    2.25 +     * @implSpec This implementation throws {@code UnsupportedOperationException}.
    2.26 +     *
    2.27 +     * @param location the location
    2.28 +     * @param fo the file object
    2.29 +     * @return whether or not the file is contained in the location
    2.30 +     *
    2.31 +     * @throws IOException if there is a problem determining the result
    2.32 +     * @throws UnsupportedOperationException if the method is not supported
    2.33 +     *
    2.34 +     * @since 9
    2.35 +     */
    2.36 +
    2.37 +    default boolean contains(Location location, FileObject fo) throws IOException {
    2.38 +        throw new UnsupportedOperationException();
    2.39 +    }
    2.40 +
    2.41  }
     3.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java	Mon Apr 24 18:58:50 2017 +0200
     3.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java	Mon Apr 24 14:59:43 2017 -0700
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -32,7 +32,6 @@
    3.11  import java.util.LinkedList;
    3.12  import java.util.List;
    3.13  import java.util.Queue;
    3.14 -import java.util.regex.Pattern;
    3.15  
    3.16  import javax.lang.model.element.Name;
    3.17  import javax.tools.StandardLocation;
    3.18 @@ -148,9 +147,15 @@
    3.19  
    3.20          JavacFileManager fm = new JavacFileManager(new Context(), false, null);
    3.21          fm.setSymbolFileEnabled(false);
    3.22 -        fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, javacBootClassPath);
    3.23 -        fm.setLocation(StandardLocation.CLASS_PATH, javacClassPath);
    3.24 -        fm.setLocation(StandardLocation.SOURCE_PATH, javacSourcePath);
    3.25 +        if (javacBootClassPath != null) {
    3.26 +            fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, javacBootClassPath);
    3.27 +        }
    3.28 +        if (javacClassPath != null) {
    3.29 +            fm.setLocation(StandardLocation.CLASS_PATH, javacClassPath);
    3.30 +        }
    3.31 +        if (javacSourcePath != null) {
    3.32 +            fm.setLocation(StandardLocation.SOURCE_PATH, javacSourcePath);
    3.33 +        }
    3.34  
    3.35          JavacTask task = tool.getTask(out, fm, null, javacOpts, null,
    3.36                  fm.getJavaFileObjectsFromFiles(javacFiles));
     4.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Mon Apr 24 18:58:50 2017 +0200
     4.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Mon Apr 24 14:59:43 2017 -0700
     4.3 @@ -326,6 +326,17 @@
     4.4          }
     4.5  
     4.6          @Override @DefinedBy(Api.COMPILER)
     4.7 +        public boolean contains(Location location, FileObject file) throws IOException {
     4.8 +            try {
     4.9 +                return clientJavaFileManager.contains(location, unwrap(file));
    4.10 +            } catch (ClientCodeException e) {
    4.11 +                throw e;
    4.12 +            } catch (RuntimeException | Error e) {
    4.13 +                throw new ClientCodeException(e);
    4.14 +            }
    4.15 +        }
    4.16 +
    4.17 +        @Override @DefinedBy(Api.COMPILER)
    4.18          public void flush() throws IOException {
    4.19              try {
    4.20                  clientJavaFileManager.flush();
     5.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/WrappingJavaFileManager.java	Mon Apr 24 18:58:50 2017 +0200
     5.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/WrappingJavaFileManager.java	Mon Apr 24 14:59:43 2017 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -35,6 +35,7 @@
    5.11  import javax.tools.*;
    5.12  import javax.tools.JavaFileObject.Kind;
    5.13  
    5.14 +import com.sun.tools.javac.util.ClientCodeException;
    5.15  import com.sun.tools.javac.util.DefinedBy;
    5.16  import com.sun.tools.javac.util.DefinedBy.Api;
    5.17  
    5.18 @@ -214,4 +215,9 @@
    5.19                                             unwrap(sibling)));
    5.20      }
    5.21  
    5.22 +    @Override @DefinedBy(Api.COMPILER)
    5.23 +    public boolean contains(Location location, FileObject file) throws IOException {
    5.24 +        return super.contains(location, unwrap(file));
    5.25 +    }
    5.26 +
    5.27  }
     6.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Apr 24 18:58:50 2017 +0200
     6.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Apr 24 14:59:43 2017 -0700
     6.3 @@ -532,12 +532,52 @@
     6.4                  module = defaultModule;
     6.5              }
     6.6  
     6.7 -            for (JCCompilationUnit tree: trees) {
     6.8 +            for (JCCompilationUnit tree : trees) {
     6.9 +                if (defaultModule != syms.unnamedModule
    6.10 +                        && defaultModule.sourceLocation == StandardLocation.SOURCE_PATH
    6.11 +                        && fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
    6.12 +                    checkSourceLocation(tree, module);
    6.13 +                }
    6.14                  tree.modle = module;
    6.15              }
    6.16          }
    6.17      }
    6.18  
    6.19 +    private void checkSourceLocation(JCCompilationUnit tree, ModuleSymbol msym) {
    6.20 +        // skip check if legacy module override still in use
    6.21 +        if (legacyModuleOverride != null) {
    6.22 +            return;
    6.23 +        }
    6.24 +
    6.25 +        try {
    6.26 +            JavaFileObject fo = tree.sourcefile;
    6.27 +            if (fileManager.contains(msym.sourceLocation, fo)) {
    6.28 +                return;
    6.29 +            }
    6.30 +            if (msym.patchLocation != null && fileManager.contains(msym.patchLocation, fo)) {
    6.31 +                return;
    6.32 +            }
    6.33 +            if (fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT)) {
    6.34 +                if (fileManager.contains(StandardLocation.SOURCE_OUTPUT, fo)) {
    6.35 +                    return;
    6.36 +                }
    6.37 +            } else {
    6.38 +                if (fileManager.contains(StandardLocation.CLASS_OUTPUT, fo)) {
    6.39 +                    return;
    6.40 +                }
    6.41 +            }
    6.42 +        } catch (IOException e) {
    6.43 +            throw new Error(e);
    6.44 +        }
    6.45 +
    6.46 +        JavaFileObject prev = log.useSource(tree.sourcefile);
    6.47 +        try {
    6.48 +            log.error(tree.pos(), "file.sb.on.source.or.patch.path.for.module");
    6.49 +        } finally {
    6.50 +            log.useSource(prev);
    6.51 +        }
    6.52 +    }
    6.53 +
    6.54      private String singleModuleOverride(List<JCCompilationUnit> trees) {
    6.55          if (!fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) {
    6.56              return legacyModuleOverride;
     7.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Apr 24 18:58:50 2017 +0200
     7.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Mon Apr 24 14:59:43 2017 -0700
     7.3 @@ -946,6 +946,14 @@
     7.4          return locations.getLocation(location);
     7.5      }
     7.6  
     7.7 +    @Override @DefinedBy(Api.COMPILER)
     7.8 +    public boolean contains(Location location, FileObject fo) throws IOException {
     7.9 +        nullCheck(location);
    7.10 +        nullCheck(fo);
    7.11 +        Path p = asPath(fo);
    7.12 +        return locations.contains(location, p);
    7.13 +    }
    7.14 +
    7.15      private Path getClassOutDir() {
    7.16          return locations.getOutputLocation(CLASS_OUTPUT);
    7.17      }
     8.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Apr 24 18:58:50 2017 +0200
     8.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Apr 24 14:59:43 2017 -0700
     8.3 @@ -85,6 +85,7 @@
     8.4  import com.sun.tools.javac.util.ListBuffer;
     8.5  import com.sun.tools.javac.util.Log;
     8.6  import com.sun.tools.javac.jvm.ModuleNameReader;
     8.7 +import com.sun.tools.javac.util.Assert;
     8.8  import com.sun.tools.javac.util.Pair;
     8.9  import com.sun.tools.javac.util.StringUtils;
    8.10  
    8.11 @@ -226,6 +227,41 @@
    8.12          fsEnv = Collections.singletonMap("multi-release", multiReleaseValue);
    8.13      }
    8.14  
    8.15 +    private boolean contains(Collection<Path> searchPath, Path file) throws IOException {
    8.16 +
    8.17 +        if (searchPath == null) {
    8.18 +            return false;
    8.19 +        }
    8.20 +
    8.21 +        Path enclosingJar = null;
    8.22 +        if (file.getFileSystem().provider() == fsInfo.getJarFSProvider()) {
    8.23 +            URI uri = file.toUri();
    8.24 +            if (uri.getScheme().equals("jar")) {
    8.25 +                String ssp = uri.getSchemeSpecificPart();
    8.26 +                int sep = ssp.lastIndexOf("!");
    8.27 +                if (ssp.startsWith("file:") && sep > 0) {
    8.28 +                    enclosingJar = Paths.get(URI.create(ssp.substring(0, sep)));
    8.29 +                }
    8.30 +            }
    8.31 +        }
    8.32 +
    8.33 +        Path nf = normalize(file);
    8.34 +        for (Path p : searchPath) {
    8.35 +            Path np = normalize(p);
    8.36 +            if (np.getFileSystem() == nf.getFileSystem()
    8.37 +                    && Files.isDirectory(np)
    8.38 +                    && nf.startsWith(np)) {
    8.39 +                return true;
    8.40 +            }
    8.41 +            if (enclosingJar != null
    8.42 +                    && Files.isSameFile(enclosingJar, np)) {
    8.43 +                return true;
    8.44 +            }
    8.45 +        }
    8.46 +
    8.47 +        return false;
    8.48 +    }
    8.49 +
    8.50      /**
    8.51       * Utility class to help evaluate a path option. Duplicate entries are ignored, jar class paths
    8.52       * can be expanded.
    8.53 @@ -456,6 +492,11 @@
    8.54          Iterable<Set<Location>> listLocationsForModules() throws IOException {
    8.55              return null;
    8.56          }
    8.57 +
    8.58 +        /**
    8.59 +         * @see JavaFileManager#contains
    8.60 +         */
    8.61 +        abstract boolean contains(Path file) throws IOException;
    8.62      }
    8.63  
    8.64      /**
    8.65 @@ -611,6 +652,15 @@
    8.66  
    8.67              return Collections.singleton(moduleTable.locations());
    8.68          }
    8.69 +
    8.70 +        @Override
    8.71 +        boolean contains(Path file) throws IOException {
    8.72 +            if (moduleTable != null) {
    8.73 +                return moduleTable.contains(file);
    8.74 +            } else {
    8.75 +                return (outputDir) != null && normalize(file).startsWith(normalize(outputDir));
    8.76 +            }
    8.77 +        }
    8.78      }
    8.79  
    8.80      /**
    8.81 @@ -660,6 +710,11 @@
    8.82          protected SearchPath createPath() {
    8.83              return new SearchPath();
    8.84          }
    8.85 +
    8.86 +        @Override
    8.87 +        boolean contains(Path file) throws IOException {
    8.88 +            return Locations.this.contains(searchPath, file);
    8.89 +        }
    8.90      }
    8.91  
    8.92      /**
    8.93 @@ -879,13 +934,18 @@
    8.94          private void lazy() {
    8.95              if (searchPath == null) {
    8.96                  try {
    8.97 -                searchPath = Collections.unmodifiableCollection(computePath());
    8.98 +                    searchPath = Collections.unmodifiableCollection(computePath());
    8.99                  } catch (IOException e) {
   8.100                      // TODO: need better handling here, e.g. javac Abort?
   8.101                      throw new UncheckedIOException(e);
   8.102                  }
   8.103              }
   8.104          }
   8.105 +
   8.106 +        @Override
   8.107 +        boolean contains(Path file) throws IOException {
   8.108 +            return Locations.this.contains(searchPath, file);
   8.109 +        }
   8.110      }
   8.111  
   8.112      /**
   8.113 @@ -896,7 +956,7 @@
   8.114       * The Location can be specified to accept overriding classes from the
   8.115       * {@code --patch-module <module>=<path> } parameter.
   8.116       */
   8.117 -    private static class ModuleLocationHandler extends LocationHandler implements Location {
   8.118 +    private class ModuleLocationHandler extends LocationHandler implements Location {
   8.119          private final LocationHandler parent;
   8.120          private final String name;
   8.121          private final String moduleName;
   8.122 @@ -949,6 +1009,11 @@
   8.123          }
   8.124  
   8.125          @Override
   8.126 +        boolean contains(Path file) throws IOException {
   8.127 +            return Locations.this.contains(searchPath, file);
   8.128 +        }
   8.129 +
   8.130 +        @Override
   8.131          public String toString() {
   8.132              return name;
   8.133          }
   8.134 @@ -957,7 +1022,7 @@
   8.135      /**
   8.136       * A table of module location handlers, indexed by name and path.
   8.137       */
   8.138 -    private static class ModuleTable {
   8.139 +    private class ModuleTable {
   8.140          private final Map<String, ModuleLocationHandler> nameMap = new LinkedHashMap<>();
   8.141          private final Map<Path, ModuleLocationHandler> pathMap = new LinkedHashMap<>();
   8.142  
   8.143 @@ -1008,6 +1073,10 @@
   8.144              return nameMap.isEmpty();
   8.145          }
   8.146  
   8.147 +        boolean contains(Path file) throws IOException {
   8.148 +            return Locations.this.contains(pathMap.keySet(), file);
   8.149 +        }
   8.150 +
   8.151          Set<Location> locations() {
   8.152              return Collections.unmodifiableSet(nameMap.values().stream().collect(Collectors.toSet()));
   8.153          }
   8.154 @@ -1040,6 +1109,12 @@
   8.155          }
   8.156  
   8.157          @Override
   8.158 +        public Location getLocationForModule(Path file) {
   8.159 +            initModuleLocations();
   8.160 +            return moduleTable.get(file);
   8.161 +        }
   8.162 +
   8.163 +        @Override
   8.164          Iterable<Set<Location>> listLocationsForModules() {
   8.165              if (searchPath == null)
   8.166                  return Collections.emptyList();
   8.167 @@ -1048,6 +1123,14 @@
   8.168          }
   8.169  
   8.170          @Override
   8.171 +        boolean contains(Path file) throws IOException {
   8.172 +            if (moduleTable == null) {
   8.173 +                initModuleLocations();
   8.174 +            }
   8.175 +            return moduleTable.contains(file);
   8.176 +        }
   8.177 +
   8.178 +        @Override
   8.179          void setPaths(Iterable<? extends Path> paths) {
   8.180              if (paths != null) {
   8.181                  for (Path p: paths) {
   8.182 @@ -1592,6 +1675,11 @@
   8.183              return Collections.singleton(moduleTable.locations());
   8.184          }
   8.185  
   8.186 +        @Override
   8.187 +        boolean contains(Path file) throws IOException {
   8.188 +            return (moduleTable == null) ? false : moduleTable.contains(file);
   8.189 +        }
   8.190 +
   8.191      }
   8.192  
   8.193      private class SystemModulesLocationHandler extends BasicLocationHandler {
   8.194 @@ -1698,6 +1786,12 @@
   8.195              return Collections.singleton(moduleTable.locations());
   8.196          }
   8.197  
   8.198 +        @Override
   8.199 +        boolean contains(Path file) throws IOException {
   8.200 +            initSystemModules();
   8.201 +            return moduleTable.contains(file);
   8.202 +        }
   8.203 +
   8.204          private void initSystemModules() throws IOException {
   8.205              if (moduleTable != null)
   8.206                  return;
   8.207 @@ -1828,6 +1922,11 @@
   8.208          Iterable<Set<Location>> listLocationsForModules() throws IOException {
   8.209              return Collections.singleton(moduleTable.locations());
   8.210          }
   8.211 +
   8.212 +        @Override
   8.213 +        boolean contains(Path file) throws IOException {
   8.214 +            return moduleTable.contains(file);
   8.215 +        }
   8.216      }
   8.217  
   8.218      Map<Location, LocationHandler> handlersForLocation;
   8.219 @@ -1931,6 +2030,13 @@
   8.220          return (h == null ? null : h.listLocationsForModules());
   8.221      }
   8.222  
   8.223 +    boolean contains(Location location, Path file) throws IOException {
   8.224 +        LocationHandler h = getHandler(location);
   8.225 +        if (h == null)
   8.226 +            throw new IllegalArgumentException("unknown location");
   8.227 +        return h.contains(file);
   8.228 +    }
   8.229 +
   8.230      protected LocationHandler getHandler(Location location) {
   8.231          Objects.requireNonNull(location);
   8.232          return (location instanceof LocationHandler)
     9.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Apr 24 18:58:50 2017 +0200
     9.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Apr 24 14:59:43 2017 -0700
     9.3 @@ -947,7 +947,7 @@
     9.4      package annotations should be in file package-info.java
     9.5  
     9.6  compiler.err.no.pkg.in.module-info.java=\
     9.7 -    package clauses should not be in file module-info.java
     9.8 +    package declarations not allowed in file module-info.java
     9.9  
    9.10  # 0: symbol
    9.11  compiler.err.pkg.clashes.with.class.of.same.name=\
    9.12 @@ -1304,6 +1304,9 @@
    9.13  compiler.err.locn.invalid.arg.for.xpatch=\
    9.14      invalid argument for --patch-module option: {0}
    9.15  
    9.16 +compiler.err.file.sb.on.source.or.patch.path.for.module=\
    9.17 +    file should be on source path, or on patch path for module
    9.18 +
    9.19  #####
    9.20  
    9.21  # Fatal Errors
    10.1 --- a/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Mon Apr 24 18:58:50 2017 +0200
    10.2 +++ b/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Mon Apr 24 14:59:43 2017 -0700
    10.3 @@ -559,6 +559,11 @@
    10.4          return stdFileManager.listLocationsForModules(location);
    10.5      }
    10.6  
    10.7 +    @Override
    10.8 +    public boolean contains(Location location, FileObject file) throws IOException {
    10.9 +        return stdFileManager.contains(location, file);
   10.10 +    }
   10.11 +
   10.12      /**
   10.13       * Flushes any resources opened for output by this file manager
   10.14       * directly or indirectly.  Flushing a closed file manager has no
    11.1 --- a/test/tools/doclint/ProvidesTest.java	Mon Apr 24 18:58:50 2017 +0200
    11.2 +++ b/test/tools/doclint/ProvidesTest.java	Mon Apr 24 14:59:43 2017 -0700
    11.3 @@ -10,20 +10,20 @@
    11.4  /**
    11.5   * Invalid use of provides in class documentation.
    11.6   *
    11.7 - * @provides UsesTest
    11.8 + * @provides NotFound
    11.9   */
   11.10  public class ProvidesTest {
   11.11      /**
   11.12       * Invalid use of provides in field documentation
   11.13       *
   11.14 -     * @provides UsesTest Test description.
   11.15 +     * @provides NotFound Test description.
   11.16       */
   11.17      public int invalid_param;
   11.18  
   11.19      /**
   11.20       * Invalid use of provides in method documentation
   11.21       *
   11.22 -     * @provides UsesTest Test description.
   11.23 +     * @provides NotFound Test description.
   11.24       */
   11.25      public class InvalidParam { }
   11.26  }
    12.1 --- a/test/tools/doclint/ProvidesTest.out	Mon Apr 24 18:58:50 2017 +0200
    12.2 +++ b/test/tools/doclint/ProvidesTest.out	Mon Apr 24 14:59:43 2017 -0700
    12.3 @@ -1,28 +1,28 @@
    12.4  ProvidesTest.java:13: error: invalid use of @provides
    12.5 - * @provides UsesTest
    12.6 + * @provides NotFound
    12.7     ^
    12.8  ProvidesTest.java:13: error: service-type not found
    12.9 - * @provides UsesTest
   12.10 + * @provides NotFound
   12.11     ^
   12.12  ProvidesTest.java:13: error: reference not found
   12.13 - * @provides UsesTest
   12.14 + * @provides NotFound
   12.15               ^
   12.16  ProvidesTest.java:19: error: invalid use of @provides
   12.17 -     * @provides UsesTest Test description.
   12.18 +     * @provides NotFound Test description.
   12.19         ^
   12.20  ProvidesTest.java:19: error: service-type not found
   12.21 -     * @provides UsesTest Test description.
   12.22 +     * @provides NotFound Test description.
   12.23         ^
   12.24  ProvidesTest.java:19: error: reference not found
   12.25 -     * @provides UsesTest Test description.
   12.26 +     * @provides NotFound Test description.
   12.27                   ^
   12.28  ProvidesTest.java:26: error: invalid use of @provides
   12.29 -     * @provides UsesTest Test description.
   12.30 +     * @provides NotFound Test description.
   12.31         ^
   12.32  ProvidesTest.java:26: error: service-type not found
   12.33 -     * @provides UsesTest Test description.
   12.34 +     * @provides NotFound Test description.
   12.35         ^
   12.36  ProvidesTest.java:26: error: reference not found
   12.37 -     * @provides UsesTest Test description.
   12.38 +     * @provides NotFound Test description.
   12.39                   ^
   12.40  9 errors
    13.1 --- a/test/tools/doclint/UsesTest.java	Mon Apr 24 18:58:50 2017 +0200
    13.2 +++ b/test/tools/doclint/UsesTest.java	Mon Apr 24 14:59:43 2017 -0700
    13.3 @@ -10,20 +10,20 @@
    13.4  /**
    13.5   * Invalid use of uses in class documentation.
    13.6   *
    13.7 - * @uses ProvidesTest
    13.8 + * @uses NotFound
    13.9   */
   13.10  public class UsesTest {
   13.11      /**
   13.12       * Invalid use of uses in field documentation
   13.13       *
   13.14 -     * @uses ProvidesTest Test description.
   13.15 +     * @uses NotFound Test description.
   13.16       */
   13.17      public int invalid_param;
   13.18  
   13.19      /**
   13.20       * Invalid use of uses in method documentation
   13.21       *
   13.22 -     * @uses ProvidesTest Test description.
   13.23 +     * @uses NotFound Test description.
   13.24       */
   13.25      public class InvalidParam { }
   13.26  }
    14.1 --- a/test/tools/doclint/UsesTest.out	Mon Apr 24 18:58:50 2017 +0200
    14.2 +++ b/test/tools/doclint/UsesTest.out	Mon Apr 24 14:59:43 2017 -0700
    14.3 @@ -1,28 +1,28 @@
    14.4  UsesTest.java:13: error: invalid use of @uses
    14.5 - * @uses ProvidesTest
    14.6 + * @uses NotFound
    14.7     ^
    14.8  UsesTest.java:13: error: service-type not found
    14.9 - * @uses ProvidesTest
   14.10 + * @uses NotFound
   14.11     ^
   14.12  UsesTest.java:13: error: reference not found
   14.13 - * @uses ProvidesTest
   14.14 + * @uses NotFound
   14.15           ^
   14.16  UsesTest.java:19: error: invalid use of @uses
   14.17 -     * @uses ProvidesTest Test description.
   14.18 +     * @uses NotFound Test description.
   14.19         ^
   14.20  UsesTest.java:19: error: service-type not found
   14.21 -     * @uses ProvidesTest Test description.
   14.22 +     * @uses NotFound Test description.
   14.23         ^
   14.24  UsesTest.java:19: error: reference not found
   14.25 -     * @uses ProvidesTest Test description.
   14.26 +     * @uses NotFound Test description.
   14.27               ^
   14.28  UsesTest.java:26: error: invalid use of @uses
   14.29 -     * @uses ProvidesTest Test description.
   14.30 +     * @uses NotFound Test description.
   14.31         ^
   14.32  UsesTest.java:26: error: service-type not found
   14.33 -     * @uses ProvidesTest Test description.
   14.34 +     * @uses NotFound Test description.
   14.35         ^
   14.36  UsesTest.java:26: error: reference not found
   14.37 -     * @uses ProvidesTest Test description.
   14.38 +     * @uses NotFound Test description.
   14.39               ^
   14.40  9 errors
    15.1 --- a/test/tools/javac/api/TestClientCodeWrapper.java	Mon Apr 24 18:58:50 2017 +0200
    15.2 +++ b/test/tools/javac/api/TestClientCodeWrapper.java	Mon Apr 24 14:59:43 2017 -0700
    15.3 @@ -62,7 +62,7 @@
    15.4              defaultFileManager = fm;
    15.5  
    15.6              for (Method m: getMethodsExcept(JavaFileManager.class,
    15.7 -                        "close", "getJavaFileForInput", "getLocationForModule", "getServiceLoader")) {
    15.8 +                        "close", "getJavaFileForInput", "getLocationForModule", "getServiceLoader", "contains")) {
    15.9                  test(m);
   15.10              }
   15.11  
   15.12 @@ -424,6 +424,12 @@
   15.13              return super.listLocationsForModules(location);
   15.14          }
   15.15  
   15.16 +        @Override
   15.17 +        public boolean contains(Location location, FileObject fo) throws IOException {
   15.18 +            throwUserExceptionIfNeeded(fileManagerMethod, "contains");
   15.19 +            return super.contains(location, fo);
   15.20 +        }
   15.21 +
   15.22          public FileObject wrap(FileObject fo) {
   15.23              if (fileObjectMethod == null || fo == null)
   15.24                  return fo;
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/javac/diags/examples/FileShouldBeOnSourcePathOrPatchPath/FileShouldBeOnSourcePathOrModulePath.java	Mon Apr 24 14:59:43 2017 -0700
    16.3 @@ -0,0 +1,28 @@
    16.4 +/*
    16.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +
   16.27 +//key: compiler.err.file.sb.on.source.or.patch.path.for.module
   16.28 +
   16.29 +public class FileShouldBeOnSourcePathOrModulePath {
   16.30 +}
   16.31 +
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/tools/javac/diags/examples/FileShouldBeOnSourcePathOrPatchPath/sourcepath/module-info.java	Mon Apr 24 14:59:43 2017 -0700
    17.3 @@ -0,0 +1,25 @@
    17.4 +/*
    17.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.
   17.11 + *
   17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.15 + * version 2 for more details (a copy is included in the LICENSE file that
   17.16 + * accompanied this code).
   17.17 + *
   17.18 + * You should have received a copy of the GNU General Public License version
   17.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.21 + *
   17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.23 + * or visit www.oracle.com if you need additional information or have any
   17.24 + * questions.
   17.25 + */
   17.26 +
   17.27 +module m { }
   17.28 +
    18.1 --- a/test/tools/javac/file/ModuleAndPackageLocations.java	Mon Apr 24 18:58:50 2017 +0200
    18.2 +++ b/test/tools/javac/file/ModuleAndPackageLocations.java	Mon Apr 24 14:59:43 2017 -0700
    18.3 @@ -117,7 +117,6 @@
    18.4              assertRefused(() -> fm.getJavaFileForOutput(StandardLocation.MODULE_SOURCE_PATH, "", Kind.SOURCE, null));
    18.5              assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, "test"));
    18.6              JavaFileObject out = fm.getJavaFileForInput(StandardLocation.CLASS_OUTPUT, "test.Test", Kind.CLASS);
    18.7 -            assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, out));
    18.8              assertRefused(() -> fm.inferBinaryName(StandardLocation.MODULE_PATH, out));
    18.9              assertRefused(() -> fm.inferModuleName(StandardLocation.MODULE_SOURCE_PATH));
   18.10              assertRefused(() -> fm.list(StandardLocation.MODULE_SOURCE_PATH, "test", EnumSet.allOf(Kind.class), false));
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/tools/javac/modules/ContainsTest.java	Mon Apr 24 14:59:43 2017 -0700
    19.3 @@ -0,0 +1,169 @@
    19.4 +/*
    19.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.7 + *
    19.8 + * This code is free software; you can redistribute it and/or modify it
    19.9 + * under the terms of the GNU General Public License version 2 only, as
   19.10 + * published by the Free Software Foundation.
   19.11 + *
   19.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   19.15 + * version 2 for more details (a copy is included in the LICENSE file that
   19.16 + * accompanied this code).
   19.17 + *
   19.18 + * You should have received a copy of the GNU General Public License version
   19.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   19.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   19.21 + *
   19.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   19.23 + * or visit www.oracle.com if you need additional information or have any
   19.24 + * questions.
   19.25 + */
   19.26 +
   19.27 +/**
   19.28 + * @test
   19.29 + * @bug 8178518
   19.30 + * @summary Add method JavaFileManager.contains
   19.31 + * @library /tools/lib
   19.32 + * @modules
   19.33 + *      jdk.compiler/com.sun.tools.javac.api
   19.34 + *      jdk.compiler/com.sun.tools.javac.main
   19.35 + * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
   19.36 + * @run main ContainsTest
   19.37 + */
   19.38 +
   19.39 +import java.io.IOException;
   19.40 +import java.nio.file.FileSystem;
   19.41 +import java.nio.file.FileSystems;
   19.42 +import java.nio.file.Files;
   19.43 +import java.nio.file.Path;
   19.44 +import java.nio.file.Paths;
   19.45 +import java.util.EnumSet;
   19.46 +import java.util.List;
   19.47 +
   19.48 +import javax.tools.FileObject;
   19.49 +import javax.tools.JavaCompiler;
   19.50 +import javax.tools.JavaFileManager.Location;
   19.51 +import javax.tools.JavaFileObject;
   19.52 +import javax.tools.StandardJavaFileManager;
   19.53 +import javax.tools.StandardLocation;
   19.54 +import javax.tools.ToolProvider;
   19.55 +
   19.56 +import toolbox.JarTask;
   19.57 +import toolbox.JavacTask;
   19.58 +
   19.59 +public class ContainsTest extends ModuleTestBase {
   19.60 +    public static void main(String... args) throws Exception {
   19.61 +        ContainsTest t = new ContainsTest();
   19.62 +        t.runTests();
   19.63 +    }
   19.64 +
   19.65 +    JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
   19.66 +
   19.67 +    @Test
   19.68 +    public void testSimplePath(Path base) throws IOException {
   19.69 +        // Test that we can look up in directories in the default file system.
   19.70 +        Path src = base.resolve("src");
   19.71 +        tb.writeJavaFiles(src, "package p; class C { }");
   19.72 +        Path c = src.resolve("p/C.java");
   19.73 +        Path x = base.resolve("src2/p/C.java");
   19.74 +        try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
   19.75 +            fm.setLocationFromPaths(StandardLocation.SOURCE_PATH, List.of(src));
   19.76 +            checkContains(fm, StandardLocation.SOURCE_PATH, c, true);
   19.77 +            checkContains(fm, StandardLocation.SOURCE_PATH, x, false);
   19.78 +        }
   19.79 +    }
   19.80 +
   19.81 +    @Test
   19.82 +    public void testJarPath(Path base) throws IOException {
   19.83 +        // Test that we can look up in jar files on a search path.
   19.84 +        // In this case, the path we look up must come from open file system
   19.85 +        // as used by the file manager.
   19.86 +        Path src = base.resolve("src");
   19.87 +        tb.writeJavaFiles(src, "package p; class C { }");
   19.88 +        Path classes = Files.createDirectories(base.resolve("classes"));
   19.89 +        new JavacTask(tb)
   19.90 +            .options("-sourcepath", src.toString())
   19.91 +            .outdir(classes)
   19.92 +            .files(findJavaFiles(src))
   19.93 +            .run()
   19.94 +            .writeAll();
   19.95 +
   19.96 +        Path jar = base.resolve("classes.jar");
   19.97 +        new JarTask(tb).run("cf", jar.toString(), "-C", classes.toString(), "p");
   19.98 +
   19.99 +        Path c = src.resolve("p/C.java");
  19.100 +        Path x = base.resolve("src2/p/C.java");
  19.101 +
  19.102 +        try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
  19.103 +            fm.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(src, jar));
  19.104 +
  19.105 +            checkContains(fm, StandardLocation.CLASS_PATH, c, true);
  19.106 +            checkContains(fm, StandardLocation.CLASS_PATH, x, false);
  19.107 +
  19.108 +            JavaFileObject fo = fm.list(StandardLocation.CLASS_PATH, "p",
  19.109 +                    EnumSet.of(JavaFileObject.Kind.CLASS), false).iterator().next();
  19.110 +
  19.111 +            checkContains(fm, StandardLocation.CLASS_PATH, fo, true);
  19.112 +        }
  19.113 +    }
  19.114 +
  19.115 +    @Test
  19.116 +    public void testJarFSPath(Path base) throws IOException {
  19.117 +        // Test that we can look up in non-default file systems on the search path,
  19.118 +        // such as an open jar file system.
  19.119 +        Path src = base.resolve("src");
  19.120 +        tb.writeJavaFiles(src, "package p; class C { }");
  19.121 +        Path classes = Files.createDirectories(base.resolve("classes"));
  19.122 +        new JavacTask(tb)
  19.123 +            .options("-sourcepath", src.toString())
  19.124 +            .outdir(classes)
  19.125 +            .files(findJavaFiles(src))
  19.126 +            .run()
  19.127 +            .writeAll();
  19.128 +
  19.129 +        Path jar = base.resolve("classes.jar");
  19.130 +        new JarTask(tb).run("cf", jar.toString(), "-C", classes.toString(), "p");
  19.131 +
  19.132 +        Path c = src.resolve("p/C.java");
  19.133 +        Path x = base.resolve("src2/p/C.java");
  19.134 +
  19.135 +        try (FileSystem jarFS = FileSystems.newFileSystem(jar, null);
  19.136 +                StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
  19.137 +            Path jarRoot = jarFS.getRootDirectories().iterator().next();
  19.138 +            fm.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(src, jarRoot));
  19.139 +
  19.140 +            checkContains(fm, StandardLocation.CLASS_PATH, c, true);
  19.141 +            checkContains(fm, StandardLocation.CLASS_PATH, x, false);
  19.142 +
  19.143 +            JavaFileObject fo = fm.list(StandardLocation.CLASS_PATH, "p",
  19.144 +                    EnumSet.of(JavaFileObject.Kind.CLASS), false).iterator().next();
  19.145 +
  19.146 +            checkContains(fm, StandardLocation.CLASS_PATH, fo, true);
  19.147 +            checkContains(fm, StandardLocation.CLASS_PATH, jarRoot.resolve("p/C.class"), true);
  19.148 +        }
  19.149 +    }
  19.150 +
  19.151 +    void checkContains(StandardJavaFileManager fm, Location l, Path p, boolean expect) throws IOException {
  19.152 +        JavaFileObject fo = fm.getJavaFileObjects(p).iterator().next();
  19.153 +        checkContains(fm, l, fo, expect);
  19.154 +    }
  19.155 +
  19.156 +    void checkContains(StandardJavaFileManager fm, Location l, FileObject fo, boolean expect) throws IOException {
  19.157 +        boolean found = fm.contains(l, fo);
  19.158 +        if (found) {
  19.159 +            if (expect) {
  19.160 +                out.println("file found, as expected: " + l + " " + fo.getName());
  19.161 +            } else {
  19.162 +                error("file not found: " + l + " " + fo.getName());
  19.163 +            }
  19.164 +        } else {
  19.165 +            if (expect) {
  19.166 +                error("file found unexpectedly: " + l + " " + fo.getName());
  19.167 +            } else {
  19.168 +                out.println("file not found, as expected: " + l + " " + fo.getName());
  19.169 +            }
  19.170 +        }
  19.171 +    }
  19.172 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/tools/javac/modules/SourcePathTest.java	Mon Apr 24 14:59:43 2017 -0700
    20.3 @@ -0,0 +1,310 @@
    20.4 +/*
    20.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.
   20.11 + *
   20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.15 + * version 2 for more details (a copy is included in the LICENSE file that
   20.16 + * accompanied this code).
   20.17 + *
   20.18 + * You should have received a copy of the GNU General Public License version
   20.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.21 + *
   20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.23 + * or visit www.oracle.com if you need additional information or have any
   20.24 + * questions.
   20.25 + */
   20.26 +
   20.27 +/**
   20.28 + * @test
   20.29 + * @bug 8176327
   20.30 + * @summary javac produces wrong module-info
   20.31 + * @library /tools/lib
   20.32 + * @modules
   20.33 + *      jdk.compiler/com.sun.tools.javac.api
   20.34 + *      jdk.compiler/com.sun.tools.javac.main
   20.35 + * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
   20.36 + * @run main SourcePathTest
   20.37 + */
   20.38 +
   20.39 +import java.io.IOException;
   20.40 +import java.nio.file.FileVisitResult;
   20.41 +import java.nio.file.Files;
   20.42 +import java.nio.file.Path;
   20.43 +import java.nio.file.SimpleFileVisitor;
   20.44 +import java.nio.file.attribute.BasicFileAttributes;
   20.45 +import java.util.ArrayList;
   20.46 +import java.util.List;
   20.47 +
   20.48 +import toolbox.JavacTask;
   20.49 +import toolbox.Task;
   20.50 +
   20.51 +public class SourcePathTest extends ModuleTestBase {
   20.52 +    public static void main(String... args) throws Exception {
   20.53 +        SourcePathTest t = new SourcePathTest();
   20.54 +        t.runTests();
   20.55 +    }
   20.56 +
   20.57 +    @Test
   20.58 +    public void test_unnamedModuleOnSourcePath_fileNotOnPath(Path base) throws IOException {
   20.59 +        Path src = base.resolve("src");
   20.60 +        tb.writeJavaFiles(src, "package p; public class A { }");
   20.61 +        Path otherSrc = base.resolve("otherSrc");
   20.62 +        tb.writeJavaFiles(otherSrc, "package p2; public class B { }");
   20.63 +
   20.64 +        Path classes = base.resolve("classes");
   20.65 +        Files.createDirectories(classes);
   20.66 +
   20.67 +        new JavacTask(tb)
   20.68 +            .options("-sourcepath", src.toString())
   20.69 +            .outdir(classes)
   20.70 +            .files(findJavaFiles(otherSrc))
   20.71 +            .run()
   20.72 +            .writeAll();
   20.73 +
   20.74 +        showFiles(classes);
   20.75 +    }
   20.76 +
   20.77 +    @Test
   20.78 +    public void test_unnamedModuleOnSourcePath_fileOnPath(Path base) throws IOException {
   20.79 +        Path src = base.resolve("src");
   20.80 +        tb.writeJavaFiles(src, "package p; public class A { }");
   20.81 +
   20.82 +        Path classes = base.resolve("classes");
   20.83 +        Files.createDirectories(classes);
   20.84 +
   20.85 +        new JavacTask(tb)
   20.86 +            .options("-sourcepath", src.toString())
   20.87 +            .outdir(classes)
   20.88 +            .files(findJavaFiles(src))
   20.89 +            .run()
   20.90 +            .writeAll();
   20.91 +
   20.92 +        showFiles(classes);
   20.93 +    }
   20.94 +
   20.95 +    @Test
   20.96 +    public void test_namedModuleOnSourcePath_fileNotOnPath_1(Path base) throws Exception {
   20.97 +        Path src = base.resolve("src");
   20.98 +        tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }");
   20.99 +        tb.writeJavaFiles(src, "package p; public class A { }");
  20.100 +        Path otherSrc = base.resolve("otherSrc");
  20.101 +        tb.writeJavaFiles(otherSrc, "package p2; public class B { }");
  20.102 +
  20.103 +        Path classes = base.resolve("classes");
  20.104 +        Files.createDirectories(classes);
  20.105 +
  20.106 +        String log = new JavacTask(tb)
  20.107 +            .options("-XDrawDiagnostics=true", "-sourcepath", src.toString())
  20.108 +            .outdir(classes)
  20.109 +            .files(findJavaFiles(otherSrc))
  20.110 +            .run(Task.Expect.FAIL)
  20.111 +            .writeAll()
  20.112 +            .getOutput(Task.OutputKind.DIRECT);
  20.113 +
  20.114 +        showFiles(classes);
  20.115 +        checkOutputContains(log,
  20.116 +                "B.java:1:1: compiler.err.file.sb.on.source.or.patch.path.for.module");
  20.117 +    }
  20.118 +
  20.119 +    @Test
  20.120 +    public void test_namedModuleOnSourcePath_fileNotOnPath_2(Path base) throws Exception {
  20.121 +        // This is the original test case:
  20.122 +        // the source path contains one module, but the file to be compiled appears to be
  20.123 +        // in another module.
  20.124 +        Path src = base.resolve("src");
  20.125 +        Path src_mA = src.resolve("mA");
  20.126 +        tb.writeJavaFiles(src_mA,
  20.127 +                "module mA { exports p; }",
  20.128 +                "package p; public class A { }");
  20.129 +        Path src_mB = src.resolve("mB");
  20.130 +        tb.writeJavaFiles(src_mB,
  20.131 +                "module mA { exports p2; }",
  20.132 +                "package p2; public class B { }");
  20.133 +
  20.134 +        Path classes = base.resolve("classes");
  20.135 +        Files.createDirectories(classes);
  20.136 +
  20.137 +        String log = new JavacTask(tb)
  20.138 +            .options("-XDrawDiagnostics=true", "-sourcepath", src_mA.toString())
  20.139 +            .outdir(classes)
  20.140 +            .files(findJavaFiles(src_mB.resolve("p2")))
  20.141 +            .run(Task.Expect.FAIL)
  20.142 +            .writeAll()
  20.143 +            .getOutput(Task.OutputKind.DIRECT);
  20.144 +
  20.145 +        showFiles(classes);
  20.146 +        checkOutputContains(log,
  20.147 +                "B.java:1:1: compiler.err.file.sb.on.source.or.patch.path.for.module");
  20.148 +    }
  20.149 +
  20.150 +    @Test
  20.151 +    public void test_namedModuleOnSourcePath_fileOnPath(Path base) throws Exception {
  20.152 +        Path src = base.resolve("src");
  20.153 +        tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }");
  20.154 +        tb.writeJavaFiles(src, "package p; public class A { }");
  20.155 +
  20.156 +        Path classes = base.resolve("classes");
  20.157 +        Files.createDirectories(classes);
  20.158 +
  20.159 +        String log = new JavacTask(tb)
  20.160 +            .options("-XDrawDiagnostics=true", "-sourcepath", src.toString())
  20.161 +            .outdir(classes)
  20.162 +            .files(findJavaFiles(src.resolve("p")))
  20.163 +            .run()
  20.164 +            .writeAll()
  20.165 +            .getOutput(Task.OutputKind.DIRECT);
  20.166 +
  20.167 +        showFiles(classes);
  20.168 +    }
  20.169 +
  20.170 +    @Test
  20.171 +    public void test_namedModuleOnSourcePath_fileOnPatchPath(Path base) throws Exception {
  20.172 +        // similar to test_namedModuleOnSourcePath_fileNotOnPath_1
  20.173 +        // except that other src directory is not put on the patch path
  20.174 +        Path src = base.resolve("src");
  20.175 +        tb.writeFile(src.resolve("module-info.java"), "module m { exports p; }");
  20.176 +        tb.writeJavaFiles(src, "package p; public class A { }");
  20.177 +        Path otherSrc = base.resolve("otherSrc");
  20.178 +        tb.writeJavaFiles(otherSrc, "package p2; public class B { }");
  20.179 +
  20.180 +        Path classes = base.resolve("classes");
  20.181 +        Files.createDirectories(classes);
  20.182 +
  20.183 +        String log = new JavacTask(tb)
  20.184 +            .options("-XDrawDiagnostics=true",
  20.185 +                    "-sourcepath", src.toString(),
  20.186 +                    "--patch-module", "m=" + otherSrc)
  20.187 +            .outdir(classes)
  20.188 +            .files(findJavaFiles(otherSrc))
  20.189 +            .run()
  20.190 +            .writeAll()
  20.191 +            .getOutput(Task.OutputKind.DIRECT);
  20.192 +
  20.193 +        showFiles(classes);
  20.194 +    }
  20.195 +
  20.196 +    /*
  20.197 +     * The following tests are not for the source path, but they exercise similar test
  20.198 +     * cases for the module source path.
  20.199 +     */
  20.200 +
  20.201 +    @Test
  20.202 +    public void test_moduleSourcePath_fileNotOnPath(Path base) throws Exception {
  20.203 +        Path src = base.resolve("src");
  20.204 +        Path src_mA = src.resolve("mA");
  20.205 +        tb.writeJavaFiles(src_mA,
  20.206 +                "module mA { exports p; }",
  20.207 +                "package p; public class A { }");
  20.208 +        Path src_mB = src.resolve("mB");
  20.209 +        tb.writeJavaFiles(src_mB,
  20.210 +                "module mB { exports p2; }",
  20.211 +                "package p2; public class B { }");
  20.212 +        Path otherSrc = base.resolve("otherSrc");
  20.213 +        tb.writeJavaFiles(otherSrc, "package p3; public class C { }");
  20.214 +
  20.215 +        Path classes = base.resolve("classes");
  20.216 +        Files.createDirectories(classes);
  20.217 +
  20.218 +        String log = new JavacTask(tb)
  20.219 +            .options("-XDrawDiagnostics=true",
  20.220 +                    "--module-source-path", src.toString())
  20.221 +            .outdir(classes)
  20.222 +            .files(findJavaFiles(otherSrc))
  20.223 +            .run(Task.Expect.FAIL)
  20.224 +            .writeAll()
  20.225 +            .getOutput(Task.OutputKind.DIRECT);
  20.226 +
  20.227 +        showFiles(classes);
  20.228 +        checkOutputContains(log,
  20.229 +                "C.java:1:1: compiler.err.not.in.module.on.module.source.path");
  20.230 +    }
  20.231 +
  20.232 +    @Test
  20.233 +    public void test_moduleSourcePath_fileOnPath(Path base) throws Exception {
  20.234 +        Path src = base.resolve("src");
  20.235 +        Path src_mA = src.resolve("mA");
  20.236 +        tb.writeJavaFiles(src_mA,
  20.237 +                "module mA { exports p; }",
  20.238 +                "package p; public class A { }");
  20.239 +        Path src_mB = src.resolve("mB");
  20.240 +        tb.writeJavaFiles(src_mB,
  20.241 +                "module mB { exports p2; }",
  20.242 +                "package p2; public class B { }");
  20.243 +
  20.244 +        Path classes = base.resolve("classes");
  20.245 +        Files.createDirectories(classes);
  20.246 +
  20.247 +        String log = new JavacTask(tb)
  20.248 +            .options("-XDrawDiagnostics=true",
  20.249 +                    "--module-source-path", src.toString())
  20.250 +            .outdir(classes)
  20.251 +            .files(findJavaFiles(src_mB.resolve("p2")))
  20.252 +            .run()
  20.253 +            .writeAll()
  20.254 +            .getOutput(Task.OutputKind.DIRECT);
  20.255 +
  20.256 +        showFiles(classes);
  20.257 +
  20.258 +    }
  20.259 +
  20.260 +    @Test
  20.261 +    public void test_moduleSourcePath_fileOnPatchPath(Path base) throws Exception {
  20.262 +        // similar to test_moduleSourcePath_fileNotOnPath
  20.263 +        // except that other src directory is not put on the patch path
  20.264 +        Path src = base.resolve("src");
  20.265 +        Path src_mA = src.resolve("mA");
  20.266 +        tb.writeJavaFiles(src_mA,
  20.267 +                "module mA { exports p; }",
  20.268 +                "package p; public class A { }");
  20.269 +        Path src_mB = src.resolve("mB");
  20.270 +        tb.writeJavaFiles(src_mB,
  20.271 +                "module mB { exports p2; }",
  20.272 +                "package p2; public class B { }");
  20.273 +        Path otherSrc = base.resolve("otherSrc");
  20.274 +        tb.writeJavaFiles(otherSrc, "package p3; public class C { }");
  20.275 +
  20.276 +        Path classes = base.resolve("classes");
  20.277 +        Files.createDirectories(classes);
  20.278 +
  20.279 +        String log = new JavacTask(tb)
  20.280 +            .options("-XDrawDiagnostics=true",
  20.281 +                    "--module-source-path", src.toString(),
  20.282 +                    "--patch-module", "mA=" + otherSrc)
  20.283 +            .outdir(classes)
  20.284 +            .files(findJavaFiles(otherSrc))
  20.285 +            .run()
  20.286 +            .writeAll()
  20.287 +            .getOutput(Task.OutputKind.DIRECT);
  20.288 +
  20.289 +        showFiles(classes);
  20.290 +    }
  20.291 +
  20.292 +    /**
  20.293 +     * This method is primarily used to give visual confirmation that a test case
  20.294 +     * generated files when the compilation succeeds and so generates no other output,
  20.295 +     * such as error messages.
  20.296 +     */
  20.297 +    List<Path> showFiles(Path dir) throws IOException {
  20.298 +        List<Path> files = new ArrayList<>();
  20.299 +        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
  20.300 +            @Override
  20.301 +            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  20.302 +                    throws IOException {
  20.303 +                if (Files.isRegularFile(file)) {
  20.304 +                    out.println("Found " + file);
  20.305 +                    files.add(file);
  20.306 +                }
  20.307 +                return FileVisitResult.CONTINUE;
  20.308 +            }
  20.309 +        });
  20.310 +        return files;
  20.311 +    }
  20.312 +}
  20.313 +
    21.1 --- a/test/tools/javac/modules/T8158224/T8158224.java	Mon Apr 24 18:58:50 2017 +0200
    21.2 +++ b/test/tools/javac/modules/T8158224/T8158224.java	Mon Apr 24 14:59:43 2017 -0700
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    21.6 + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
    21.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.8   *
    21.9   * This code is free software; you can redistribute it and/or modify it
   21.10 @@ -25,8 +25,41 @@
   21.11   * @test
   21.12   * @bug 8158224
   21.13   * @summary NullPointerException in com.sun.tools.javac.comp.Modules.checkCyclicDependencies when module missing
   21.14 + * @library /tools/lib
   21.15 + * @modules
   21.16 + *      jdk.compiler/com.sun.tools.javac.api
   21.17 + *      jdk.compiler/com.sun.tools.javac.main
   21.18 + * @build toolbox.ToolBox toolbox.JavacTask
   21.19   * @build Processor
   21.20 - * @compile/fail/ref=T8158224.out -XDrawDiagnostics -processor Processor mods/foo/module-info.java
   21.21 + * @run main T8158224
   21.22   */
   21.23  
   21.24 -// No code here, this file is just to host test description.
   21.25 +// previously:
   21.26 +// @compile/fail/ref=T8158224.out -XDrawDiagnostics -processor Processor mods/foo/module-info.java
   21.27 +
   21.28 +import java.util.List;
   21.29 +import toolbox.JavacTask;
   21.30 +import toolbox.Task;
   21.31 +import toolbox.ToolBox;
   21.32 +
   21.33 +public class T8158224 {
   21.34 +    public static void main(String... args) throws Exception {
   21.35 +        ToolBox tb = new ToolBox();
   21.36 +
   21.37 +        List<String> log = new JavacTask(tb)
   21.38 +                .options("-XDrawDiagnostics",
   21.39 +                        "-processor", "Processor",
   21.40 +                        "-sourcepath", tb.testSrc + "/mods/foo",
   21.41 +                        "-classpath", tb.testClasses)
   21.42 +                .files(tb.testSrc + "/mods/foo/module-info.java")
   21.43 +                .run(Task.Expect.FAIL)
   21.44 +                .writeAll()
   21.45 +                .getOutputLines(Task.OutputKind.DIRECT);
   21.46 +
   21.47 +        if (!log.equals(List.of(
   21.48 +                "module-info.java:4:14: compiler.err.module.not.found: nonexistent",
   21.49 +                "1 error"))) {
   21.50 +            throw new Exception("Expected output not found");
   21.51 +        }
   21.52 +    }
   21.53 +}
    22.1 --- a/test/tools/javac/modules/T8158224/T8158224.out	Mon Apr 24 18:58:50 2017 +0200
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,2 +0,0 @@
    22.4 -module-info.java:4:14: compiler.err.module.not.found: nonexistent
    22.5 -1 error