diff options
author | George Fraser <george@fivetran.com> | 2018-12-27 12:27:25 -0800 |
---|---|---|
committer | George Fraser <george@fivetran.com> | 2018-12-27 12:27:25 -0800 |
commit | 62d4cd468264783efb95c3687188bd12d395f7cf (patch) | |
tree | 2d8fca91eae3edcca7befb222a888e167506e6a3 /src | |
parent | 6d08a795f5f39e35dfdb502ae86f1b9af51d1f0e (diff) | |
download | java-language-server-62d4cd468264783efb95c3687188bd12d395f7cf.zip |
Constructor refs almost work
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/org/javacs/CompileBatch.java | 31 | ||||
-rw-r--r-- | src/main/java/org/javacs/JavaCompilerService.java | 21 | ||||
-rw-r--r-- | src/main/java/org/javacs/JavaTextDocumentService.java | 6 | ||||
-rw-r--r-- | src/main/java/org/javacs/Ptr.java | 1 | ||||
-rw-r--r-- | src/test/java/org/javacs/CodeLensTest.java | 22 | ||||
-rw-r--r-- | src/test/java/org/javacs/FindReferencesTest.java | 19 | ||||
-rw-r--r-- | src/test/test-project/workspace/src/org/javacs/example/ConstructorRefs.java | 12 |
7 files changed, 94 insertions, 18 deletions
diff --git a/src/main/java/org/javacs/CompileBatch.java b/src/main/java/org/javacs/CompileBatch.java index e2514b6..88a728d 100644 --- a/src/main/java/org/javacs/CompileBatch.java +++ b/src/main/java/org/javacs/CompileBatch.java @@ -117,23 +117,29 @@ public class CompileBatch { && toStringEquals(to, from); } + private boolean isField(Element to) { + if (!(to instanceof VariableElement)) return false; + var field = (VariableElement) to; + return field.getEnclosingElement() instanceof TypeElement; + } + private Optional<TreePath> ref(TreePath from) { var root = from.getCompilationUnit(); var lines = root.getLineMap(); var to = trees.getElement(from); // Skip elements we can't find if (to == null) { - LOG.warning(String.format("No element for `%s`", from.getLeaf())); + // LOG.warning(String.format("No element for `%s`", from.getLeaf())); return Optional.empty(); } // Skip non-methods - if (!(to instanceof ExecutableElement || to instanceof TypeElement || to instanceof VariableElement)) { + if (!(to instanceof ExecutableElement || to instanceof TypeElement || isField(to))) { return Optional.empty(); } // TODO skip anything not on source path var result = trees.getPath(to); if (result == null) { - LOG.warning(String.format("Element `%s` has no TreePath", to)); + // LOG.warning(String.format("Element `%s` has no TreePath", to)); return Optional.empty(); } return Optional.of(result); @@ -167,6 +173,12 @@ public class CompileBatch { check(getCurrentPath()); return super.visitIdentifier(t, null); } + + @Override + public Void visitNewClass(NewClassTree t, Void __) { + check(getCurrentPath()); + return super.visitNewClass(t, null); + } } new FindReferencesElement().scan(root, null); LOG.info( @@ -199,11 +211,18 @@ public class CompileBatch { check(getCurrentPath()); return super.visitIdentifier(t, null); } + + @Override + public Void visitNewClass(NewClassTree t, Void __) { + check(getCurrentPath()); + return super.visitNewClass(t, null); + } } new IndexFile().scan(root, null); - LOG.info( - String.format( - "Found %d refs in %s", refs.size(), Paths.get(root.getSourceFile().toUri()).getFileName())); + if (refs.size() > 0) + LOG.info( + String.format( + "Found %d refs in %s", refs.size(), Paths.get(root.getSourceFile().toUri()).getFileName())); return refs; } diff --git a/src/main/java/org/javacs/JavaCompilerService.java b/src/main/java/org/javacs/JavaCompilerService.java index ded3788..cc73cb2 100644 --- a/src/main/java/org/javacs/JavaCompilerService.java +++ b/src/main/java/org/javacs/JavaCompilerService.java @@ -126,6 +126,7 @@ public class JavaCompilerService { } private boolean containsWord(String toPackage, String toClass, String name, Path file) { + if (!name.matches("\\w*")) throw new RuntimeException(String.format("`%s` is not a word", name)); var samePackage = Pattern.compile("^package +" + toPackage + ";"); var importClass = Pattern.compile("^import +" + toPackage + "\\." + toClass + ";"); var importStar = Pattern.compile("^import +" + toPackage + "\\.\\*;"); @@ -187,19 +188,29 @@ public class JavaCompilerService { return allFiles; } + // TODO should probably cache this public List<URI> potentialReferences(Element to) { + LOG.info(String.format("Find potential references to `%s`...", to)); + + // Find files that import toPackage.toClass and contain the word el var toPackage = packageName(to); var toClass = className(to); - // Enumerate all files on source path - var allFiles = allJavaSources(); - // Filter for files that import toPackage.toClass and contain the word el - // TODO should probably cache this var name = to.getSimpleName().toString(); + if (name.equals("<init>")) name = to.getEnclosingElement().getSimpleName().toString(); + LOG.info(String.format("...look for the word `%s` in files that import %s.%s", name, toPackage, toClass)); + + // Check all files on source path + var allFiles = allJavaSources(); + LOG.info(String.format("...check %d files on the source path", allFiles.size())); + + // Check files, one at a time var result = new ArrayList<URI>(); int nScanned = 0; for (var file : allFiles) { - if (toPackage.isEmpty() || containsWord(toPackage, toClass, name, file)) result.add(file.toUri()); + if (containsWord(toPackage, toClass, name, file)) result.add(file.toUri()); } + LOG.info(String.format("...%d files might have references to `%s`", result.size(), to)); + return result; } diff --git a/src/main/java/org/javacs/JavaTextDocumentService.java b/src/main/java/org/javacs/JavaTextDocumentService.java index 8a19ae0..672a288 100644 --- a/src/main/java/org/javacs/JavaTextDocumentService.java +++ b/src/main/java/org/javacs/JavaTextDocumentService.java @@ -456,13 +456,17 @@ class JavaTextDocumentService implements TextDocumentService { var toColumn = position.getPosition().getCharacter() + 1; var toEl = server.compiler.compileFocus(toUri, toContent, toLine, toColumn).element(); var fromFiles = server.compiler.potentialReferences(toEl); + if (fromFiles.isEmpty()) return CompletableFuture.completedFuture(List.of()); var batch = server.compiler.compileBatch(fromFiles); var fromTreePaths = batch.references(toEl); var result = new ArrayList<Location>(); for (var path : fromTreePaths) { var fromUri = path.getCompilationUnit().getSourceFile().toUri(); var fromRange = batch.range(path); - if (!fromRange.isPresent()) continue; + if (!fromRange.isPresent()) { + LOG.warning(String.format("Couldn't locate `%s`", path.getLeaf())); + continue; + } var from = new Location(fromUri.toString(), fromRange.get()); result.add(from); } diff --git a/src/main/java/org/javacs/Ptr.java b/src/main/java/org/javacs/Ptr.java index e958b59..176b99e 100644 --- a/src/main/java/org/javacs/Ptr.java +++ b/src/main/java/org/javacs/Ptr.java @@ -15,6 +15,7 @@ import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; +// TODO Ptr is really dangerous because it doesn't uniquely identify overloaded methods or constructors /** Ptr is a serialized TreePath, suitable for storing in Index and remember across compiler invocations */ public class Ptr { private final String path; diff --git a/src/test/java/org/javacs/CodeLensTest.java b/src/test/java/org/javacs/CodeLensTest.java index 553e3e5..d086018 100644 --- a/src/test/java/org/javacs/CodeLensTest.java +++ b/src/test/java/org/javacs/CodeLensTest.java @@ -52,10 +52,17 @@ public class CodeLensTest { return commands; } + private List<String> titles(List<? extends CodeLens> lenses) { + var titles = new ArrayList<String>(); + for (var lens : lenses) { + titles.add(lens.getCommand().getTitle()); + } + return titles; + } + @Test - public void codeLens() { - var file = "/org/javacs/example/HasTest.java"; - var lenses = lenses(file); + public void testMethods() { + var lenses = lenses("/org/javacs/example/HasTest.java"); assertThat(lenses, not(empty())); var commands = commands(lenses); @@ -63,4 +70,13 @@ public class CodeLensTest { assertThat(commands, hasItem(containsString("HasTest, testMethod"))); assertThat(commands, hasItem(containsString("HasTest, otherTestMethod"))); } + + @Test + public void constructorReferences() { + var lenses = lenses("/org/javacs/example/ConstructorRefs.java"); + assertThat(lenses, not(empty())); + + var titles = titles(lenses); + assertThat(titles, hasItem(containsString("1 references"))); + } } diff --git a/src/test/java/org/javacs/FindReferencesTest.java b/src/test/java/org/javacs/FindReferencesTest.java index 50b8ea5..4cf0d2a 100644 --- a/src/test/java/org/javacs/FindReferencesTest.java +++ b/src/test/java/org/javacs/FindReferencesTest.java @@ -3,10 +3,11 @@ package org.javacs; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.net.URI; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Logger; -import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.ReferenceParams; import org.eclipse.lsp4j.TextDocumentIdentifier; @@ -17,7 +18,7 @@ public class FindReferencesTest { private static final JavaLanguageServer server = LanguageServerFixture.getJavaLanguageServer(); - protected List<? extends Location> items(String file, int row, int column) { + protected List<String> items(String file, int row, int column) { var uri = FindResource.uri(file); var params = new ReferenceParams(); @@ -26,7 +27,14 @@ public class FindReferencesTest { params.setPosition(new Position(row - 1, column - 1)); try { - return server.getTextDocumentService().references(params).get(); + var locations = server.getTextDocumentService().references(params).get(); + var strings = new ArrayList<String>(); + for (var l : locations) { + var fileName = Parser.fileName(URI.create(l.getUri())); + var line = l.getRange().getStart().getLine(); + strings.add(String.format("%s(%d)", fileName, line + 1)); + } + return strings; } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -36,4 +44,9 @@ public class FindReferencesTest { public void findAllReferences() { assertThat(items("/org/javacs/example/GotoOther.java", 6, 30), not(empty())); } + + @Test + public void findConstructorReferences() { + assertThat(items("/org/javacs/example/ConstructorRefs.java", 4, 10), contains("ConstructorRefs.java(9)")); + } } diff --git a/src/test/test-project/workspace/src/org/javacs/example/ConstructorRefs.java b/src/test/test-project/workspace/src/org/javacs/example/ConstructorRefs.java new file mode 100644 index 0000000..4e033de --- /dev/null +++ b/src/test/test-project/workspace/src/org/javacs/example/ConstructorRefs.java @@ -0,0 +1,12 @@ +package org.javacs.example; + +class ConstructorRefs { + ConstructorRefs(String stringConstructor) { + } + ConstructorRefs(int intConstructor) { + } + static void main() { + new ConstructorRefs("1"); + new ConstructorRefs(1); + } +}
\ No newline at end of file |