summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Fraser <george@fivetran.com>2018-12-27 14:24:24 -0800
committerGeorge Fraser <george@fivetran.com>2018-12-27 14:24:24 -0800
commit84982255bbcf53bec86e31b6cd4f7282169ccc5d (patch)
treea79362475400e039228ecb06ab3a415f0f23e86a /src
parent5b2339d7a7a33edd7fe6390181b2e26e167e3c92 (diff)
downloadjava-language-server-84982255bbcf53bec86e31b6cd4f7282169ccc5d.zip
Fix enum completions, cache hovers
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/javacs/CompileFile.java10
-rw-r--r--src/main/java/org/javacs/CompileFocus.java20
-rw-r--r--src/main/java/org/javacs/JavaTextDocumentService.java38
-rw-r--r--src/test/java/org/javacs/CompletionsTest.java12
-rw-r--r--src/test/test-project/workspace/src/org/javacs/example/AutocompleteCase.java8
-rw-r--r--src/test/test-project/workspace/src/org/javacs/example/AutocompleteCaseFromClasspath.java15
6 files changed, 81 insertions, 22 deletions
diff --git a/src/main/java/org/javacs/CompileFile.java b/src/main/java/org/javacs/CompileFile.java
index 826f7e9..d928508 100644
--- a/src/main/java/org/javacs/CompileFile.java
+++ b/src/main/java/org/javacs/CompileFile.java
@@ -13,8 +13,8 @@ import org.eclipse.lsp4j.Range;
public class CompileFile {
private final JavaCompilerService parent;
- private final URI file;
- private final String contents;
+ final URI file;
+ final String contents;
private final JavacTask task;
private final Trees trees;
private final CompilationUnitTree root;
@@ -39,6 +39,12 @@ public class CompileFile {
profiler.print();
}
+ public Optional<Element> element(int line, int character) {
+ var path = CompileFocus.findPath(task, root, line, character);
+ var el = trees.getElement(path);
+ return Optional.ofNullable(el);
+ }
+
public Optional<TreePath> find(Ptr target) {
class FindPtr extends TreePathScanner<Void, Void> {
TreePath found = null;
diff --git a/src/main/java/org/javacs/CompileFocus.java b/src/main/java/org/javacs/CompileFocus.java
index e8a9a27..4183faf 100644
--- a/src/main/java/org/javacs/CompileFocus.java
+++ b/src/main/java/org/javacs/CompileFocus.java
@@ -54,7 +54,7 @@ public class CompileFocus {
throw new RuntimeException(e);
}
profiler.print();
- this.path = findPath();
+ this.path = findPath(task, root, line, character);
}
/** Create a task that compiles a single file */
@@ -200,17 +200,21 @@ public class CompileFocus {
/** Find all case options in the switch expression surrounding line:character */
public List<Completion> completeCases() {
- // Find path to case
- var types = task.getTypes();
+ LOG.info(String.format("Complete enum constants following `%s`...", path.getLeaf()));
+
// Find surrounding switch
var path = this.path;
while (!(path.getLeaf() instanceof SwitchTree)) path = path.getParentPath();
var leaf = (SwitchTree) path.getLeaf();
path = new TreePath(path, leaf.getExpression());
+ LOG.info(String.format("...found switch expression `%s`", leaf.getExpression()));
+
// Get members of switched type
- var element = trees.getElement(path);
- var type = element.asType();
+ var type = trees.getTypeMirror(path);
+ LOG.info(String.format("...switched expression has type `%s`", type));
+ var types = task.getTypes();
var definition = types.asElement(type);
+ LOG.info(String.format("...switched expression has definition `%s`", definition));
var result = new ArrayList<Completion>();
for (var member : definition.getEnclosedElements()) {
if (member.getKind() == ElementKind.ENUM_CONSTANT) result.add(Completion.ofElement(member));
@@ -833,7 +837,8 @@ public class CompileFocus {
}
/** Find the smallest tree that includes the cursor */
- private TreePath findPath() {
+ static TreePath findPath(JavacTask task, CompilationUnitTree root, int line, int character) {
+ var trees = Trees.instance(task);
var pos = trees.getSourcePositions();
var cursor = root.getLineMap().getPosition(line, character);
@@ -868,7 +873,8 @@ public class CompileFocus {
var find = new FindSmallest();
find.scan(root, null);
if (find.found == null) {
- var message = String.format("No TreePath to %s %d:%d", file, line, character);
+ var uri = root.getSourceFile().toUri();
+ var message = String.format("No TreePath to %s %d:%d", uri, line, character);
throw new RuntimeException(message);
}
return find.found;
diff --git a/src/main/java/org/javacs/JavaTextDocumentService.java b/src/main/java/org/javacs/JavaTextDocumentService.java
index c23244b..6707cd0 100644
--- a/src/main/java/org/javacs/JavaTextDocumentService.java
+++ b/src/main/java/org/javacs/JavaTextDocumentService.java
@@ -10,7 +10,6 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
-import java.lang.annotation.Annotation;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -254,6 +253,9 @@ class JavaTextDocumentService implements TextDocumentService {
case CLASS:
result.append("class");
break;
+ case ENUM:
+ result.append("enum");
+ break;
default:
LOG.warning("Don't know what to call type element " + t);
result.append("???");
@@ -304,19 +306,39 @@ class JavaTextDocumentService implements TextDocumentService {
} else return Optional.empty();
}
+ private CompileFile hoverCache;
+
+ private void updateHoverCache(URI uri, String contents) {
+ if (hoverCache == null || !hoverCache.file.equals(uri) || !hoverCache.contents.equals(contents)) {
+ LOG.info("File has changed since last hover, recompiling");
+ hoverCache = server.compiler.compileFile(uri, contents);
+ }
+ }
+
@Override
public CompletableFuture<Hover> hover(TextDocumentPositionParams position) {
+ // Compile entire file if it's changed since last hover
var uri = URI.create(position.getTextDocument().getUri());
var content = contents(uri).content;
+ updateHoverCache(uri, content);
+
+ // Find element undeer cursor
var line = position.getPosition().getLine() + 1;
var column = position.getPosition().getCharacter() + 1;
- var e = server.compiler.compileFocus(uri, content, line, column).element();
- if (e != null) {
- List<Either<String, MarkedString>> result = new ArrayList<>();
- result.add(Either.forRight(new MarkedString("java.hover", hoverCode(e))));
- hoverDocs(e).ifPresent(doc -> result.add(Either.forLeft(doc)));
- return CompletableFuture.completedFuture(new Hover(result));
- } else return CompletableFuture.completedFuture(new Hover(Collections.emptyList()));
+ var el = hoverCache.element(line, column);
+ if (el.isEmpty()) return CompletableFuture.completedFuture(new Hover(Collections.emptyList()));
+
+ // Add code hover message
+ var result = new ArrayList<Either<String, MarkedString>>();
+ var code = hoverCode(el.get());
+ result.add(Either.forRight(new MarkedString("java.hover", code)));
+ // Add docs hover message
+ var docs = hoverDocs(el.get());
+ if (docs.isPresent()) {
+ result.add(Either.forLeft(docs.get()));
+ }
+
+ return CompletableFuture.completedFuture(new Hover(result));
}
private List<ParameterInformation> signatureParamsFromDocs(MethodTree method, DocCommentTree doc) {
diff --git a/src/test/java/org/javacs/CompletionsTest.java b/src/test/java/org/javacs/CompletionsTest.java
index 569a620..1a8171d 100644
--- a/src/test/java/org/javacs/CompletionsTest.java
+++ b/src/test/java/org/javacs/CompletionsTest.java
@@ -667,14 +667,22 @@ public class CompletionsTest extends CompletionsBase {
}
@Test
- public void switchCase() {
+ public void enumConstantFromSourcePath() {
var file = "/org/javacs/example/AutocompleteCase.java";
- var suggestions = insertText(file, 8, 18);
+ var suggestions = insertText(file, 6, 18);
assertThat("suggests enum options", suggestions, containsInAnyOrder("Foo", "Bar"));
}
@Test
+ public void enumConstantFromClassPath() {
+ var file = "/org/javacs/example/AutocompleteCaseFromClassPath.java";
+ var suggestions = insertText(file, 8, 18);
+
+ assertThat("suggests enum options", suggestions, containsInAnyOrder("FULL", "LONG", "MEDIUM", "SHORT"));
+ }
+
+ @Test
public void staticStarImport() {
var file = "/org/javacs/example/AutocompleteStaticImport.java";
var suggestions = insertText(file, 9, 15);
diff --git a/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCase.java b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCase.java
index 1a5788f..d8afd69 100644
--- a/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCase.java
+++ b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCase.java
@@ -2,13 +2,15 @@ package org.javacs.example;
class AutocompleteCase {
void test() {
- var e = MyEnum.Foo;
-
- switch (e) {
+ switch (myEnum()) {
case
}
}
+ MyEnum myEnum() {
+ return MyEnum.Foo;
+ }
+
enum MyEnum {
Foo,
Bar
diff --git a/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCaseFromClasspath.java b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCaseFromClasspath.java
new file mode 100644
index 0000000..6a893ae
--- /dev/null
+++ b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteCaseFromClasspath.java
@@ -0,0 +1,15 @@
+package org.javacs.example;
+
+import java.time.format.FormatStyle;
+
+class AutocompleteCaseFromClasspath {
+ public void main() {
+ switch (style()) {
+ case
+ }
+ }
+
+ private FormatStyle style() {
+ return FormatStyle.FULL;
+ }
+} \ No newline at end of file