diff options
author | George Fraser <george@fivetran.com> | 2018-12-30 22:49:30 -0800 |
---|---|---|
committer | George Fraser <george@fivetran.com> | 2018-12-30 22:49:30 -0800 |
commit | d9af3a7527cc171b7b7e73415d057b5a71fac537 (patch) | |
tree | 9adfbb2c267366ee5f409a72fb8b05035066c8ba /src | |
parent | bab1f5a754c72d6b10c6c43af2a17d25bd93cdef (diff) | |
download | java-language-server-d9af3a7527cc171b7b7e73415d057b5a71fac537.zip |
Fix goto overload
Diffstat (limited to 'src')
7 files changed, 142 insertions, 88 deletions
diff --git a/src/main/java/org/javacs/CompileFocus.java b/src/main/java/org/javacs/CompileFocus.java index 4cf3308..29dd70e 100644 --- a/src/main/java/org/javacs/CompileFocus.java +++ b/src/main/java/org/javacs/CompileFocus.java @@ -78,6 +78,10 @@ public class CompileFocus { return trees.getElement(path); } + public Optional<TreePath> path(Element e) { + return Optional.ofNullable(trees.getPath(e)); + } + /** Find all overloads for the smallest method call that includes the cursor */ public Optional<MethodInvocation> methodInvocation() { LOG.info(String.format("Find method invocation around %s(%d,%d)...", file, line, character)); @@ -296,6 +300,10 @@ public class CompileFocus { return result; } else { var type = trees.getTypeMirror(path); + if (type == null) { + LOG.warning(String.format("`...%s` has not type", path.getLeaf())); + return List.of(); + } if (hasMembers(type)) { LOG.info(String.format("...completing virtual members of %s", type)); diff --git a/src/main/java/org/javacs/JavaLanguageServer.java b/src/main/java/org/javacs/JavaLanguageServer.java index b2a9c09..e55923a 100644 --- a/src/main/java/org/javacs/JavaLanguageServer.java +++ b/src/main/java/org/javacs/JavaLanguageServer.java @@ -698,19 +698,29 @@ class JavaLanguageServer extends LanguageServer { var fromLine = position.position.line + 1; var fromColumn = position.position.character + 1; var fromContent = contents(fromUri).content; + LOG.info(String.format("Go-to-def at %s:%d...", fromUri, fromLine)); var fromFocus = compiler.compileFocus(fromUri, fromContent, fromLine, fromColumn); var toEl = fromFocus.element(); - var toUri = fromFocus.declaringFile(toEl); - if (!toUri.isPresent()) return List.of(); - if (!isJavaFile(toUri.get())) return List.of(); - var toContent = contents(toUri.get()).content; - var toFile = compiler.compileFile(toUri.get(), toContent); - var toPath = toFile.find(new Ptr(toEl)); - if (!toPath.isPresent()) return List.of(); + LOG.info(String.format("...looking for definition of `%s`", toEl)); + var toPath = fromFocus.path(toEl); + if (!toPath.isPresent()) { + LOG.info(String.format("...couldn't find declaring file, giving up")); + return List.of(); + } + var toUri = toPath.get().getCompilationUnit().getSourceFile().toUri(); + if (!isJavaFile(toUri)) { + LOG.info(String.format("...declaring file %s isn't a .java file", toUri)); + return List.of(); + } + var toContent = contents(toUri).content; + var toFile = compiler.compileFile(toUri, toContent); // Figure out where in the file the definition is var toRange = toFile.range(toPath.get()); - if (!toRange.isPresent()) return List.of(); - var to = new Location(toUri.get(), toRange.get()); + if (!toRange.isPresent()) { + LOG.info(String.format("Couldn't find `%s` in %s", toPath.get(), toUri)); + return List.of(); + } + var to = new Location(toUri, toRange.get()); return List.of(to); } diff --git a/src/test/java/org/javacs/GotoTest.java b/src/test/java/org/javacs/GotoTest.java index 74bc9dd..7ad39ea 100644 --- a/src/test/java/org/javacs/GotoTest.java +++ b/src/test/java/org/javacs/GotoTest.java @@ -16,91 +16,91 @@ public class GotoTest { @Test public void localVariable() { - var suggestions = doGoto(file, 9, 8); + var suggestions = doGoto(file, 10, 9); assertThat(suggestions, contains("Goto.java:5")); } @Test public void defaultConstructor() { - var suggestions = doGoto(defaultConstructorFile, 4, 45); + var suggestions = doGoto(defaultConstructorFile, 5, 46); assertThat(suggestions, contains("GotoDefaultConstructor.java:3")); } @Test public void constructor() { - var suggestions = doGoto(file, 10, 20); + var suggestions = doGoto(file, 11, 21); assertThat(suggestions, contains("Goto.java:3")); } @Test public void className() { - var suggestions = doGoto(file, 15, 8); + var suggestions = doGoto(file, 16, 9); assertThat(suggestions, contains("Goto.java:3")); } @Test public void staticField() { - var suggestions = doGoto(file, 12, 21); + var suggestions = doGoto(file, 13, 22); assertThat(suggestions, contains("Goto.java:36")); } @Test public void field() { - var suggestions = doGoto(file, 13, 21); + var suggestions = doGoto(file, 14, 22); assertThat(suggestions, contains("Goto.java:37")); } @Test public void staticMethod() { - var suggestions = doGoto(file, 15, 13); + var suggestions = doGoto(file, 16, 14); assertThat(suggestions, contains("Goto.java:38")); } @Test public void method() { - var suggestions = doGoto(file, 16, 13); + var suggestions = doGoto(file, 17, 14); assertThat(suggestions, contains("Goto.java:41")); } @Test public void staticMethodReference() { - var suggestions = doGoto(file, 18, 26); + var suggestions = doGoto(file, 19, 27); assertThat(suggestions, contains("Goto.java:38")); } @Test public void methodReference() { - var suggestions = doGoto(file, 19, 26); + var suggestions = doGoto(file, 20, 27); assertThat(suggestions, contains("Goto.java:41")); } @Test public void otherStaticMethod() { - var suggestions = doGoto(file, 28, 24); + var suggestions = doGoto(file, 29, 25); assertThat(suggestions, contains(startsWith("GotoOther.java:"))); } @Test public void otherMethod() { - var suggestions = doGoto(file, 29, 17); + var suggestions = doGoto(file, 30, 18); assertThat(suggestions, contains(startsWith("GotoOther.java:"))); } @Test public void otherCompiledFile() { - var suggestions = doGoto(file, 28, 24); + var suggestions = doGoto(file, 29, 25); assertThat(suggestions, contains(startsWith("GotoOther.java:"))); } @@ -108,7 +108,7 @@ public class GotoTest { @Test @Ignore // TODO public void typeParam() { - var suggestions = doGoto(file, 45, 11); + var suggestions = doGoto(file, 46, 12); assertThat(suggestions, contains("Goto.java:3")); } @@ -117,8 +117,26 @@ public class GotoTest { public void gotoEnum() { String file = "/org/javacs/example/GotoEnum.java"; - assertThat(doGoto(file, 5, 30), not(empty())); - assertThat(doGoto(file, 5, 35), not(empty())); + assertThat(doGoto(file, 6, 31), not(empty())); + assertThat(doGoto(file, 6, 36), not(empty())); + } + + @Test + public void gotoOverload() { + String file = "/org/javacs/example/GotoOverload.java"; + + assertThat(doGoto(file, 7, 12), contains("GotoOverload.java:4")); + assertThat(doGoto(file, 8, 12), contains("GotoOverload.java:12")); + assertThat(doGoto(file, 9, 12), contains("GotoOverload.java:16")); + } + + @Test + public void gotoOverloadInOtherFile() { + String file = "/org/javacs/example/GotoOverloadInOtherFile.java"; + + assertThat(doGoto(file, 5, 25), contains("GotoOverload.java:4")); + assertThat(doGoto(file, 6, 25), contains("GotoOverload.java:12")); + assertThat(doGoto(file, 7, 25), contains("GotoOverload.java:16")); } private static final JavaLanguageServer server = LanguageServerFixture.getJavaLanguageServer(); @@ -130,8 +148,8 @@ public class GotoTest { Position position = new Position(); - position.line = row; - position.character = column; + position.line = row - 1; + position.character = column - 1; TextDocumentPositionParams p = new TextDocumentPositionParams(); diff --git a/src/test/java/org/javacs/JavaCompilerServiceTest.java b/src/test/java/org/javacs/JavaCompilerServiceTest.java index 8c67cdf..b0f80e1 100644 --- a/src/test/java/org/javacs/JavaCompilerServiceTest.java +++ b/src/test/java/org/javacs/JavaCompilerServiceTest.java @@ -3,11 +3,8 @@ package org.javacs; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; -import java.io.BufferedReader; 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; @@ -16,6 +13,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Set; +import java.util.StringJoiner; import java.util.logging.Logger; import java.util.stream.Collectors; import javax.lang.model.element.Element; @@ -53,26 +51,30 @@ public class JavaCompilerServiceTest { } } - private String contents(String resourceFile) { - try (var in = JavaCompilerServiceTest.class.getResourceAsStream(resourceFile)) { - return new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n")); + static String contents(String resourceFile) { + var root = JavaCompilerServiceTest.simpleProjectSrc(); + var file = root.resolve(resourceFile); + List<String> lines; + try { + lines = Files.readAllLines(file); } catch (IOException e) { throw new RuntimeException(e); } + var join = new StringJoiner("\n"); + for (var l : lines) join.add(l); + return join.toString(); } private URI resourceUri(String resourceFile) { - try { - return JavaCompilerServiceTest.class.getResource(resourceFile).toURI(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } + var root = JavaCompilerServiceTest.simpleProjectSrc(); + var file = root.resolve(resourceFile); + return file.toUri(); } @Test public void element() { - var uri = resourceUri("/HelloWorld.java"); - var contents = contents("/HelloWorld.java"); + var uri = resourceUri("HelloWorld.java"); + var contents = contents("HelloWorld.java"); var found = compiler.compileFocus(uri, contents, 3, 24).element(); assertThat(found.getSimpleName(), hasToString(containsString("println"))); @@ -80,8 +82,8 @@ public class JavaCompilerServiceTest { @Test public void elementWithError() { - var uri = resourceUri("/CompleteMembers.java"); - var contents = contents("/CompleteMembers.java"); + var uri = resourceUri("CompleteMembers.java"); + var contents = contents("CompleteMembers.java"); var found = compiler.compileFocus(uri, contents, 3, 12).element(); assertThat(found, notNullValue()); @@ -105,8 +107,8 @@ public class JavaCompilerServiceTest { @Test public void identifiers() { - var uri = resourceUri("/CompleteIdentifiers.java"); - var contents = contents("/CompleteIdentifiers.java"); + var uri = resourceUri("CompleteIdentifiers.java"); + var contents = contents("CompleteIdentifiers.java"); var focus = compiler.compileFocus(uri, contents, 13, 21); var found = focus.scopeMembers("complete"); var names = elementNames(found); @@ -123,8 +125,8 @@ public class JavaCompilerServiceTest { @Test public void identifiersInMiddle() { - var uri = resourceUri("/CompleteInMiddle.java"); - var contents = contents("/CompleteInMiddle.java"); + var uri = resourceUri("CompleteInMiddle.java"); + var contents = contents("CompleteInMiddle.java"); var focus = compiler.compileFocus(uri, contents, 13, 21); var found = focus.scopeMembers("complete"); var names = elementNames(found); @@ -141,8 +143,8 @@ public class JavaCompilerServiceTest { @Test public void completeIdentifiers() { - var uri = resourceUri("/CompleteIdentifiers.java"); - var contents = contents("/CompleteIdentifiers.java"); + var uri = resourceUri("CompleteIdentifiers.java"); + var contents = contents("CompleteIdentifiers.java"); var ctx = compiler.parseFile(uri, contents).completionContext(13, 21).get(); var focus = compiler.compileFocus(uri, contents, ctx.line, ctx.character); var found = focus.completeIdentifiers(ctx.inClass, ctx.inMethod, ctx.partialName); @@ -160,8 +162,8 @@ public class JavaCompilerServiceTest { @Test public void members() { - var uri = resourceUri("/CompleteMembers.java"); - var contents = contents("/CompleteMembers.java"); + var uri = resourceUri("CompleteMembers.java"); + var contents = contents("CompleteMembers.java"); var focus = compiler.compileFocus(uri, contents, 3, 14); var found = focus.completeMembers(false); var names = completionNames(found); @@ -172,8 +174,8 @@ public class JavaCompilerServiceTest { @Test public void completeMembers() { - var uri = resourceUri("/CompleteMembers.java"); - var contents = contents("/CompleteMembers.java"); + var uri = resourceUri("CompleteMembers.java"); + var contents = contents("CompleteMembers.java"); var ctx = compiler.parseFile(uri, contents).completionContext(3, 15).get(); var focus = compiler.compileFocus(uri, contents, ctx.line, ctx.character); var found = focus.completeMembers(false); @@ -185,8 +187,8 @@ public class JavaCompilerServiceTest { @Test public void completeExpression() { - var uri = resourceUri("/CompleteExpression.java"); - var contents = contents("/CompleteExpression.java"); + var uri = resourceUri("CompleteExpression.java"); + var contents = contents("CompleteExpression.java"); var ctx = compiler.parseFile(uri, contents).completionContext(3, 37).get(); var focus = compiler.compileFocus(uri, contents, ctx.line, ctx.character); var found = focus.completeMembers(false); @@ -198,8 +200,8 @@ public class JavaCompilerServiceTest { @Test public void completeClass() { - var uri = resourceUri("/CompleteClass.java"); - var contents = contents("/CompleteClass.java"); + var uri = resourceUri("CompleteClass.java"); + var contents = contents("CompleteClass.java"); var ctx = compiler.parseFile(uri, contents).completionContext(3, 23).get(); var focus = compiler.compileFocus(uri, contents, ctx.line, ctx.character); var found = focus.completeMembers(false); @@ -212,8 +214,8 @@ public class JavaCompilerServiceTest { @Test public void completeImports() { - var uri = resourceUri("/CompleteImports.java"); - var contents = contents("/CompleteImports.java"); + var uri = resourceUri("CompleteImports.java"); + var contents = contents("CompleteImports.java"); var ctx = compiler.parseFile(uri, contents).completionContext(1, 18).get(); var focus = compiler.compileFocus(uri, contents, ctx.line, ctx.character); var found = focus.completeMembers(false); @@ -244,7 +246,7 @@ public class JavaCompilerServiceTest { @Test public void references() { - var file = "/GotoDefinition.java"; + var file = "GotoDefinition.java"; var to = compiler.compileFocus(resourceUri(file), contents(file), 6, 13).element(); var possible = compiler.potentialReferences(to); assertThat( @@ -267,7 +269,7 @@ public class JavaCompilerServiceTest { @Test public void countReferences() { - var file = "/GotoDefinition.java"; + var file = "GotoDefinition.java"; var refs = compiler.countReferences(resourceUri(file), contents(file), ReportProgress.EMPTY); var stringify = new HashMap<String, Integer>(); for (var kv : refs.entrySet()) { @@ -279,8 +281,8 @@ public class JavaCompilerServiceTest { @Test public void overloads() { - var uri = resourceUri("/Overloads.java"); - var contents = contents("/Overloads.java"); + var uri = resourceUri("Overloads.java"); + var contents = contents("Overloads.java"); var found = compiler.compileFocus(uri, contents, 3, 15).methodInvocation().get(); var strings = found.overloads.stream().map(Object::toString).collect(Collectors.toList()); @@ -290,7 +292,7 @@ public class JavaCompilerServiceTest { @Test public void lint() { - var uri = resourceUri("/HasError.java"); + var uri = resourceUri("HasError.java"); var files = Collections.singleton(uri); var diags = compiler.compileBatch(files).lint(); assertThat(diags, not(empty())); @@ -298,8 +300,8 @@ public class JavaCompilerServiceTest { @Test public void localDoc() { - var uri = resourceUri("/LocalMethodDoc.java"); - var contents = contents("/LocalMethodDoc.java"); + var uri = resourceUri("LocalMethodDoc.java"); + var contents = contents("LocalMethodDoc.java"); var method = compiler.compileFocus(uri, contents, 3, 21).methodInvocation().get().activeMethod.get(); var doc = compiler.docs().methodDoc(method); assertTrue(doc.isPresent()); @@ -308,8 +310,8 @@ public class JavaCompilerServiceTest { @Test public void fixImports() { - var uri = resourceUri("/MissingImport.java"); - var contents = contents("/MissingImport.java"); + var uri = resourceUri("MissingImport.java"); + var contents = contents("MissingImport.java"); var qualifiedNames = compiler.compileFile(uri, contents).fixImports().fixedImports; assertThat(qualifiedNames, hasItem("java.util.List")); } diff --git a/src/test/java/org/javacs/PrunerTest.java b/src/test/java/org/javacs/PrunerTest.java index 361070c..fc1d163 100644 --- a/src/test/java/org/javacs/PrunerTest.java +++ b/src/test/java/org/javacs/PrunerTest.java @@ -1,51 +1,39 @@ package org.javacs; import static org.hamcrest.Matchers.*; +import static org.javacs.JavaCompilerServiceTest.contents; import static org.junit.Assert.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.net.URI; -import java.util.stream.Collectors; import org.junit.Test; public class PrunerTest { - private String contents(String resourceFile) { - try (var in = JavaCompilerServiceTest.class.getResourceAsStream(resourceFile)) { - return new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - @Test public void pruneMethods() { - var actual = new Pruner(URI.create("/PruneMethods.java"), contents("/PruneMethods.java")).prune(6, 19); - var expected = contents("/PruneMethods_erased.java"); + var actual = new Pruner(URI.create("/PruneMethods.java"), contents("PruneMethods.java")).prune(6, 19); + var expected = contents("PruneMethods_erased.java"); assertThat(actual, equalToIgnoringWhiteSpace(expected)); } @Test public void pruneToEndOfBlock() { - var actual = - new Pruner(URI.create("/PruneToEndOfBlock.java"), contents("/PruneToEndOfBlock.java")).prune(4, 18); - var expected = contents("/PruneToEndOfBlock_erased.java"); + var actual = new Pruner(URI.create("/PruneToEndOfBlock.java"), contents("PruneToEndOfBlock.java")).prune(4, 18); + var expected = contents("PruneToEndOfBlock_erased.java"); assertThat(actual, equalToIgnoringWhiteSpace(expected)); } @Test public void pruneMiddle() { - var actual = new Pruner(URI.create("/PruneMiddle.java"), contents("/PruneMiddle.java")).prune(4, 12); - var expected = contents("/PruneMiddle_erased.java"); + var actual = new Pruner(URI.create("/PruneMiddle.java"), contents("PruneMiddle.java")).prune(4, 12); + var expected = contents("PruneMiddle_erased.java"); assertThat(actual, equalToIgnoringWhiteSpace(expected)); } @Test public void pruneDot() { - var actual = new Pruner(URI.create("/PruneDot.java"), contents("/PruneDot.java")).prune(3, 11); - var expected = contents("/PruneDot_erased.java"); + var actual = new Pruner(URI.create("/PruneDot.java"), contents("PruneDot.java")).prune(3, 11); + var expected = contents("PruneDot_erased.java"); assertThat(actual, equalToIgnoringWhiteSpace(expected)); } } diff --git a/src/test/test-project/workspace/src/org/javacs/example/GotoOverload.java b/src/test/test-project/workspace/src/org/javacs/example/GotoOverload.java new file mode 100644 index 0000000..73b773b --- /dev/null +++ b/src/test/test-project/workspace/src/org/javacs/example/GotoOverload.java @@ -0,0 +1,19 @@ +package org.javacs.example; + +class GotoOverload { + static int overloaded = 1; + + static void main() { + overloaded = 10; + overloaded(1); + overloaded("1"); + } + + static void overloaded(int x) { + + } + + static void overloaded(String x) { + + } +}
\ No newline at end of file diff --git a/src/test/test-project/workspace/src/org/javacs/example/GotoOverloadInOtherFile.java b/src/test/test-project/workspace/src/org/javacs/example/GotoOverloadInOtherFile.java new file mode 100644 index 0000000..8e49b2f --- /dev/null +++ b/src/test/test-project/workspace/src/org/javacs/example/GotoOverloadInOtherFile.java @@ -0,0 +1,9 @@ +package org.javacs.example; + +class GotoOverloadInOtherFile { + void main() { + GotoOverload.overloaded = 10; + GotoOverload.overloaded(1); + GotoOverload.overloaded("1"); + } +}
\ No newline at end of file |