diff options
-rw-r--r-- | TODOS.md | 1 | ||||
-rw-r--r-- | src/main/java/org/javacs/CompileFile.java | 2 | ||||
-rw-r--r-- | src/main/java/org/javacs/CompileFocus.java | 4 | ||||
-rw-r--r-- | src/main/java/org/javacs/InferSourcePath.java | 82 | ||||
-rw-r--r-- | src/main/java/org/javacs/JavaCompilerService.java | 20 | ||||
-rw-r--r-- | src/main/java/org/javacs/JavaLanguageServer.java | 45 | ||||
-rw-r--r-- | src/main/java/org/javacs/Parser.java | 71 | ||||
-rw-r--r-- | src/main/java/org/javacs/SourcePath.java | 146 | ||||
-rw-r--r-- | src/main/java/org/javacs/lsp/FileEvent.java | 1 | ||||
-rw-r--r-- | src/main/java/org/javacs/lsp/LSP.java | 4 | ||||
-rw-r--r-- | src/test/java/org/javacs/JavaCompilerServiceTest.java | 19 | ||||
-rw-r--r-- | src/test/java/org/javacs/ParserFixImportsTest.java | 14 | ||||
-rw-r--r-- | src/test/java/org/javacs/ParserTest.java | 5 |
13 files changed, 267 insertions, 147 deletions
@@ -12,6 +12,7 @@ - Always shows last javadoc - Goto field goes to method of same name - Goto definition goes to wrong method in overloads +- T x, y; 'n references' shows references for y even when you click for x ## Autocomplete - Annotation fields diff --git a/src/main/java/org/javacs/CompileFile.java b/src/main/java/org/javacs/CompileFile.java index 7437864..35f9cd1 100644 --- a/src/main/java/org/javacs/CompileFile.java +++ b/src/main/java/org/javacs/CompileFile.java @@ -112,7 +112,7 @@ public class CompileFile { } } // Look at imports in other classes to help us guess how to fix imports - var sourcePathImports = Parser.existingImports(parent.sourcePath); + var sourcePathImports = Parser.existingImports(parent.allJavaFiles.get()); var classes = new HashSet<String>(); classes.addAll(parent.jdkClasses.classes()); classes.addAll(parent.classPathClasses.classes()); diff --git a/src/main/java/org/javacs/CompileFocus.java b/src/main/java/org/javacs/CompileFocus.java index e942ff6..65bde00 100644 --- a/src/main/java/org/javacs/CompileFocus.java +++ b/src/main/java/org/javacs/CompileFocus.java @@ -212,6 +212,10 @@ public class CompileFocus { LOG.info(String.format("...switched expression has type `%s`", type)); var types = task.getTypes(); var definition = types.asElement(type); + if (definition == null) { + LOG.info("...type has no definition, completing identifiers instead"); + return completeIdentifiers(true, true, ""); // TODO pass partial name + } LOG.info(String.format("...switched expression has definition `%s`", definition)); var result = new ArrayList<Completion>(); for (var member : definition.getEnclosedElements()) { diff --git a/src/main/java/org/javacs/InferSourcePath.java b/src/main/java/org/javacs/InferSourcePath.java deleted file mode 100644 index f1fd1d2..0000000 --- a/src/main/java/org/javacs/InferSourcePath.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.javacs; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; -import java.util.logging.Logger; -import java.util.stream.Stream; - -class InferSourcePath { - - static Stream<Path> allJavaFiles(Path dir) { - var match = FileSystems.getDefault().getPathMatcher("glob:*.java"); - - try { - return Files.walk(dir).filter(java -> match.matches(java.getFileName())); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - static Set<Path> sourcePath(Path workspaceRoot) { - LOG.info("Searching for source roots in " + workspaceRoot); - - class SourcePaths implements Consumer<Path> { - int certaintyThreshold = 10; - Map<Path, Integer> sourceRoots = new HashMap<>(); - - boolean alreadyKnown(Path java) { - for (var root : sourceRoots.keySet()) { - if (java.startsWith(root) && sourceRoots.get(root) > certaintyThreshold) return true; - } - return false; - } - - Optional<Path> infer(Path java) { - var packageName = Objects.toString(Parser.parse(java).getPackageName(), ""); - var packagePath = packageName.replace('.', File.separatorChar); - var dir = java.getParent(); - if (packagePath.isEmpty()) { - LOG.warning("Ignoring file with missing package declaration " + java); - return Optional.empty(); - } else if (!dir.endsWith(packagePath)) { - LOG.warning("Java source file " + java + " is not in " + packagePath); - return Optional.empty(); - } else { - var up = Paths.get(packagePath).getNameCount(); - var truncate = dir; - for (int i = 0; i < up; i++) truncate = truncate.getParent(); - return Optional.of(truncate); - } - } - - @Override - public void accept(Path java) { - if (java.getFileName().toString().equals("module-info.java")) return; - - if (!alreadyKnown(java)) { - infer(java) - .ifPresent( - root -> { - var count = sourceRoots.getOrDefault(root, 0); - sourceRoots.put(root, count + 1); - }); - } - } - } - var checker = new SourcePaths(); - allJavaFiles(workspaceRoot).forEach(checker); - return checker.sourceRoots.keySet(); - } - - private static final Logger LOG = Logger.getLogger("main"); -} diff --git a/src/main/java/org/javacs/JavaCompilerService.java b/src/main/java/org/javacs/JavaCompilerService.java index 56614a8..aff5721 100644 --- a/src/main/java/org/javacs/JavaCompilerService.java +++ b/src/main/java/org/javacs/JavaCompilerService.java @@ -12,6 +12,7 @@ import java.nio.charset.Charset; import java.nio.file.*; import java.time.Instant; import java.util.*; +import java.util.function.Supplier; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -22,6 +23,7 @@ import javax.tools.*; public class JavaCompilerService { // Not modifiable! If you want to edit these, you need to create a new instance final Set<Path> sourcePath, classPath, docPath; + final Supplier<Set<Path>> allJavaFiles; final JavaCompiler compiler = ServiceLoader.load(JavaCompiler.class).iterator().next(); final Docs docs; final ClassSource jdkClasses = Classes.jdkTopLevelClasses(), classPathClasses; @@ -31,7 +33,8 @@ public class JavaCompilerService { final StandardJavaFileManager fileManager = new FileManagerWrapper(compiler.getStandardFileManager(diags::add, null, Charset.defaultCharset())); - public JavaCompilerService(Set<Path> sourcePath, Set<Path> classPath, Set<Path> docPath) { + public JavaCompilerService( + Set<Path> sourcePath, Supplier<Set<Path>> allJavaFiles, Set<Path> classPath, Set<Path> docPath) { System.err.println("Source path:"); for (var p : sourcePath) { System.err.println(" " + p); @@ -46,6 +49,7 @@ public class JavaCompilerService { } // sourcePath and classPath can't actually be modified, because JavaCompiler remembers them from task to task this.sourcePath = Collections.unmodifiableSet(sourcePath); + this.allJavaFiles = allJavaFiles; this.classPath = Collections.unmodifiableSet(classPath); this.docPath = Collections.unmodifiableSet(docPath); var docSourcePath = new HashSet<Path>(); @@ -179,22 +183,12 @@ public class JavaCompilerService { return false; } - private List<Path> allJavaSources() { - var allFiles = new ArrayList<Path>(); - for (var dir : sourcePath) { - for (var file : javaSourcesInDir(dir)) { - allFiles.add(file); - } - } - return allFiles; - } - // TODO should probably cache this public List<URI> potentialReferences(Element to) { LOG.info(String.format("Find potential references to `%s`...", to)); // Check all files on source path - var allFiles = allJavaSources(); + var allFiles = allJavaFiles.get(); LOG.info(String.format("...check %d files on the source path", allFiles.size())); // Figure out which files import `to`, explicitly or implicitly @@ -350,7 +344,7 @@ public class JavaCompilerService { LOG.info(String.format("Searching for `%s`...", query)); var result = new ArrayList<TreePath>(); - var files = allJavaSources(); + var files = allJavaFiles.get(); var checked = 0; var parsed = 0; for (var file : files) { diff --git a/src/main/java/org/javacs/JavaLanguageServer.java b/src/main/java/org/javacs/JavaLanguageServer.java index e0a6d60..c7b475a 100644 --- a/src/main/java/org/javacs/JavaLanguageServer.java +++ b/src/main/java/org/javacs/JavaLanguageServer.java @@ -45,7 +45,9 @@ import org.javacs.lsp.*; class JavaLanguageServer extends LanguageServer { private static final Logger LOG = Logger.getLogger("main"); + // TODO allow multiple workspace roots private Path workspaceRoot; + private SourcePath sourcePath; private final LanguageClient client; private Set<String> externalDependencies = Set.of(); private Set<Path> classPath = Set.of(); @@ -135,12 +137,11 @@ class JavaLanguageServer extends LanguageServer { javaStartProgress(new JavaStartProgressParams("Configure javac")); javaReportProgress(new JavaReportProgressParams("Finding source roots")); - var sourcePath = InferSourcePath.sourcePath(workspaceRoot); // TODO show each folder as we find it - // If classpath is specified by the user, don't infer anything if (!classPath.isEmpty()) { javaEndProgress(); - return new JavaCompilerService(sourcePath, classPath, Collections.emptySet()); + return new JavaCompilerService( + sourcePath.sourceRoots(), sourcePath::allJavaFiles, classPath, Collections.emptySet()); } // Otherwise, combine inference with user-specified external dependencies else { @@ -153,7 +154,7 @@ class JavaLanguageServer extends LanguageServer { var docPath = infer.buildDocPath(); javaEndProgress(); - return new JavaCompilerService(sourcePath, classPath, docPath); + return new JavaCompilerService(sourcePath.sourceRoots(), sourcePath::allJavaFiles, classPath, docPath); } } @@ -174,6 +175,7 @@ class JavaLanguageServer extends LanguageServer { @Override public InitializeResult initialize(InitializeParams params) { this.workspaceRoot = Paths.get(params.rootUri); + this.sourcePath = new SourcePath(Set.of(workspaceRoot)); var c = new JsonObject(); c.addProperty("textDocumentSync", 2); // Incremental @@ -205,6 +207,17 @@ class JavaLanguageServer extends LanguageServer { @Override public void initialized() { this.compiler = createCompiler(); + + // Register for didChangeWatchedFiles notifications + var options = + new Object() { + public List watchers = + List.of( + new Object() { + public String globPattern = "**/*.java"; + }); + }; + client.registerCapability("workspace/didChangeWatchedFiles", gson.toJsonTree(options)); } @Override @@ -241,7 +254,29 @@ class JavaLanguageServer extends LanguageServer { } @Override - public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {} + public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) { + var changed = false; + var created = new HashSet<Path>(); + var deleted = new HashSet<Path>(); + for (var c : params.changes) { + if (!isJavaFile(c.uri)) continue; + var file = Paths.get(c.uri); + switch (c.type) { + case FileChangeType.Created: + created.add(file); + break; + case FileChangeType.Changed: + if (sourcePath.update(file)) changed = true; + break; + case FileChangeType.Deleted: + deleted.add(file); + break; + } + } + if (sourcePath.create(created)) changed = true; + if (sourcePath.delete(deleted)) changed = true; + if (changed) this.compiler = createCompiler(); + } private Integer completionItemKind(Element e) { switch (e.getKind()) { diff --git a/src/main/java/org/javacs/Parser.java b/src/main/java/org/javacs/Parser.java index d1d9bcb..aaacbc2 100644 --- a/src/main/java/org/javacs/Parser.java +++ b/src/main/java/org/javacs/Parser.java @@ -11,7 +11,6 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; -import java.util.function.Consumer; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -303,48 +302,46 @@ class Parser { return i; } - /** Find all already-imported symbols in all .java files in sourcePath */ - static ExistingImports existingImports(Collection<Path> sourcePath) { + /** Find all already-imported symbols in all .java files in workspace */ + static ExistingImports existingImports(Collection<Path> allJavaFiles) { var classes = new HashSet<String>(); var packages = new HashSet<String>(); var importClass = Pattern.compile("^import +(([\\w\\.]+)\\.\\w+);"); var importStar = Pattern.compile("^import +([\\w\\.]+)\\.\\*;"); var importSimple = Pattern.compile("^import +(\\w+);"); - Consumer<Path> findImports = - path -> { - try (var lines = Files.newBufferedReader(path)) { - while (true) { - var line = lines.readLine(); - // If we reach the end of the file, stop looking for imports - if (line == null) return; - // If we reach a class declaration, stop looking for imports - // TODO This could be a little more specific - if (line.contains("class")) return; - // import foo.bar.Doh; - var matchesClass = importClass.matcher(line); - if (matchesClass.matches()) { - String className = matchesClass.group(1), packageName = matchesClass.group(2); - packages.add(packageName); - classes.add(className); - } - // import foo.bar.* - var matchesStar = importStar.matcher(line); - if (matchesStar.matches()) { - var packageName = matchesStar.group(1); - packages.add(packageName); - } - // import Doh - var matchesSimple = importSimple.matcher(line); - if (matchesSimple.matches()) { - var className = matchesSimple.group(1); - classes.add(className); - } - } - } catch (IOException e) { - throw new RuntimeException(e); + for (var path : allJavaFiles) { + try (var lines = Files.newBufferedReader(path)) { + while (true) { + var line = lines.readLine(); + // If we reach the end of the file, stop looking for imports + if (line == null) break; + // If we reach a class declaration, stop looking for imports + // TODO This could be a little more specific + if (line.contains("class")) break; + // import foo.bar.Doh; + var matchesClass = importClass.matcher(line); + if (matchesClass.matches()) { + String className = matchesClass.group(1), packageName = matchesClass.group(2); + packages.add(packageName); + classes.add(className); } - }; - sourcePath.stream().flatMap(InferSourcePath::allJavaFiles).forEach(findImports); + // import foo.bar.* + var matchesStar = importStar.matcher(line); + if (matchesStar.matches()) { + var packageName = matchesStar.group(1); + packages.add(packageName); + } + // import Doh + var matchesSimple = importSimple.matcher(line); + if (matchesSimple.matches()) { + var className = matchesSimple.group(1); + classes.add(className); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } return new ExistingImports(classes, packages); } diff --git a/src/main/java/org/javacs/SourcePath.java b/src/main/java/org/javacs/SourcePath.java new file mode 100644 index 0000000..75c4d4c --- /dev/null +++ b/src/main/java/org/javacs/SourcePath.java @@ -0,0 +1,146 @@ +package org.javacs; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.logging.Logger; + +class SourcePath { + private final Set<Path> workspaceRoots; + /** All .java files under workspaceRoot */ + private final Set<Path> allJavaFiles; + /** Source roots, computed from allJavaFiles by looking at package declarations. */ + private Set<Path> sourceRoots = new HashSet<>(); + + public SourcePath(Set<Path> workspaceRoots) { + this.workspaceRoots = Collections.unmodifiableSet(workspaceRoots); + this.sourceRoots = sourcePath(workspaceRoots); + this.allJavaFiles = allJavaFilesInDirs(sourceRoots); + } + + /** + * A .java file has been created. Update allJavaFiles, but don't recalculate sourceRoots until the file is saved, + * because the user hasn't had a change to type in a package name yet. + */ + boolean create(Set<Path> javaFiles) { + if (javaFiles.isEmpty()) return false; + allJavaFiles.addAll(javaFiles); + return checkSourceRoots(); + } + + /** + * A .java file has been deleted. If the file is the last one in a particular source root, we should remove that + * source root. + */ + boolean delete(Set<Path> javaFiles) { + if (javaFiles.isEmpty()) return false; + allJavaFiles.removeAll(javaFiles); + return checkSourceRoots(); + } + + /** + * A .java file has been edited and saved. If the package declaration has been changed, we may need to recalculate + * sourceRoots. + */ + boolean update(Path javaFile) { + for (var root : sourceRoots) { + if (!javaFile.startsWith(root)) continue; + var dir = javaFile.getParent(); + var expectedPackageName = root.relativize(dir).toString().replace('/', '.'); + var parse = Parser.parse(javaFile); + var foundPackageName = Objects.toString(parse.getPackageName(), ""); + if (!expectedPackageName.equals(foundPackageName)) { + LOG.info( + String.format( + "%s is in %s, which implies package %s, but now has package %s", + javaFile.getFileName(), root, expectedPackageName, foundPackageName)); + return checkSourceRoots(); + } + } + return false; + } + + Set<Path> sourceRoots() { + return Collections.unmodifiableSet(sourceRoots); + } + + Set<Path> allJavaFiles() { + return Collections.unmodifiableSet(allJavaFiles); + } + + private boolean checkSourceRoots() { + var newSourceRoots = sourcePath(workspaceRoots); + if (!newSourceRoots.equals(sourceRoots)) { + LOG.info(String.format("Source path has changed from %s to %s", sourceRoots, newSourceRoots)); + sourceRoots = newSourceRoots; + return true; + } + return false; + } + + private static Set<Path> allJavaFilesInDirs(Set<Path> dirs) { + var all = new HashSet<Path>(); + var match = FileSystems.getDefault().getPathMatcher("glob:*.java"); + for (var dir : dirs) { + try { + Files.walk(dir).filter(java -> match.matches(java.getFileName())).forEach(all::add); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return all; + } + + private static Set<Path> sourcePath(Set<Path> workspaceRoots) { + LOG.info("Searching for source roots in " + workspaceRoots); + + var certaintyThreshold = 10; + var sourceRoots = new HashMap<Path, Integer>(); + fileLoop: + for (var file : allJavaFilesInDirs(workspaceRoots)) { + // First, check if we already have a high-confidence source root containing file + for (var root : sourceRoots.keySet()) { + var confidence = sourceRoots.get(root); + if (file.startsWith(root) && confidence > certaintyThreshold) { + continue fileLoop; + } + } + // Otherwise, parse the file and look at its package declaration + var parse = Parser.parse(file); + var packageName = Objects.toString(parse.getPackageName(), ""); + var packagePath = packageName.replace('.', File.separatorChar); + // If file has no package declaration, don't try to guess a source root + // This is probably a new file that the user will add a package declaration to later + if (packagePath.isEmpty()) { + LOG.warning("Ignoring file with missing package declaration " + file); + continue fileLoop; + } + // If path to file contradicts package declaration, give up + var dir = file.getParent(); + if (!dir.endsWith(packagePath)) { + LOG.warning("Java source file " + file + " is not in " + packagePath); + continue fileLoop; + } + // Otherwise, use the package declaration to guess the source root + var up = Paths.get(packagePath).getNameCount(); + var sourceRoot = dir; + for (int i = 0; i < up; i++) { + sourceRoot = sourceRoot.getParent(); + } + // Increment our confidence in sourceRoot as a source root + var count = sourceRoots.getOrDefault(sourceRoot, 0); + sourceRoots.put(sourceRoot, count + 1); + } + return sourceRoots.keySet(); + } + + private static final Logger LOG = Logger.getLogger("main"); +} diff --git a/src/main/java/org/javacs/lsp/FileEvent.java b/src/main/java/org/javacs/lsp/FileEvent.java index 2f766e3..a2c20a0 100644 --- a/src/main/java/org/javacs/lsp/FileEvent.java +++ b/src/main/java/org/javacs/lsp/FileEvent.java @@ -4,5 +4,6 @@ import java.net.URI; public class FileEvent { public URI uri; + // FileChangeType public int type; } diff --git a/src/main/java/org/javacs/lsp/LSP.java b/src/main/java/org/javacs/lsp/LSP.java index a9c2cbd..eede0d3 100644 --- a/src/main/java/org/javacs/lsp/LSP.java +++ b/src/main/java/org/javacs/lsp/LSP.java @@ -140,10 +140,10 @@ public class LSP { } @Override - public void registerCapability(String id, JsonElement options) { + public void registerCapability(String method, JsonElement options) { var params = new RegistrationParams(); params.id = UUID.randomUUID().toString(); - params.id = id; + params.method = method; params.registerOptions = options; notifyClient(send, "client/registerCapability", params); diff --git a/src/test/java/org/javacs/JavaCompilerServiceTest.java b/src/test/java/org/javacs/JavaCompilerServiceTest.java index 7b8d20c..8011789 100644 --- a/src/test/java/org/javacs/JavaCompilerServiceTest.java +++ b/src/test/java/org/javacs/JavaCompilerServiceTest.java @@ -8,12 +8,14 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collectors; import javax.lang.model.element.Element; @@ -28,7 +30,10 @@ public class JavaCompilerServiceTest { private JavaCompilerService compiler = new JavaCompilerService( - Collections.singleton(resourcesDir()), Collections.emptySet(), Collections.emptySet()); + Collections.singleton(resourcesDir()), + JavaCompilerServiceTest::allJavaFiles, + Collections.emptySet(), + Collections.emptySet()); static Path resourcesDir() { try { @@ -38,6 +43,16 @@ public class JavaCompilerServiceTest { } } + static Set<Path> allJavaFiles() { + try { + return Files.walk(resourcesDir()) + .filter(f -> f.getFileName().toString().endsWith(".java")) + .collect(Collectors.toSet()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private String contents(String resourceFile) { try (var in = JavaCompilerServiceTest.class.getResourceAsStream(resourceFile)) { return new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n")); @@ -233,7 +248,7 @@ public class JavaCompilerServiceTest { var to = compiler.compileFocus(resourceUri(file), contents(file), 6, 13).element(); var possible = compiler.potentialReferences(to); assertThat( - "GotoDefinition.java can have refernces to itself", + "GotoDefinition.java can have references to itself", possible, hasItem(hasToString(endsWith("/GotoDefinition.java")))); diff --git a/src/test/java/org/javacs/ParserFixImportsTest.java b/src/test/java/org/javacs/ParserFixImportsTest.java index eddd105..e935962 100644 --- a/src/test/java/org/javacs/ParserFixImportsTest.java +++ b/src/test/java/org/javacs/ParserFixImportsTest.java @@ -3,13 +3,21 @@ package org.javacs; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; -import java.util.Collections; +import java.io.IOException; +import java.nio.file.Files; +import java.util.stream.Collectors; import org.junit.Test; public class ParserFixImportsTest { @Test - public void findExistingImports() { - var find = Parser.existingImports(Collections.singleton(JavaCompilerServiceTest.resourcesDir())); + public void findExistingImports() throws IOException { + var allJavaFiles = + Files.walk(JavaCompilerServiceTest.resourcesDir()) + .filter(f -> f.getFileName().toString().endsWith(".java")) + .collect(Collectors.toSet()); + assertThat(allJavaFiles, not(empty())); + + var find = Parser.existingImports(allJavaFiles); assertThat(find.classes, hasItem("java.util.List")); assertThat(find.packages, hasItem("java.util")); } diff --git a/src/test/java/org/javacs/ParserTest.java b/src/test/java/org/javacs/ParserTest.java index 8d1419d..93ac5ed 100644 --- a/src/test/java/org/javacs/ParserTest.java +++ b/src/test/java/org/javacs/ParserTest.java @@ -4,7 +4,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.nio.file.Paths; -import java.util.Set; +import java.util.Collections; import org.junit.Test; public class ParserTest { @@ -58,7 +58,8 @@ public class ParserTest { public void findExistingImports() { var rel = Paths.get("src", "org", "javacs", "doimport"); var dir = LanguageServerFixture.DEFAULT_WORKSPACE_ROOT.resolve(rel); - var existing = Parser.existingImports(Set.of(dir)); + var sourcePath = new SourcePath(Collections.singleton(dir)); + var existing = Parser.existingImports(sourcePath.allJavaFiles()); assertThat(existing.classes, hasItems("java.util.List")); assertThat(existing.packages, hasItems("java.util", "java.io")); } |