diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java index 424337a652..599854750c 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetector.java @@ -30,7 +30,7 @@ import java.util.Collection; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -56,7 +56,7 @@ public class BasicFileDetector { private String fileName; private int maxDepth = 5; private boolean includeNested = true; - private Set exclusions = new HashSet<>(1); + private Set exclusions = new LinkedHashSet<>(1); /** * Constructs a new BasicFileDetector for the given root directory, searching for a fileName. @@ -172,13 +172,19 @@ private boolean isExcluded(Path dir) { if (dir.getFileName() == null) { return true; } + boolean excluded = false; for (String pattern : exclusions) { + boolean includePattern = false; + if (pattern.startsWith("!")) { + includePattern = true; + pattern = pattern.substring(1); + } PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern); if (matcher.matches(dir)) { - return true; + excluded = includePattern ? false : true; } } - return false; + return excluded; } private boolean hasTargetFile(Path dir) { diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java index fb04359f60..38fa428133 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java @@ -96,15 +96,21 @@ public boolean applies(IProgressMonitor monitor) throws OperationCanceledExcepti private boolean exclude(java.nio.file.Path path) { List javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions(); + boolean excluded = false; if (javaImportExclusions != null) { for (String pattern : javaImportExclusions) { + boolean includePattern = false; + if (pattern.startsWith("!")) { + includePattern = true; + pattern = pattern.substring(1); + } PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern); if (matcher.matches(path)) { - return true; + excluded = includePattern ? false : true; } } } - return false; + return excluded; } synchronized Set getMavenProjectInfo(IProgressMonitor monitor) throws OperationCanceledException { diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java index 415205dbd3..4fb7c101c8 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/BasicFileDetectorTest.java @@ -19,12 +19,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; +import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.junit.Test; /** @@ -72,6 +74,74 @@ public void testScanExcludingNestedBuildFilesDepth3() throws Exception { assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size()); } + @Test + public void testInclusions() throws Exception { + List javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions(); + List javaImportInclusions = new LinkedList<>(); + javaImportInclusions.addAll(javaImportExclusions); + javaImportInclusions.add("**/parent/**"); + javaImportInclusions.add("!**/parent"); + javaImportInclusions.add("!**/parent/1_0"); + javaImportInclusions.add("!**/parent/1_0/*"); + try { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions); + BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3); + Collection dirs = detector.scan(null); + assertEquals("Found " + dirs, 2, dirs.size()); + List missingDirs = separatorsToSystem(list("projects/buildfiles/parent/1_0/0_2_0", "projects/buildfiles/parent/1_0/0_2_1")); + dirs.stream().map(Path::toString).forEach(missingDirs::remove); + assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size()); + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions); + detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3); + dirs = detector.scan(null); + assertEquals("Found " + dirs, 3, dirs.size()); + } finally { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions); + } + } + + @Test + public void testInclusions2() throws Exception { + List javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions(); + List javaImportInclusions = new LinkedList<>(); + javaImportInclusions.addAll(javaImportExclusions); + javaImportInclusions.add("**/parent/**"); + javaImportInclusions.add("!**/parent"); + javaImportInclusions.add("!**/parent/1_0"); + javaImportInclusions.add("!**/parent/1_0/0_2_0"); + try { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions); + BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3); + Collection dirs = detector.scan(null); + assertEquals("Found " + dirs, 1, dirs.size()); + List missingDirs = separatorsToSystem(list("projects/buildfiles/parent/1_0/0_2_0")); + dirs.stream().map(Path::toString).forEach(missingDirs::remove); + assertEquals("Directories were not detected" + missingDirs, 0, missingDirs.size()); + } finally { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions); + } + } + + @Test + public void testInclusions3() throws Exception { + List javaImportExclusions = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getJavaImportExclusions(); + List javaImportInclusions = new LinkedList<>(); + javaImportInclusions.addAll(javaImportExclusions); + javaImportInclusions.add("!**/parent"); + javaImportInclusions.add("!**/parent/1_0"); + javaImportInclusions.add("!**/parent/1_0/0_2_0"); + javaImportInclusions.add("**/parent/**"); + try { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportInclusions); + BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile").includeNested(false).maxDepth(3); + Collection dirs = detector.scan(null); + assertEquals("Found " + dirs, 0, dirs.size()); + } finally { + JavaLanguageServerPlugin.getPreferencesManager().getPreferences().setJavaImportExclusions(javaImportExclusions); + } + } + + @Test public void testScanNestedBuildFilesDepth2() throws Exception { BasicFileDetector detector = new BasicFileDetector(Paths.get("projects/buildfiles/parent"), "buildfile")