8144226: Sjavac's handling of include/exclude patterns is buggy, redundant and inconsistent
authoralundblad
Fri, 08 Jan 2016 17:14:10 +0100
changeset 34991 ff8be37d1164
parent 34918 80f67512daa1
child 34992 eaba62b5d8e2
8144226: Sjavac's handling of include/exclude patterns is buggy, redundant and inconsistent Summary: Rewrote sjavac include/exclude pattern handling. Reviewed-by: jlahoda
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java
langtools/test/tools/sjavac/CompileExcludingDependency.java
langtools/test/tools/sjavac/CompileWithAtFile.java
langtools/test/tools/sjavac/CompileWithInvisibleSources.java
langtools/test/tools/sjavac/CompileWithOverrideSources.java
langtools/test/tools/sjavac/ExclPattern.java
langtools/test/tools/sjavac/HiddenFiles.java
langtools/test/tools/sjavac/IncludeExcludePatterns.java
langtools/test/tools/sjavac/OptionDecoding.java
langtools/test/tools/sjavac/Serialization.java
langtools/test/tools/sjavac/util/OptionTestUtil.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Fri Jan 08 17:14:10 2016 +0100
@@ -26,11 +26,20 @@
 package com.sun.tools.sjavac;
 
 import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Set;
 import java.util.Collections;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.regex.PatternSyntaxException;
 
 /** A Source object maintains information about a source file.
  * For example which package it belongs to and kind of source it is.
@@ -56,8 +65,6 @@
     private long lastModified;
     // The source File.
     private File file;
-    // The source root under which file resides.
-    private File root;
     // If the source is generated.
     private boolean isGenerated;
     // If the source is only linked to, not compiled.
@@ -78,7 +85,7 @@
         return name.hashCode();
     }
 
-    public Source(Module m, String n, File f, File r) {
+    public Source(Module m, String n, File f) {
         name = n;
         int dp = n.lastIndexOf(".");
         if (dp != -1) {
@@ -87,7 +94,6 @@
             suffix = "";
         }
         file = f;
-        root = r;
         lastModified = f.lastModified();
         linkedOnly = false;
     }
@@ -102,7 +108,6 @@
             suffix = "";
         }
         file = null;
-        root = null;
         lastModified = lm;
         linkedOnly = false;
         int ls = n.lastIndexOf('/');
@@ -112,7 +117,6 @@
     public String suffix() { return suffix; }
     public Package pkg() { return pkg; }
     public File   file() { return file; }
-    public File   root() { return root; }
     public long lastModified() {
         return lastModified;
     }
@@ -183,225 +187,122 @@
      */
     static public void scanRoot(File root,
                                 Set<String> suffixes,
-                                List<String> excludes, List<String> includes,
-                                List<String> excludeFiles, List<String> includeFiles,
+                                List<String> excludes,
+                                List<String> includes,
                                 Map<String,Source> foundFiles,
                                 Map<String,Module> foundModules,
-                                Module currentModule,
+                                final Module currentModule,
                                 boolean permitSourcesWithoutPackage,
                                 boolean inGensrc,
                                 boolean inLinksrc)
-        throws ProblemException {
+                                        throws IOException, ProblemException {
+
+        if (root == null)
+            return;
+
+        FileSystem fs = root.toPath().getFileSystem();
+
+        if (includes.isEmpty()) {
+            includes = Collections.singletonList("**");
+        }
+
+        List<PathMatcher> includeMatchers = createPathMatchers(fs, includes);
+        List<PathMatcher> excludeMatchers = createPathMatchers(fs, excludes);
 
-        if (root == null) return;
-        int root_prefix = root.getPath().length()+1;
-        // This is the root source directory, it must not contain any Java sources files
-        // because we do not allow Java source files without a package.
-        // (Unless of course --permit-sources-without-package has been specified.)
-        // It might contain other source files however, (for -tr and -copy) these will
-        // always be included, since no package pattern can match the root directory.
-        currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
-                                       excludeFiles, includeFiles,
-                                       foundFiles, foundModules, currentModule,
-                                       inGensrc, inLinksrc);
+        Files.walkFileTree(root.toPath(), new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+
+                Path relToRoot = root.toPath().relativize(file);
 
-        File[] dirfiles = root.listFiles();
-        for (File d : dirfiles) {
-            if (d.isDirectory()) {
-                // Descend into the directory structure.
-                scanDirectory(d, root_prefix, root, suffixes,
-                              excludes, includes, excludeFiles, includeFiles,
-                              foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
-            }
-        }
-    }
+                if (includeMatchers.stream().anyMatch(im -> im.matches(relToRoot))
+                        && excludeMatchers.stream().noneMatch(em -> em.matches(relToRoot))
+                        && suffixes.contains(Util.fileSuffix(file))) {
+
+                    // TODO: Test this.
+                    Source existing = foundFiles.get(file);
+                    if (existing != null) {
+                        throw new IOException("You have already added the file "+file+" from "+existing.file().getPath());
+                    }
+                    existing = currentModule.lookupSource(file.toString());
+                    if (existing != null) {
 
-    /**
-     * Test if a path matches any of the patterns given.
-     * The pattern foo/bar matches only foo/bar
-     * The pattern foo/* matches foo/bar and foo/bar/zoo etc
-     */
-    static private boolean hasMatch(String path, List<String> patterns) {
-
-        // Convert Windows '\' to '/' for the sake of comparing with the patterns
-        path = path.replace(File.separatorChar, '/');
+                            // Oups, the source is already added, could be ok, could be not, lets check.
+                            if (inLinksrc) {
+                                // So we are collecting sources for linking only.
+                                if (existing.isLinkedOnly()) {
+                                    // Ouch, this one is also for linking only. Bad.
+                                    throw new IOException("You have already added the link only file " + file + " from " + existing.file().getPath());
+                                }
+                                // Ok, the existing source is to be compiled. Thus this link only is redundant
+                                // since all compiled are also linked to. Continue to the next source.
+                                // But we need to add the source, so that it will be visible to linking,
+                                // if not the multi core compile will fail because a JavaCompiler cannot
+                                // find the necessary dependencies for its part of the source.
+                                foundFiles.put(file.toString(), existing);
+                            } else {
+                                // We are looking for sources to compile, if we find an existing to be compiled
+                                // source with the same name, it is an internal error, since we must
+                                // find the sources to be compiled before we find the sources to be linked to.
+                                throw new IOException("Internal error: Double add of file " + file + " from " + existing.file().getPath());
+                            }
 
-        for (String p : patterns) {
-            // Exact match
-            if (p.equals(path))
-                return true;
+                    } else {
 
-            // Single dot the end matches this package and all its subpackages.
-            if (p.endsWith("/*")) {
-                // Remove the wildcard
-                String patprefix = p.substring(0,p.length()-2);
-                // Does the path start with the pattern prefix?
-                if (path.startsWith(patprefix)) {
-                    // If the path has the same length as the pattern prefix, then it is a match.
-                    // If the path is longer, then make sure that
-                    // the next part of the path starts with a dot (.) to prevent
-                    // wildcard matching in the middle of a package name.
-                    if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='/') {
-                        return true;
+                        //////////////////////////////////////////////////////////////
+                        // Add source
+                        Source s = new Source(currentModule, file.toString(), file.toFile());
+                        if (inGensrc) {
+                            s.markAsGenerated();
+                        }
+                        if (inLinksrc) {
+                            s.markAsLinkedOnly();
+                        }
+                        String pkg = packageOfJavaFile(root.toPath(), file);
+                        pkg = currentModule.name() + ":" + pkg;
+                        foundFiles.put(file.toString(), s);
+                        currentModule.addSource(pkg, s);
+                        //////////////////////////////////////////////////////////////
                     }
                 }
+
+                return FileVisitResult.CONTINUE;
             }
-        }
-        return false;
-    }
-
-    /**
-     * Matches patterns with the asterisk first. */
-     // The pattern foo/bar.java only matches foo/bar.java
-     // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
-    static private boolean hasFileMatch(String path, List<String> patterns) {
-        // Convert Windows '\' to '/' for the sake of comparing with the patterns
-        path = path.replace(File.separatorChar, '/');
-
-        path = Util.normalizeDriveLetter(path);
-        for (String p : patterns) {
-            // Exact match
-            if (p.equals(path)) {
-                return true;
-            }
-            // Single dot the end matches this package and all its subpackages.
-            if (p.startsWith("*")) {
-                // Remove the wildcard
-                String patsuffix = p.substring(1);
-                // Does the path start with the pattern prefix?
-                if (path.endsWith(patsuffix)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+        });
     }
 
-    /**
-     * Add the files in the directory, assuming that the file has not been excluded.
-     * Returns a fresh Module object, if this was a dir with a module-info.java file.
-     */
-    static private Module addFilesInDir(File dir, int rootPrefix, File root,
-                                        Set<String> suffixes, boolean allow_javas,
-                                        List<String> excludeFiles, List<String> includeFiles,
-                                        Map<String,Source> foundFiles,
-                                        Map<String,Module> foundModules,
-                                        Module currentModule,
-                                        boolean inGensrc,
-                                        boolean inLinksrc)
-        throws ProblemException
-    {
-        for (File f : dir.listFiles()) {
-
-            if (!f.isFile())
-                continue;
-
-            boolean should_add =
-                (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
-                && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
-
-            if (!should_add)
-                continue;
-
-            if (!allow_javas && f.getName().endsWith(".java")) {
-                throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
-                                           ", please remove "+f.getName());
-            }
-            // Extract the file name relative the root.
-            String fn = f.getPath().substring(rootPrefix);
-            // Extract the package name.
-            int sp = fn.lastIndexOf(File.separatorChar);
-            String pkg = "";
-            if (sp != -1) {
-                pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
-            }
-            // Is this a module-info.java file?
-            if (fn.endsWith("module-info.java")) {
-                // Aha! We have recursed into a module!
-                if (!currentModule.name().equals("")) {
-                    throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
-                }
-                String module_name = fn.substring(0,fn.length()-16);
-                currentModule = new Module(module_name, f.getPath());
-                foundModules.put(module_name, currentModule);
-            }
-            // Extract the suffix.
-            int dp = fn.lastIndexOf(".");
-            String suffix = "";
-            if (dp > 0) {
-                suffix = fn.substring(dp);
-            }
-            // Should the file be added?
-            if (suffixes.contains(suffix)) {
-                Source of = foundFiles.get(f.getPath());
-                if (of != null) {
-                    throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
-                }
-                of = currentModule.lookupSource(f.getPath());
-                if (of != null) {
-                    // Oups, the source is already added, could be ok, could be not, lets check.
-                    if (inLinksrc) {
-                        // So we are collecting sources for linking only.
-                        if (of.isLinkedOnly()) {
-                            // Ouch, this one is also for linking only. Bad.
-                            throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
-                        }
-                        // Ok, the existing source is to be compiled. Thus this link only is redundant
-                        // since all compiled are also linked to. Continue to the next source.
-                        // But we need to add the source, so that it will be visible to linking,
-                        // if not the multi core compile will fail because a JavaCompiler cannot
-                        // find the necessary dependencies for its part of the source.
-                        foundFiles.put(f.getPath(), of);
-                        continue;
-                    } else {
-                        // We are looking for sources to compile, if we find an existing to be compiled
-                        // source with the same name, it is an internal error, since we must
-                        // find the sources to be compiled before we find the sources to be linked to.
-                        throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
-                    }
-                }
-                Source s = new Source(currentModule, f.getPath(), f, root);
-                if (inGensrc) s.markAsGenerated();
-                if (inLinksrc) {
-                    s.markAsLinkedOnly();
-                }
-                pkg = currentModule.name()+":"+pkg;
-                foundFiles.put(f.getPath(), s);
-                currentModule.addSource(pkg, s);
+    private static List<PathMatcher> createPathMatchers(FileSystem fs, List<String> patterns) {
+        List<PathMatcher> matchers = new ArrayList<>();
+        for (String pattern : patterns) {
+            try {
+                matchers.add(fs.getPathMatcher("glob:" + pattern));
+            } catch (PatternSyntaxException e) {
+                Log.error("Invalid pattern: " + pattern);
+                throw e;
             }
         }
-        return currentModule;
+        return matchers;
+    }
+
+    private static String packageOfJavaFile(Path sourceRoot, Path javaFile) {
+        Path javaFileDir = javaFile.getParent();
+        Path packageDir = sourceRoot.relativize(javaFileDir);
+        List<String> separateDirs = new ArrayList<>();
+        for (Path pathElement : packageDir) {
+            separateDirs.add(pathElement.getFileName().toString());
+        }
+        return String.join(".", separateDirs);
     }
 
-    static private void scanDirectory(File dir, int rootPrefix, File root,
-                                      Set<String> suffixes,
-                                      List<String> excludes, List<String> includes,
-                                      List<String> excludeFiles, List<String> includeFiles,
-                                      Map<String,Source> foundFiles,
-                                      Map<String,Module> foundModules,
-                                      Module currentModule, boolean inGensrc, boolean inLinksrc)
-        throws ProblemException {
-
-        String path = "";
-        // Remove the root prefix from the dir path
-        if (dir.getPath().length() > rootPrefix) {
-            path = dir.getPath().substring(rootPrefix);
-        }
-        // Should this package directory be included and not excluded?
-        if ((includes==null || includes.isEmpty() || hasMatch(path, includes)) &&
-            (excludes==null || excludes.isEmpty() || !hasMatch(path, excludes))) {
-            // Add the source files.
-            currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles,
-                                          foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
-        }
-
-        for (File d : dir.listFiles()) {
-            if (d.isDirectory()) {
-                // Descend into the directory structure.
-                scanDirectory(d, rootPrefix, root, suffixes,
-                              excludes, includes, excludeFiles, includeFiles,
-                              foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
-            }
-        }
+    @Override
+    public String toString() {
+        return String.format("%s[pkg: %s, name: %s, suffix: %s, file: %s, isGenerated: %b, linkedOnly: %b]",
+                             getClass().getSimpleName(),
+                             pkg,
+                             name,
+                             suffix,
+                             file,
+                             isGenerated,
+                             linkedOnly);
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Fri Jan 08 17:14:10 2016 +0100
@@ -230,4 +230,10 @@
                                            Function<? super T, ? extends I> indexFunction) {
         return c.stream().collect(Collectors.<T, I, T>toMap(indexFunction, o -> o));
     }
+
+    public static String fileSuffix(Path file) {
+        String fileNameStr = file.getFileName().toString();
+        int dotIndex = fileNameStr.indexOf('.');
+        return dotIndex == -1 ? "" : fileNameStr.substring(dotIndex);
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Fri Jan 08 17:14:10 2016 +0100
@@ -144,77 +144,77 @@
             Module current_module = new Module("", "");
             modules.put("", current_module);
 
-            // Find all sources, use the suffix rules to know which files are sources.
-            Map<String,Source> sources = new HashMap<>();
+            try {
+                // Find all sources, use the suffix rules to know which files are sources.
+                Map<String,Source> sources = new HashMap<>();
 
-            // Find the files, this will automatically populate the found modules
-            // with found packages where the sources are found!
-            findSourceFiles(options.getSources(),
-                            suffixRules.keySet(),
-                            sources,
-                            modules,
-                            current_module,
-                            options.isDefaultPackagePermitted(),
-                            false);
+                // Find the files, this will automatically populate the found modules
+                // with found packages where the sources are found!
+                findSourceFiles(options.getSources(),
+                                suffixRules.keySet(),
+                                sources,
+                                modules,
+                                current_module,
+                                options.isDefaultPackagePermitted(),
+                                false);
 
-            if (sources.isEmpty()) {
-                Log.error("Found nothing to compile!");
-                return RC_FATAL;
-            }
+                if (sources.isEmpty()) {
+                    Log.error("Found nothing to compile!");
+                    return RC_FATAL;
+                }
 
 
-            // Create a map of all source files that are available for linking. Both -src and
-            // -sourcepath point to such files. It is possible to specify multiple
-            // -sourcepath options to enable different filtering rules. If the
-            // filters are the same for multiple sourcepaths, they may be concatenated
-            // using :(;). Before sending the list of sourcepaths to javac, they are
-            // all concatenated. The list created here is used by the SmartFileWrapper to
-            // make sure only the correct sources are actually available.
-            // We might find more modules here as well.
-            Map<String,Source> sources_to_link_to = new HashMap<>();
+                // Create a map of all source files that are available for linking. Both -src and
+                // -sourcepath point to such files. It is possible to specify multiple
+                // -sourcepath options to enable different filtering rules. If the
+                // filters are the same for multiple sourcepaths, they may be concatenated
+                // using :(;). Before sending the list of sourcepaths to javac, they are
+                // all concatenated. The list created here is used by the SmartFileWrapper to
+                // make sure only the correct sources are actually available.
+                // We might find more modules here as well.
+                Map<String,Source> sources_to_link_to = new HashMap<>();
 
-            List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
-            sourceResolutionLocations.addAll(options.getSources());
-            sourceResolutionLocations.addAll(options.getSourceSearchPaths());
-            findSourceFiles(sourceResolutionLocations,
-                            Collections.singleton(".java"),
-                            sources_to_link_to,
-                            modules,
-                            current_module,
-                            options.isDefaultPackagePermitted(),
-                            true);
+                List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
+                sourceResolutionLocations.addAll(options.getSources());
+                sourceResolutionLocations.addAll(options.getSourceSearchPaths());
+                findSourceFiles(sourceResolutionLocations,
+                                Collections.singleton(".java"),
+                                sources_to_link_to,
+                                modules,
+                                current_module,
+                                options.isDefaultPackagePermitted(),
+                                true);
 
-            // Add the set of sources to the build database.
-            javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
-            javac_state.now().checkInternalState("checking sources", false, sources);
-            javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
-            javac_state.setVisibleSources(sources_to_link_to);
+                // Add the set of sources to the build database.
+                javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
+                javac_state.now().checkInternalState("checking sources", false, sources);
+                javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+                javac_state.setVisibleSources(sources_to_link_to);
 
-            int round = 0;
-            printRound(round);
+                int round = 0;
+                printRound(round);
 
-            // If there is any change in the source files, taint packages
-            // and mark the database in need of saving.
-            javac_state.checkSourceStatus(false);
+                // If there is any change in the source files, taint packages
+                // and mark the database in need of saving.
+                javac_state.checkSourceStatus(false);
 
-            // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
-            // in javac_state, simply because loading of the JavacState will clean out all artifacts
-            // that do not match the javac_state database.
-            javac_state.findAllArtifacts();
+                // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+                // in javac_state, simply because loading of the JavacState will clean out all artifacts
+                // that do not match the javac_state database.
+                javac_state.findAllArtifacts();
 
-            // Remove unidentified artifacts from the bin, gensrc and header dirs.
-            // (Unless we allow them to be there.)
-            // I.e. artifacts that are not known according to the build database (javac_state).
-            // For examples, files that have been manually copied into these dirs.
-            // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
-            // in javac_state) have already been removed when the javac_state was loaded.
-            if (!options.areUnidentifiedArtifactsPermitted()) {
-                javac_state.removeUnidentifiedArtifacts();
-            }
-            // Go through all sources and taint all packages that miss artifacts.
-            javac_state.taintPackagesThatMissArtifacts();
+                // Remove unidentified artifacts from the bin, gensrc and header dirs.
+                // (Unless we allow them to be there.)
+                // I.e. artifacts that are not known according to the build database (javac_state).
+                // For examples, files that have been manually copied into these dirs.
+                // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+                // in javac_state) have already been removed when the javac_state was loaded.
+                if (!options.areUnidentifiedArtifactsPermitted()) {
+                    javac_state.removeUnidentifiedArtifacts();
+                }
+                // Go through all sources and taint all packages that miss artifacts.
+                javac_state.taintPackagesThatMissArtifacts();
 
-            try {
                 // Check recorded classpath public apis. Taint packages that depend on
                 // classpath classes whose public apis have changed.
                 javac_state.taintPackagesDependingOnChangedClasspathPackages();
@@ -229,8 +229,16 @@
                 // (Generated sources must always have a package.)
                 Map<String,Source> generated_sources = new HashMap<>();
 
-                Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null,
-                        generated_sources, modules, current_module, false, true, false);
+                Source.scanRoot(Util.pathToFile(options.getGenSrcDir()),
+                                Util.set(".java"),
+                                Collections.emptyList(),
+                                Collections.emptyList(),
+                                generated_sources,
+                                modules,
+                                current_module,
+                                false,
+                                true,
+                                false);
                 javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
                 // Recheck the the source files and their timestamps again.
                 javac_state.checkSourceStatus(true);
@@ -254,7 +262,10 @@
                         printRound(round);
                     // Clean out artifacts in tainted packages.
                     javac_state.deleteClassArtifactsInTaintedPackages();
-                    again = javac_state.performJavaCompilations(compilationService, options, recently_compiled, rc);
+                    again = javac_state.performJavaCompilations(compilationService,
+                                                                options,
+                                                                recently_compiled,
+                                                                rc);
                     if (!rc[0]) {
                         Log.debug("Compilation failed.");
                         break;
@@ -344,7 +355,8 @@
                                        Map<String, Module> foundModules,
                                        Module currentModule,
                                        boolean permitSourcesInDefaultPackage,
-                                       boolean inLinksrc) {
+                                       boolean inLinksrc)
+                                               throws IOException {
 
         for (SourceLocation source : sourceLocations) {
             source.findSourceFiles(sourceTypes,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Fri Jan 08 17:14:10 2016 +0100
@@ -93,7 +93,7 @@
             CLASSPATH.processMatching(iter, helper);
         }
     },
-    X("-x", "Exclude directory from the subsequent source directory") {
+    X("-x", "Exclude files matching the given pattern") {
         @Override
         protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
             String pattern = getFilePatternArg(iter, helper);
@@ -101,7 +101,7 @@
                 helper.exclude(pattern);
         }
     },
-    I("-i", "Include only the given directory from the subsequent source directory") {
+    I("-i", "Include only files matching the given pattern") {
         @Override
         protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
             String pattern = getFilePatternArg(iter, helper);
@@ -109,22 +109,6 @@
                 helper.include(pattern);
         }
     },
-    XF("-xf", "Exclude a given file") {
-        @Override
-        protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
-            String pattern = getFilePatternArg(iter, helper);
-            if (pattern != null)
-                helper.excludeFile(pattern);
-        }
-    },
-    IF("-if", "Include only the given file") {
-        @Override
-        protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
-            String pattern = getFilePatternArg(iter, helper);
-            if (pattern != null)
-                helper.includeFile(pattern);
-        }
-    },
     TR("-tr", "Translate resources") {
         @Override
         protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
@@ -338,7 +322,7 @@
     String getFilePatternArg(ArgumentIterator iter, OptionHelper helper) {
 
         if (!iter.hasNext()) {
-            helper.reportError(arg + " must be followed by a file or directory pattern.");
+            helper.reportError(arg + " must be followed by a glob pattern.");
             return null;
         }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Fri Jan 08 17:14:10 2016 +0100
@@ -53,12 +53,6 @@
     /** Record a package inclusion pattern */
     public abstract void include(String incl);
 
-    /** Record a file exclusion */
-    public abstract void excludeFile(String exclFile);
-
-    /** Record a file inclusion */
-    public abstract void includeFile(String inclFile);
-
     /** Record a root of sources to be compiled */
     public abstract void sourceRoots(List<Path> path);
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Fri Jan 08 17:14:10 2016 +0100
@@ -220,8 +220,6 @@
                 for (SourceLocation sl : locs) {
                     for (String pkg : sl.includes) addArg(Option.I, pkg);
                     for (String pkg : sl.excludes) addArg(Option.X, pkg);
-                    for (String f : sl.excludedFiles) addArg(Option.XF, f);
-                    for (String f : sl.includedFiles) addArg(Option.IF, f);
                     addArg(opt, sl.getPath());
                 }
             }
@@ -380,18 +378,6 @@
         }
 
         @Override
-        public void excludeFile(String exclFilePattern) {
-            exclFilePattern = Util.normalizeDriveLetter(exclFilePattern);
-            excludeFiles.add(exclFilePattern);
-        }
-
-        @Override
-        public void includeFile(String inclFilePattern) {
-            inclFilePattern = Util.normalizeDriveLetter(inclFilePattern);
-            includeFiles.add(inclFilePattern);
-        }
-
-        @Override
         public void addTransformer(String suffix, Transformer tr) {
             if (trRules.containsKey(suffix)) {
                 reportError("More than one transformer specified for " +
@@ -519,9 +505,7 @@
                 result.add(new SourceLocation(
                         path,
                         includes,
-                        excludes,
-                        includeFiles,
-                        excludeFiles));
+                        excludes));
             }
             resetFilters();
             return result;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java	Fri Jan 08 17:14:10 2016 +0100
@@ -25,11 +25,13 @@
 
 package com.sun.tools.sjavac.options;
 
+import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Module;
 import com.sun.tools.sjavac.ProblemException;
 import com.sun.tools.sjavac.Source;
@@ -49,18 +51,14 @@
     private Path path;
 
     // Package include / exclude patterns and file includes / excludes.
-    List<String> includes, excludes, includedFiles, excludedFiles;
+    List<String> includes, excludes;
 
     public SourceLocation(Path path,
                           List<String> includes,
-                          List<String> excludes,
-                          List<String> includedFiles,
-                          List<String> excludedFiles) {
+                          List<String> excludes) {
         this.path = path;
         this.includes = includes;
         this.excludes = excludes;
-        this.includedFiles = includedFiles;
-        this.excludedFiles = excludedFiles;
     }
 
 
@@ -81,17 +79,23 @@
                                 Map<String, Module> foundModules,
                                 Module currentModule,
                                 boolean permitSourcesInDefaultPackage,
-                                boolean inLinksrc) {
+                                boolean inLinksrc)
+                                        throws IOException {
         try {
-            Source.scanRoot(path.toFile(), suffixes, excludes, includes,
-                    excludedFiles, includedFiles, foundFiles, foundModules,
-                    currentModule, permitSourcesInDefaultPackage, false,
-                    inLinksrc);
+            Source.scanRoot(path.toFile(),
+                            suffixes,
+                            excludes,
+                            includes,
+                            foundFiles,
+                            foundModules,
+                            currentModule,
+                            permitSourcesInDefaultPackage,
+                            false,
+                            inLinksrc);
         } catch (ProblemException e) {
             e.printStackTrace();
         }
     }
-
     /** Get the root directory of this source location */
     public Path getPath() {
         return path;
@@ -107,14 +111,9 @@
         return excludes;
     }
 
-    /** Get the file include patterns */
-    public List<String> getIncludedFiles() {
-        return includedFiles;
+    @Override
+    public String toString() {
+        return String.format("%s[\"%s\", includes: %s, excludes: %s]",
+                             getClass().getSimpleName(), path, includes, excludes);
     }
-
-    /** Get the file exclude patterns */
-    public List<String> getExcludedFiles() {
-        return excludedFiles;
-    }
-
 }
--- a/langtools/test/tools/sjavac/CompileExcludingDependency.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/CompileExcludingDependency.java	Fri Jan 08 17:14:10 2016 +0100
@@ -55,9 +55,9 @@
         tb.writeFile(GENSRC.resolve("beta/B.java"),
                      "package beta; public class B { }");
 
-        compile("-x", "beta",
+        compile("-x", "beta/*",
                 "-src", GENSRC.toString(),
-                "-x", "alfa/omega",
+                "-x", "alfa/omega/*",
                 "-sourcepath", GENSRC.toString(),
                 "-d", BIN.toString(),
                 "--state-dir=" + BIN,
--- a/langtools/test/tools/sjavac/CompileWithAtFile.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/CompileWithAtFile.java	Fri Jan 08 17:14:10 2016 +0100
@@ -47,8 +47,8 @@
 
     void test() throws Exception {
         tb.writeFile(GENSRC.resolve("list.txt"),
-                     "-if */alfa/omega/A.java\n" +
-                     "-if */beta/B.java\n" +
+                     "-i alfa/omega/A.java\n" +
+                     "-i beta/B.java\n" +
                      GENSRC + "\n" +
                      "-d " + BIN + "\n" +
                      "--state-dir=" + BIN + "\n");
--- a/langtools/test/tools/sjavac/CompileWithInvisibleSources.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/CompileWithInvisibleSources.java	Fri Jan 08 17:14:10 2016 +0100
@@ -64,7 +64,7 @@
                      "package beta; public class B { }");
 
         compile(GENSRC.toString(),
-                "-x", "beta",
+                "-x", "beta/*",
                 "-sourcepath", GENSRC2.toString(),
                 "-sourcepath", GENSRC3.toString(),
                 "-d", BIN.toString(),
--- a/langtools/test/tools/sjavac/CompileWithOverrideSources.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/CompileWithOverrideSources.java	Fri Jan 08 17:14:10 2016 +0100
@@ -62,7 +62,7 @@
         tb.writeFile(GENSRC2.resolve("beta/B.java"),
                      "package beta; public class B { }");
 
-        compile("-x", "beta",
+        compile("-x", "beta/*",
                 GENSRC.toString(),
                 GENSRC2.toString(),
                 "-d", BIN.toString(),
--- a/langtools/test/tools/sjavac/ExclPattern.java	Wed Jul 05 21:12:04 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8037085
- * @summary Ensures that sjavac can handle various exclusion patterns.
- *
- * @modules jdk.compiler/com.sun.tools.sjavac
- * @build Wrapper
- * @run main Wrapper ExclPattern
- */
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-public class ExclPattern {
-
-    public static void main(String[] ignore) throws IOException {
-
-        String toBeExcluded = "pkg/excl-dir/excluded.txt";
-        String toBeIncluded = "pkg/incl-dir/included.txt";
-
-        // Set up source directory with directory to be excluded
-        populate(Paths.get("srcdir"),
-            "pkg/SomeClass.java",
-            "package pkg; public class SomeClass { }",
-
-            toBeExcluded,
-            "This file should not end up in the dest directory.",
-
-            toBeIncluded,
-            "This file should end up in the dest directory.");
-
-        String[] args = {
-                "-x", "pkg/excl-dir/*",
-                "-src", "srcdir",
-                "-d", "dest",
-                "--state-dir=dest",
-                "-j", "1",
-                "-copy", ".txt",
-                "--server:portfile=testserver,background=false",
-                "--log=debug"
-        };
-
-        int rc = com.sun.tools.sjavac.Main.go(args);
-        if (rc != 0) throw new RuntimeException("Error during compile!");
-
-        if (!Files.exists(Paths.get("dest/" + toBeIncluded)))
-            throw new AssertionError("File missing: " + toBeIncluded);
-
-        if (Files.exists(Paths.get("dest/" + toBeExcluded)))
-            throw new AssertionError("File present: " + toBeExcluded);
-    }
-
-    static void populate(Path root, String... args) throws IOException {
-        if (!Files.exists(root))
-            Files.createDirectory(root);
-        for (int i = 0; i < args.length; i += 2) {
-            String filename = args[i];
-            String content = args[i+1];
-            Path p = root.resolve(filename);
-            Files.createDirectories(p.getParent());
-            try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
-                    Charset.defaultCharset()))) {
-                out.println(content);
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/HiddenFiles.java	Fri Jan 08 17:14:10 2016 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8144226
+ * @summary Ensures that excluded files are inaccessible (even for implicit
+ *          compilation)
+ *
+ * @modules jdk.compiler/com.sun.tools.sjavac
+ * @library /tools/lib
+ * @build Wrapper ToolBox
+ * @run main Wrapper HiddenFiles
+ */
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.server.Sjavac;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class HiddenFiles extends SjavacBase {
+
+    public static void main(String[] ignore) throws Exception {
+        Path BIN = Paths.get("bin");
+        Path STATE_DIR = Paths.get("state-dir");
+        Path SRC = Paths.get("src");
+
+        Files.createDirectories(BIN);
+        Files.createDirectories(STATE_DIR);
+
+        toolbox.writeJavaFiles(SRC, "package pkg; class A { B b; }");
+        toolbox.writeJavaFiles(SRC, "package pkg; class B { }");
+
+        // This compilation should fail (return RC_FATAL) since A.java refers to B.java and B.java
+        // is excluded.
+        int rc = compile("-x", "pkg/B.java", SRC.toString(),
+                         "--server:portfile=testportfile,background=false",
+                         "-d", BIN.toString(),
+                         "--state-dir=" + STATE_DIR);
+
+        Assert.check(rc == Sjavac.RC_FATAL, "Compilation succeeded unexpectedly.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/IncludeExcludePatterns.java	Fri Jan 08 17:14:10 2016 +0100
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2014, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8037085
+ * @summary Ensures that sjavac can handle various exclusion patterns.
+ *
+ * @modules jdk.compiler/com.sun.tools.sjavac
+ * @library /tools/lib
+ * @build Wrapper ToolBox
+ * @run main Wrapper IncludeExcludePatterns
+ */
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.server.Sjavac;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class IncludeExcludePatterns extends SjavacBase {
+
+    final Path SRC = Paths.get("src");
+    final Path BIN = Paths.get("bin");
+    final Path STATE_DIR = Paths.get("state-dir");
+
+    // An arbitrarily but sufficiently complicated source tree.
+    final Path A = Paths.get("pkga/A.java");
+    final Path X1 = Paths.get("pkga/subpkg/Xx.java");
+    final Path Y = Paths.get("pkga/subpkg/subsubpkg/Y.java");
+    final Path B = Paths.get("pkgb/B.java");
+    final Path C = Paths.get("pkgc/C.java");
+    final Path X2 = Paths.get("pkgc/Xx.java");
+
+    final Path[] ALL_PATHS = {A, X1, Y, B, C, X2};
+
+    public static void main(String[] ignore) throws Exception {
+        new IncludeExcludePatterns().runTest();
+    }
+
+    public void runTest() throws IOException, ReflectiveOperationException {
+        Files.createDirectories(BIN);
+        Files.createDirectories(STATE_DIR);
+        for (Path p : ALL_PATHS) {
+            writeDummyClass(p);
+        }
+
+        // Single file
+        testPattern("pkga/A.java", A);
+
+        // Leading wild cards
+        testPattern("*/A.java", A);
+        testPattern("**/Xx.java", X1, X2);
+        testPattern("**x.java", X1, X2);
+
+        // Wild card in middle of path
+        testPattern("pkga/*/Xx.java", X1);
+        testPattern("pkga/**/Y.java", Y);
+
+        // Trailing wild cards
+        testPattern("pkga/*", A);
+        testPattern("pkga/**", A, X1, Y);
+
+        // Multiple wildcards
+        testPattern("pkga/*/*/Y.java", Y);
+        testPattern("**/*/**", X1, Y);
+
+    }
+
+    // Given "src/pkg/subpkg/A.java" this method returns "A"
+    String classNameOf(Path javaFile) {
+        return javaFile.getFileName()
+                       .toString()
+                       .replace(".java", "");
+    }
+
+    // Puts an empty (dummy) class definition in the given path.
+    void writeDummyClass(Path javaFile) throws IOException {
+        String pkg = javaFile.getParent().toString().replace('/', '.');
+        String cls = javaFile.getFileName().toString().replace(".java", "");
+        toolbox.writeFile(SRC.resolve(javaFile), "package " + pkg + "; class " + cls + " {}");
+    }
+
+    void testPattern(String filterArgs, Path... sourcesExpectedToBeVisible)
+            throws ReflectiveOperationException, IOException {
+        testFilter("-i " + filterArgs, Arrays.asList(sourcesExpectedToBeVisible));
+
+        Set<Path> complement = new HashSet<>(Arrays.asList(ALL_PATHS));
+        complement.removeAll(Arrays.asList(sourcesExpectedToBeVisible));
+        testFilter("-x " + filterArgs, complement);
+    }
+
+    void testFilter(String filterArgs, Collection<Path> sourcesExpectedToBeVisible)
+            throws IOException, ReflectiveOperationException {
+        System.out.println("Testing filter: " + filterArgs);
+        toolbox.cleanDirectory(BIN);
+        toolbox.cleanDirectory(STATE_DIR);
+        String args = filterArgs + " " + SRC
+                + " --server:portfile=testportfile,background=false"
+                + " -d " + BIN
+                + " --state-dir=" + STATE_DIR;
+        int rc = compile((Object[]) args.split(" "));
+
+        // Compilation should always pass in these tests
+        Assert.check(rc == Sjavac.RC_OK, "Compilation failed unexpectedly.");
+
+        // The resulting .class files should correspond to the visible source files
+        Set<Path> result = allFilesInDir(BIN);
+        Set<Path> expected = correspondingClassFiles(sourcesExpectedToBeVisible);
+        if (!result.equals(expected)) {
+            System.out.println("Result:");
+            printPaths(result);
+            System.out.println("Expected:");
+            printPaths(expected);
+            Assert.error("Test case failed: " + filterArgs);
+        }
+    }
+
+    void printPaths(Collection<Path> paths) {
+        paths.stream()
+             .sorted()
+             .forEachOrdered(p -> System.out.println("    " + p));
+    }
+
+    // Given "pkg/A.java, pkg/B.java" this method returns "bin/pkg/A.class, bin/pkg/B.class"
+    Set<Path> correspondingClassFiles(Collection<Path> javaFiles) {
+        return javaFiles.stream()
+                        .map(javaFile -> javaFile.resolveSibling(classNameOf(javaFile) + ".class"))
+                        .map(BIN::resolve)
+                        .collect(Collectors.toSet());
+    }
+
+    Set<Path> allFilesInDir(Path p) throws IOException {
+        try (Stream<Path> files = Files.walk(p).filter(Files::isRegularFile)) {
+            return files.collect(Collectors.toSet());
+        }
+    }
+}
--- a/langtools/test/tools/sjavac/OptionDecoding.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/OptionDecoding.java	Fri Jan 08 17:14:10 2016 +0100
@@ -61,7 +61,6 @@
     public static void main(String[] args) throws IOException {
         testPaths();
         testDupPaths();
-        testSourceLocations();
         testSimpleOptions();
         testServerConf();
         testSearchPaths();
@@ -110,78 +109,6 @@
         }
     }
 
-    // Test source locations and -x, -i, -xf, -if filters
-    static void testSourceLocations() throws IOException {
-        Path a1 = Paths.get("root/pkg1/ClassA1.java");
-        Path a2 = Paths.get("root/pkg1/ClassA2.java");
-        Path b1 = Paths.get("root/pkg1/pkg2/ClassB1.java");
-        Path b2 = Paths.get("root/pkg1/pkg2/ClassB2.java");
-        Path c1 = Paths.get("root/pkg3/ClassC1.java");
-        Path c2 = Paths.get("root/pkg3/ClassC2.java");
-
-        for (Path p : Arrays.asList(a1, a2, b1, b2, c1, c2)) {
-            Files.createDirectories(p.getParent());
-            Files.createFile(p);
-        }
-
-        // Test -if
-        {
-            Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root");
-
-            Map<String, Source> foundFiles = new HashMap<>();
-            SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
-                    new HashMap<String, Module>(), new Module("", ""), false, true);
-
-            checkFilesFound(foundFiles.keySet(), a1);
-        }
-
-        // Test -i
-        System.out.println("--------------------------- CHECKING -i ----------------");
-        {
-            Options options = Options.parseArgs("-i", "pkg1/*", "root");
-
-            Map<String, Source> foundFiles = new HashMap<>();
-            SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
-                    new HashMap<String, Module>(), new Module("", ""), false, true);
-
-            checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
-        }
-        System.out.println("--------------------------------------------------------");
-
-        // Test -xf
-        {
-            Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root");
-
-            Map<String, Source> foundFiles = new HashMap<>();
-            SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
-                    new HashMap<String, Module>(), new Module("", ""), false, true);
-
-            checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2);
-        }
-
-        // Test -x
-        {
-            Options options = Options.parseArgs("-i", "pkg1/*", "root");
-
-            Map<String, Source> foundFiles = new HashMap<>();
-            SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
-                    new HashMap<String, Module>(), new Module("", ""), false, true);
-
-            checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
-        }
-
-        // Test -x and -i
-        {
-            Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root");
-
-            Map<String, Source> foundFiles = new HashMap<>();
-            SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
-                    new HashMap<String, Module>(), new Module("", ""), false, true);
-
-            checkFilesFound(foundFiles.keySet(), a1, a2);
-        }
-    }
-
     // Test basic options
     static void testSimpleOptions() {
         Options options = Options.parseArgs("-j", "17", "--log=debug");
@@ -216,8 +143,8 @@
         List<String> i, x, iF, xF;
         i = x = iF = xF = new ArrayList<>();
 
-        SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x, iF, xF);
-        SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x, iF, xF);
+        SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x);
+        SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x);
         String dir1_PS_dir2 = "dir1" + File.pathSeparator + "dir2";
 
         Options options = Options.parseArgs("-sourcepath", dir1_PS_dir2);
--- a/langtools/test/tools/sjavac/Serialization.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/Serialization.java	Fri Jan 08 17:14:10 2016 +0100
@@ -58,8 +58,6 @@
                 Option.D.arg, "dest",
                 Option.I.arg, "pkg/*",
                 Option.X.arg, "pkg/pkg/*",
-                Option.IF.arg, "root/pkg/MyClass1.java",
-                Option.XF.arg, "root/pkg/MyClass2.java",
                 Option.SRC.arg, "root",
                 Option.SOURCEPATH.arg, "sourcepath",
                 Option.CLASSPATH.arg, "classpath",
@@ -87,8 +85,6 @@
         assertEquals(sl1.getPath(), sl2.getPath());
         assertEquals(sl1.getIncludes(), sl2.getIncludes());
         assertEquals(sl1.getExcludes(), sl2.getExcludes());
-        assertEquals(sl1.getIncludedFiles(), sl2.getIncludedFiles());
-        assertEquals(sl1.getExcludedFiles(), sl2.getExcludedFiles());
 
         assertEquals(options1.getClassSearchPath(), options2.getClassSearchPath());
         assertEquals(options1.getSourceSearchPaths(), options2.getSourceSearchPaths());
--- a/langtools/test/tools/sjavac/util/OptionTestUtil.java	Wed Jul 05 21:12:04 2017 +0200
+++ b/langtools/test/tools/sjavac/util/OptionTestUtil.java	Fri Jan 08 17:14:10 2016 +0100
@@ -62,9 +62,7 @@
 
             if (!sl1.getPath().equals(sl2.getPath()) ||
                     !sl1.getIncludes().equals(sl2.getIncludes()) ||
-                    !sl1.getExcludes().equals(sl2.getExcludes()) ||
-                    !sl1.getIncludedFiles().equals(sl2.getIncludedFiles()) ||
-                    !sl1.getExcludedFiles().equals(sl2.getExcludedFiles()))
+                    !sl1.getExcludes().equals(sl2.getExcludes()))
                 throw new AssertionError("Expected " + sl1 + " but got " + sl2);
         }
     }