summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Fraser <george@fivetran.com>2018-12-23 12:34:11 -0800
committerGeorge Fraser <george@fivetran.com>2018-12-23 12:34:11 -0800
commitb6ad35a751145fb1e4b820d5ea11fc596a2d156d (patch)
tree75094281d7515548a990f4fd856b844bf8cb3d6c
parentd6aaf1e59cb3fd68ee72e9d2753b64f7af4ae426 (diff)
downloadjava-language-server-b6ad35a751145fb1e4b820d5ea11fc596a2d156d.zip
JavaCompilerService.referencesFile indexes all files that reference a file
-rw-r--r--TODOS.md8
-rw-r--r--src/main/java/org/javacs/Index.java16
-rw-r--r--src/main/java/org/javacs/JavaCompilerService.java241
-rw-r--r--src/main/java/org/javacs/QName.java10
-rw-r--r--src/main/java/org/javacs/Ref.java21
-rw-r--r--src/test/java/org/javacs/JavaCompilerServiceTest.java69
6 files changed, 299 insertions, 66 deletions
diff --git a/TODOS.md b/TODOS.md
index f61d475..dee6847 100644
--- a/TODOS.md
+++ b/TODOS.md
@@ -11,6 +11,8 @@
## Autocomplete
- Annotation fields
- cc should match CamelCase
+- Detail of fields, vars should be type
+- Autocomplete this.x = x; this.y = y; ... in constructor
## Navigation
- Go-to-subclasses
@@ -18,6 +20,8 @@
## Polish
- Convert {@tag ...} to `<tag>...</tag>` (see vscode-java)
- Auto-collapse imports
+- Hover constructor should show constructor, not class
+- String.format(...) coloring
## Simplicity
- Use module-info.java instead of build files to figure out classpath
@@ -25,3 +29,7 @@
## JShell
- Support .jshell extension as "scratch pad"
+
+# Coloring
+- new Foo< shouldn't make everything gree
+- void f() shouldn't mess up next line as you type it
diff --git a/src/main/java/org/javacs/Index.java b/src/main/java/org/javacs/Index.java
new file mode 100644
index 0000000..e910ed4
--- /dev/null
+++ b/src/main/java/org/javacs/Index.java
@@ -0,0 +1,16 @@
+package org.javacs;
+
+import java.time.Instant;
+import java.util.List;
+
+public class Index {
+ public static final Index EMPTY = new Index(List.of(), Instant.EPOCH);
+
+ public final List<Ref> refs;
+ public final Instant created;
+
+ public Index(List<Ref> refs, Instant created) {
+ this.refs = refs;
+ this.created = created;
+ }
+}
diff --git a/src/main/java/org/javacs/JavaCompilerService.java b/src/main/java/org/javacs/JavaCompilerService.java
index 5ae5d80..894df17 100644
--- a/src/main/java/org/javacs/JavaCompilerService.java
+++ b/src/main/java/org/javacs/JavaCompilerService.java
@@ -9,6 +9,7 @@ import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.*;
+import java.nio.file.attribute.FileTime;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
@@ -1276,7 +1277,7 @@ public class JavaCompilerService {
var importStatic = Pattern.compile("^import +static +" + toPackage + "\\.");
var startOfClass = Pattern.compile("class +\\w+");
var word = Pattern.compile("\\b" + name + "\\b");
- var foundImport = toPackage.isEmpty();
+ var foundImport = toPackage.isEmpty(); // If package is empty, everyone imports it
var foundWord = false;
try (var read = Files.newBufferedReader(file)) {
while (true) {
@@ -1296,27 +1297,102 @@ public class JavaCompilerService {
return foundImport && foundWord;
}
- private List<Path> potentialReferences(String toPackage, String toClass, Element toEl, ReportReferencesProgress progress) {
- // Enumerate all files on source path
+ private boolean importsAnyClass(String toPackage, List<String> toClasses, Path file) {
+ if (toPackage.isEmpty()) return true; // If package is empty, everyone imports it
+ var toClass = toClasses.stream().collect(Collectors.joining("|"));
+ var samePackage = Pattern.compile("^package +" + toPackage + ";");
+ var importClass = Pattern.compile("^import +" + toPackage + "\\.(" + toClass + ");");
+ var importStar = Pattern.compile("^import +" + toPackage + "\\.\\*;");
+ var importStatic = Pattern.compile("^import +static +" + toPackage + "\\.");
+ var startOfClass = Pattern.compile("class +\\w+");
+ try (var read = Files.newBufferedReader(file)) {
+ while (true) {
+ var line = read.readLine();
+ if (line == null) break;
+ if (startOfClass.matcher(line).find()) break;
+ if (samePackage.matcher(line).find()) return true;
+ if (importClass.matcher(line).find()) return true;
+ if (importStar.matcher(line).find()) return true;
+ if (importStatic.matcher(line).find()) return true;
+ if (importClass.matcher(line).find()) return true;
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ 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;
+ }
+
+ private List<Path> potentialReferences(String toPackage, String toClass, Element toEl, ReportReferencesProgress progress) {
+ // Enumerate all files on source path
+ var allFiles = allJavaSources();
progress.scanForPotentialReferences(0, allFiles.size());
// Filter for files that import toPackage.toClass and contain the word el
+ // TODO should probably cache this
var name = toEl.getSimpleName().toString();
var result = new ArrayList<Path>();
int nScanned = 0;
for (var file : allFiles) {
- if (containsWord(toPackage, toClass, name, file))
+ if (toPackage.isEmpty() || containsWord(toPackage, toClass, name, file))
result.add(file);
progress.scanForPotentialReferences(++nScanned, allFiles.size());
}
return result;
}
+ private List<Path> potentialReferencesToClasses(String toPackage, List<String> toClasses, ReportReferencesProgress progress) {
+ // Enumerate all files on source path
+ var allFiles = allJavaSources();
+ progress.scanForPotentialReferences(0, allFiles.size());
+ // Filter for files that import toPackage.toClass
+ // TODO should probably cache this
+ var result = new ArrayList<Path>();
+ int nScanned = 0;
+ for (var dir : sourcePath) {
+ for (var file : javaSourcesInDir(dir)) {
+ if (importsAnyClass(toPackage, toClasses, file))
+ result.add(file);
+ progress.scanForPotentialReferences(++nScanned, allFiles.size());
+ }
+ }
+ return result;
+ }
+
+ private static String id(TreePath path) {
+ var parts = new ArrayList<String>();
+ while (path != null) {
+ var part = path.getLeaf();
+ if (part instanceof PackageTree) {
+ var pkg = (PackageTree) part;
+ var name = Objects.toString(pkg.getPackageName(), "");
+ parts.add(name);
+ } else if (part instanceof ClassTree) {
+ var cls = (ClassTree) part;
+ var name = Objects.toString(cls.getSimpleName(), "");
+ parts.add(name);
+ } else if (part instanceof MethodTree) {
+ var method = (MethodTree) part;
+ var name = Objects.toString(method.getName(), "");
+ parts.add(name);
+ } else if (part instanceof VariableTree) {
+ var variable = (VariableTree) part;
+ var name = Objects.toString(variable.getName(), "");
+ parts.add(name);
+ }
+ path = path.getParentPath();
+ }
+ return parts.stream().collect(Collectors.joining("."));
+ }
+
/**
* Represents a batch compilation of many files. The batch context is different that the incremental context, so
* methods in this class should not access `cache`.
@@ -1330,23 +1406,22 @@ public class JavaCompilerService {
this.roots = roots;
}
- private boolean toStringEquals(Object left, Object right) {
+ boolean toStringEquals(Object left, Object right) {
return Objects.equals(Objects.toString(left, ""), Objects.toString(right, ""));
}
- private boolean sameSymbol(Element target, Element symbol) {
- return symbol != null
- && target != null
- && toStringEquals(symbol.getEnclosingElement(), target.getEnclosingElement())
- && toStringEquals(symbol, target);
+ boolean sameSymbol(Element from, Element to) {
+ return to != null
+ && from != null
+ && toStringEquals(to.getEnclosingElement(), from.getEnclosingElement())
+ && toStringEquals(to, from);
}
- private List<TreePath> actualReferences(CompilationUnitTree from, Element to) {
+ List<TreePath> referencesToElement(CompilationUnitTree from, Element to) {
var trees = Trees.instance(task);
-
- class Finder extends TreeScanner<Void, Void> {
- List<TreePath> results = new ArrayList<>();
-
+ var results = new ArrayList<TreePath>();
+ class FindReferencesElement extends TreeScanner<Void, Void> {
+ // TODO this scans a LOT, can this be more specific?
@Override
public Void scan(Tree leaf, Void nothing) {
if (leaf != null) {
@@ -1358,13 +1433,52 @@ public class JavaCompilerService {
}
return null;
}
+ }
+ from.accept(new FindReferencesElement(), null);
+ return results;
+ }
- List<TreePath> run() {
- scan(from, null);
- return results;
+ List<Ref> index(CompilationUnitTree root) {
+ var trees = Trees.instance(task);
+ var pos = trees.getSourcePositions();
+ var lines = root.getLineMap();
+ var refs = new ArrayList<Ref>();
+ class IndexFile extends TreePathScanner<Void, Void> {
+ private void accept(TreePath from) {
+ var to = trees.getElement(from);
+ // TODO skip this for anything not on the source path
+ if (to != null) {
+ if (to.getSimpleName().contentEquals("<init>")) return;
+ long start = pos.getStartPosition(root, from.getLeaf()), end = pos.getEndPosition(root, from.getLeaf());
+ if (start == -1 || end == -1) {
+ LOG.warning(String.format("Position of %s in %s is %d:%d", from.getLeaf(), root.getSourceFile(), start, end));
+ return;
+ }
+ int startLine = (int) lines.getLineNumber(start) - 1, startCol = (int) lines.getColumnNumber(start) - 1;
+ int endLine = (int) lines.getLineNumber(end) - 1, endCol = (int) lines.getColumnNumber(end) - 1;
+ var toPath = trees.getPath(to);
+ var toId = id(toPath);
+ if (toId.isEmpty()) return; // TODO log a warning if we can't get an ID for something on the source path
+ var fromFile = root.getSourceFile().toUri();
+ var toFile = toPath.getCompilationUnit().getSourceFile().toUri();
+ var ref = new Ref(fromFile, startLine, startCol, endLine, endCol, toFile, toId);
+ refs.add(ref);
+ }
+ }
+
+ @Override
+ public Void visitClass(ClassTree node, Void nothing) {
+ super.visitClass(node, nothing);
+ accept(getCurrentPath());
+ for (var t : node.getMembers()) {
+ var child = new TreePath(getCurrentPath(), t);
+ accept(child);
+ }
+ return null;
}
}
- return new Finder().run();
+ new IndexFile().scan(root, null);
+ return refs;
}
}
@@ -1384,18 +1498,31 @@ public class JavaCompilerService {
return new Batch(task, result);
}
- private QName className(TreePath path) {
- var packageName = Objects.toString(path.getCompilationUnit().getPackageName(), "");
+ private String className(TreePath path) {
while (path != null) {
var leaf = path.getLeaf();
if (leaf instanceof ClassTree) {
var classTree = (ClassTree) leaf;
var className = Objects.toString(classTree.getSimpleName(), "");
- return new QName(packageName, className);
+ return className;
}
path = path.getParentPath();
}
- return new QName(packageName, "");
+ return "";
+ }
+
+ private List<String> allClassNames(CompilationUnitTree root) {
+ var result = new ArrayList<String>();
+ class FindClasses extends TreeScanner<Void, Void> {
+ @Override
+ public Void visitClass(ClassTree classTree, Void __) {
+ var className = Objects.toString(classTree.getSimpleName(), "");
+ result.add(className);
+ return null;
+ }
+ }
+ root.accept(new FindClasses(), null);
+ return result;
}
public List<TreePath> references(URI file, String contents, int line, int character, ReportReferencesProgress progress) {
@@ -1407,8 +1534,9 @@ public class JavaCompilerService {
// `to` is part of a different batch than `batch = compileBatch(possible)`,
// so `to.equals(...thing from batch...)` shouldn't work
var toEl = trees.getElement(path);
+ var toPackage = Objects.toString(path.getCompilationUnit().getPackageName(), "");
var toClass = className(path);
- var possible = potentialReferences(toClass.packageName, toClass.className, toEl, progress);
+ var possible = potentialReferences(toPackage, toClass, toEl, progress);
if (possible.isEmpty()) {
LOG.info("No potential references to " + toEl);
return List.of();
@@ -1417,12 +1545,69 @@ public class JavaCompilerService {
// TODO optimize by pruning method bodies that don't contain potential references
var batch = compileBatch(possible);
var result = new ArrayList<TreePath>();
- int nChecked = 0;
+ var nChecked = 0;
+ for (var f : batch.roots) {
+ result.addAll(batch.referencesToElement(f, toEl));
+ nChecked++;
+ progress.checkPotentialReferences(nChecked, possible.size());
+ }
+ return result;
+ }
+
+ private Map<Path, Index> index = new HashMap<>();
+
+ public List<Ref> referencesFile(URI file, String contents, ReportReferencesProgress progress) {
+ recompile(file, contents, -1, -1);
+ // List all files that import file
+ var toPackage = Objects.toString(cache.root.getPackageName(), "");
+ var toClasses = allClassNames(cache.root);
+ var possible = potentialReferencesToClasses(toPackage, toClasses, progress);
+ if (possible.isEmpty()) {
+ LOG.info("No potential references to " + file);
+ return List.of();
+ }
+ // Reindex only files that are out-of-date
+ var outOfDate = new ArrayList<Path>();
+ for (var p : possible) {
+ var i = index.getOrDefault(p, Index.EMPTY);
+ FileTime modified;
+ try {
+ modified = Files.getLastModifiedTime(p);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ if (modified.toInstant().isAfter(i.created)) {
+ outOfDate.add(p);
+ }
+ }
+ progress.checkPotentialReferences(0, outOfDate.size());
+ // Reindex
+ var batch = compileBatch(outOfDate);
+ var nChecked = 0;
for (var f : batch.roots) {
- result.addAll(batch.actualReferences(f, toEl));
+ var uri = f.getSourceFile().toUri();
+ var path = Paths.get(uri);
+ var refs = batch.index(f);
+ FileTime modified;
+ try {
+ modified = Files.getLastModifiedTime(path);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ var i = new Index(refs, modified.toInstant());
+ index.put(path, i);
nChecked++;
progress.checkPotentialReferences(nChecked, possible.size());
}
+ // Assemble results
+ var result = new ArrayList<Ref>();
+ for (var p : possible) {
+ var i = index.get(p);
+ for (var r : i.refs) {
+ if (r.toFile.equals(file))
+ result.add(r);
+ }
+ }
return result;
}
@@ -1459,10 +1644,10 @@ public class JavaCompilerService {
if (id.matches("[A-Z]\\w+")) {
unresolved.add(id);
} else LOG.warning(id + " doesn't look like a class");
- } else if (d.getMessage(null).contains("cannot find symbol")) {
+ } else if (d.getMessage(null).contains("cannot find to")) {
var lines = d.getMessage(null).split("\n");
var firstLine = lines.length > 0 ? lines[0] : "";
- LOG.warning(String.format("%s %s doesn't look like symbol-not-found", d.getCode(), firstLine));
+ LOG.warning(String.format("%s %s doesn't look like to-not-found", d.getCode(), firstLine));
}
}
// Look at imports in other classes to help us guess how to fix imports
diff --git a/src/main/java/org/javacs/QName.java b/src/main/java/org/javacs/QName.java
deleted file mode 100644
index ca93beb..0000000
--- a/src/main/java/org/javacs/QName.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.javacs;
-
-class QName {
- final String packageName, className;
-
- QName(String packageName, String className) {
- this.packageName = packageName;
- this.className = className;
- }
-}
diff --git a/src/main/java/org/javacs/Ref.java b/src/main/java/org/javacs/Ref.java
new file mode 100644
index 0000000..b602f63
--- /dev/null
+++ b/src/main/java/org/javacs/Ref.java
@@ -0,0 +1,21 @@
+package org.javacs;
+
+import java.net.URI;
+
+/** Reference from file:line(start,end) to a class or method */
+public class Ref {
+ public final URI fromFile;
+ public final int startLine, startCol, endLine, endCol;
+ public final URI toFile;
+ public final String toEl;
+
+ public Ref(URI fromFile, int startLine, int startCol, int endLine, int endCol, URI toFile, String toEl) {
+ this.fromFile = fromFile;
+ this.startLine = startLine;
+ this.startCol = startCol;
+ this.endLine = endLine;
+ this.endCol = endCol;
+ this.toFile = toFile;
+ this.toEl = toEl;
+ }
+}
diff --git a/src/test/java/org/javacs/JavaCompilerServiceTest.java b/src/test/java/org/javacs/JavaCompilerServiceTest.java
index 0c04930..b5a7f9b 100644
--- a/src/test/java/org/javacs/JavaCompilerServiceTest.java
+++ b/src/test/java/org/javacs/JavaCompilerServiceTest.java
@@ -53,14 +53,14 @@ public class JavaCompilerServiceTest {
@Test
public void element() {
- var found = compiler.element(URI.create("/HelloWorld.java"), contents("/HelloWorld.java"), 3, 24);
+ var found = compiler.element(resourceUri("/HelloWorld.java"), contents("/HelloWorld.java"), 3, 24);
assertThat(found.getSimpleName(), hasToString(containsString("println")));
}
@Test
public void elementWithError() {
- var found = compiler.element(URI.create("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 12);
+ var found = compiler.element(resourceUri("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 12);
assertThat(found, notNullValue());
}
@@ -85,7 +85,7 @@ public class JavaCompilerServiceTest {
public void identifiers() {
var found =
compiler.scopeMembers(
- URI.create("/CompleteIdentifiers.java"),
+ resourceUri("/CompleteIdentifiers.java"),
contents("/CompleteIdentifiers.java"),
13,
21,
@@ -106,7 +106,7 @@ public class JavaCompilerServiceTest {
public void identifiersInMiddle() {
var found =
compiler.scopeMembers(
- URI.create("/CompleteInMiddle.java"), contents("/CompleteInMiddle.java"), 13, 21, "complete");
+ resourceUri("/CompleteInMiddle.java"), contents("/CompleteInMiddle.java"), 13, 21, "complete");
var names = elementNames(found);
assertThat(names, hasItem("completeLocal"));
assertThat(names, hasItem("completeParam"));
@@ -123,7 +123,7 @@ public class JavaCompilerServiceTest {
public void completeIdentifiers() {
var found =
compiler.completions(
- URI.create("/CompleteIdentifiers.java"), contents("/CompleteIdentifiers.java"), 13, 21)
+ resourceUri("/CompleteIdentifiers.java"), contents("/CompleteIdentifiers.java"), 13, 21)
.items;
var names = completionNames(found);
assertThat(names, hasItem("completeLocal"));
@@ -140,7 +140,7 @@ public class JavaCompilerServiceTest {
@Test
public void members() {
var found =
- compiler.members(URI.create("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 14, false);
+ compiler.members(resourceUri("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 14, false);
var names = completionNames(found);
assertThat(names, hasItem("subMethod"));
assertThat(names, hasItem("superMethod"));
@@ -150,7 +150,7 @@ public class JavaCompilerServiceTest {
@Test
public void completeMembers() {
var found =
- compiler.completions(URI.create("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 15)
+ compiler.completions(resourceUri("/CompleteMembers.java"), contents("/CompleteMembers.java"), 3, 15)
.items;
var names = completionNames(found);
assertThat(names, hasItem("subMethod"));
@@ -162,7 +162,7 @@ public class JavaCompilerServiceTest {
public void completeExpression() {
var found =
compiler.completions(
- URI.create("/CompleteExpression.java"), contents("/CompleteExpression.java"), 3, 37)
+ resourceUri("/CompleteExpression.java"), contents("/CompleteExpression.java"), 3, 37)
.items;
var names = completionNames(found);
assertThat(names, hasItem("instanceMethod"));
@@ -173,7 +173,7 @@ public class JavaCompilerServiceTest {
@Test
public void completeClass() {
var found =
- compiler.completions(URI.create("/CompleteClass.java"), contents("/CompleteClass.java"), 3, 23).items;
+ compiler.completions(resourceUri("/CompleteClass.java"), contents("/CompleteClass.java"), 3, 23).items;
var names = completionNames(found);
assertThat(names, hasItems("staticMethod", "staticField"));
assertThat(names, hasItems("class"));
@@ -184,7 +184,7 @@ public class JavaCompilerServiceTest {
@Test
public void completeImports() {
var found =
- compiler.completions(URI.create("/CompleteImports.java"), contents("/CompleteImports.java"), 1, 18)
+ compiler.completions(resourceUri("/CompleteImports.java"), contents("/CompleteImports.java"), 1, 18)
.items;
var names = completionNames(found);
assertThat(names, hasItem("List"));
@@ -195,7 +195,7 @@ public class JavaCompilerServiceTest {
@Test
public void gotoDefinition() {
var def =
- compiler.definition(URI.create("/GotoDefinition.java"), 3, 12, uri -> Files.readAllText(uri));
+ compiler.definition("/GotoDefinition.java";
assertTrue(def.isPresent());
var t = def.get();
@@ -211,36 +211,49 @@ public class JavaCompilerServiceTest {
}
*/
+ private final ReportReferencesProgress rrp =
+ new ReportReferencesProgress() {
+ @Override
+ public void scanForPotentialReferences(int nScanned, int nFiles) {}
+
+ @Override
+ public void checkPotentialReferences(int nCompiled, int nPotential) {}
+ };
+
@Test
public void references() {
- ReportReferencesProgress rrp =
- new ReportReferencesProgress() {
- @Override
- public void scanForPotentialReferences(int nScanned, int nFiles) {}
-
- @Override
- public void checkPotentialReferences(int nCompiled, int nPotential) {}
- };
- var refs =
- compiler.references(URI.create("/GotoDefinition.java"), contents("/GotoDefinition.java"), 6, 13, rrp);
- boolean found = false;
+ var file = "/GotoDefinition.java";
+ var refs = compiler.references(resourceUri(file), contents(file), 6, 13, rrp);
+ var stringify = new ArrayList<String>();
for (var t : refs) {
var unit = t.getCompilationUnit();
var name = unit.getSourceFile().getName();
var trees = compiler.trees();
var pos = trees.getSourcePositions();
var lines = unit.getLineMap();
- long start = pos.getStartPosition(unit, t.getLeaf());
- long line = lines.getLineNumber(start);
- if (name.endsWith("GotoDefinition.java") && line == 3) found = true;
+ var start = pos.getStartPosition(unit, t.getLeaf());
+ var line = lines.getLineNumber(start);
+ if (name.endsWith("GotoDefinition.java") && line == 3) return;
+ stringify.add(String.format("%s:%d", name, line));
}
+ fail(String.format("No GotoDefinition.java:3 in %s", stringify));
+ }
- if (!found) fail(String.format("No GotoDefinition.java line 3 in %s", refs));
+ @Test
+ public void referencesFile() {
+ var file = "/GotoDefinition.java";
+ var refs = compiler.referencesFile(resourceUri(file), contents(file), rrp);
+ var stringify = new ArrayList<String>();
+ for (var r : refs) {
+ if (r.fromFile.toString().endsWith("GotoDefinition.java")) return;
+ stringify.add(String.format("%s:%d", r.fromFile, r.startLine));
+ }
+ fail(String.format("No GotoDefinition.java in %s", stringify));
}
@Test
public void overloads() {
- var found = compiler.methodInvocation(URI.create("/Overloads.java"), contents("/Overloads.java"), 3, 15).get();
+ var found = compiler.methodInvocation(resourceUri("/Overloads.java"), contents("/Overloads.java"), 3, 15).get();
var strings = found.overloads.stream().map(Object::toString).collect(Collectors.toList());
assertThat(strings, hasItem(containsString("print(int)")));
@@ -257,7 +270,7 @@ public class JavaCompilerServiceTest {
@Test
public void localDoc() {
var method =
- compiler.methodInvocation(URI.create("/LocalMethodDoc.java"), contents("/LocalMethodDoc.java"), 3, 21)
+ compiler.methodInvocation(resourceUri("/LocalMethodDoc.java"), contents("/LocalMethodDoc.java"), 3, 21)
.get()
.activeMethod
.get();