summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Fraser <george@fivetran.com>2018-12-27 12:27:25 -0800
committerGeorge Fraser <george@fivetran.com>2018-12-27 12:27:25 -0800
commit62d4cd468264783efb95c3687188bd12d395f7cf (patch)
tree2d8fca91eae3edcca7befb222a888e167506e6a3 /src
parent6d08a795f5f39e35dfdb502ae86f1b9af51d1f0e (diff)
downloadjava-language-server-62d4cd468264783efb95c3687188bd12d395f7cf.zip
Constructor refs almost work
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/javacs/CompileBatch.java31
-rw-r--r--src/main/java/org/javacs/JavaCompilerService.java21
-rw-r--r--src/main/java/org/javacs/JavaTextDocumentService.java6
-rw-r--r--src/main/java/org/javacs/Ptr.java1
-rw-r--r--src/test/java/org/javacs/CodeLensTest.java22
-rw-r--r--src/test/java/org/javacs/FindReferencesTest.java19
-rw-r--r--src/test/test-project/workspace/src/org/javacs/example/ConstructorRefs.java12
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