summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODOS.md1
-rw-r--r--src/main/java/org/javacs/CompileFile.java2
-rw-r--r--src/main/java/org/javacs/CompileFocus.java4
-rw-r--r--src/main/java/org/javacs/InferSourcePath.java82
-rw-r--r--src/main/java/org/javacs/JavaCompilerService.java20
-rw-r--r--src/main/java/org/javacs/JavaLanguageServer.java45
-rw-r--r--src/main/java/org/javacs/Parser.java71
-rw-r--r--src/main/java/org/javacs/SourcePath.java146
-rw-r--r--src/main/java/org/javacs/lsp/FileEvent.java1
-rw-r--r--src/main/java/org/javacs/lsp/LSP.java4
-rw-r--r--src/test/java/org/javacs/JavaCompilerServiceTest.java19
-rw-r--r--src/test/java/org/javacs/ParserFixImportsTest.java14
-rw-r--r--src/test/java/org/javacs/ParserTest.java5
13 files changed, 267 insertions, 147 deletions
diff --git a/TODOS.md b/TODOS.md
index b0d8e3b..f1ad190 100644
--- a/TODOS.md
+++ b/TODOS.md
@@ -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"));
}