summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Fraser <george@fivetran.com>2018-12-30 21:56:10 -0800
committerGeorge Fraser <george@fivetran.com>2018-12-30 21:56:10 -0800
commitbab1f5a754c72d6b10c6c43af2a17d25bd93cdef (patch)
tree8c0e4619a010b4d978cbe0420c20367cbdb8dda9 /src
parentf903f5dec011e52189664d75012e9ca47318cd62 (diff)
downloadjava-language-server-bab1f5a754c72d6b10c6c43af2a17d25bd93cdef.zip
Source path classes in the same dir are accessible
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/javacs/CompileFocus.java61
-rw-r--r--src/main/java/org/javacs/JavaCompilerService.java15
-rw-r--r--src/test/java/org/javacs/CompletionsBase.java4
-rw-r--r--src/test/java/org/javacs/CompletionsTest.java27
-rw-r--r--src/test/java/org/javacs/DocsTest.java4
-rw-r--r--src/test/java/org/javacs/FindResource.java12
-rw-r--r--src/test/java/org/javacs/JavaCompilerServiceTest.java29
-rw-r--r--src/test/java/org/javacs/LanguageServerFixture.java2
-rw-r--r--src/test/java/org/javacs/ParserFixImportsTest.java2
-rw-r--r--src/test/test-project/simple/BuildUpScope.java (renamed from src/test/resources/BuildUpScope.java)0
-rw-r--r--src/test/test-project/simple/ClassDoc.java (renamed from src/test/resources/ClassDoc.java)0
-rw-r--r--src/test/test-project/simple/CompleteClass.java (renamed from src/test/resources/CompleteClass.java)0
-rw-r--r--src/test/test-project/simple/CompleteExpression.java (renamed from src/test/resources/CompleteExpression.java)0
-rw-r--r--src/test/test-project/simple/CompleteIdentifiers.java (renamed from src/test/resources/CompleteIdentifiers.java)0
-rw-r--r--src/test/test-project/simple/CompleteImports.java (renamed from src/test/resources/CompleteImports.java)0
-rw-r--r--src/test/test-project/simple/CompleteInMiddle.java (renamed from src/test/resources/CompleteInMiddle.java)0
-rw-r--r--src/test/test-project/simple/CompleteMembers.java (renamed from src/test/resources/CompleteMembers.java)0
-rw-r--r--src/test/test-project/simple/GotoDefinition.java (renamed from src/test/resources/GotoDefinition.java)0
-rw-r--r--src/test/test-project/simple/HasError.java (renamed from src/test/resources/HasError.java)0
-rw-r--r--src/test/test-project/simple/HasImport.java (renamed from src/test/resources/HasImport.java)0
-rw-r--r--src/test/test-project/simple/HelloWorld.java (renamed from src/test/resources/HelloWorld.java)0
-rw-r--r--src/test/test-project/simple/LocalMethodDoc.java (renamed from src/test/resources/LocalMethodDoc.java)0
-rw-r--r--src/test/test-project/simple/MissingImport.java (renamed from src/test/resources/MissingImport.java)0
-rw-r--r--src/test/test-project/simple/Overloads.java (renamed from src/test/resources/Overloads.java)0
-rw-r--r--src/test/test-project/simple/PruneDot.java (renamed from src/test/resources/PruneDot.java)0
-rw-r--r--src/test/test-project/simple/PruneDot_erased.java (renamed from src/test/resources/PruneDot_erased.java)0
-rw-r--r--src/test/test-project/simple/PruneMethods.java (renamed from src/test/resources/PruneMethods.java)0
-rw-r--r--src/test/test-project/simple/PruneMethods_erased.java (renamed from src/test/resources/PruneMethods_erased.java)0
-rw-r--r--src/test/test-project/simple/PruneMiddle.java (renamed from src/test/resources/PruneMiddle.java)0
-rw-r--r--src/test/test-project/simple/PruneMiddle_erased.java (renamed from src/test/resources/PruneMiddle_erased.java)0
-rw-r--r--src/test/test-project/simple/PruneToEndOfBlock.java (renamed from src/test/resources/PruneToEndOfBlock.java)0
-rw-r--r--src/test/test-project/simple/PruneToEndOfBlock_erased.java (renamed from src/test/resources/PruneToEndOfBlock_erased.java)0
-rw-r--r--src/test/test-project/workspace/src/org/javacs/example/AutocompleteNewFile.java7
33 files changed, 113 insertions, 50 deletions
diff --git a/src/main/java/org/javacs/CompileFocus.java b/src/main/java/org/javacs/CompileFocus.java
index 8acfa42..4cf3308 100644
--- a/src/main/java/org/javacs/CompileFocus.java
+++ b/src/main/java/org/javacs/CompileFocus.java
@@ -13,7 +13,6 @@ import java.util.function.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
-import java.util.stream.Stream;
import javax.lang.model.element.*;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
@@ -707,40 +706,40 @@ public class CompileFocus {
// Check sourcepath
LOG.info("...checking source path");
- Predicate<Path> matchesFileName = file -> matchesPartialName(file.getFileName().toString(), partialName);
- Predicate<Path> isPublic =
- file -> {
- var fileName = file.getFileName().toString();
- if (!fileName.endsWith(".java")) return true;
- var simpleName = fileName.substring(0, fileName.length() - ".java".length());
- Stream<String> lines;
- try {
- lines = Files.lines(file);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return lines.anyMatch(line -> line.matches(".*public\\s+class\\s+" + simpleName + ".*"));
- };
- for (var dir : parent.sourcePath) {
- Function<Path, String> qualifiedName =
- file -> {
- var relative = dir.relativize(file).toString().replace('/', '.');
- if (!relative.endsWith(".java")) return "??? " + relative + " does not end in .java";
- return relative.substring(0, relative.length() - ".java".length());
- };
- for (var file : JavaCompilerService.javaSourcesInDir(dir)) {
- if (tooManyItems(result.size())) return;
- // Fast check, file name only
- if (matchesFileName.test(file)) {
- var c = qualifiedName.apply(file);
- // Slow check, open file
- if (matchesPartialName.test(c) && isPublic.test(file)) {
- result.add(Completion.ofClassName(c, isImported(c)));
- }
+ for (var file : parent.allJavaFiles.get()) {
+ if (tooManyItems(result.size())) return;
+ // If file is in the same package, any class defined in the file is accessible
+ var pathBasedPackageName = parent.pathBasedPackageName(file);
+ var samePackage = pathBasedPackageName.equals(packageName) || pathBasedPackageName.isEmpty();
+ // If file is in a different package, only a public class with the same name as the file is accessible
+ var maybePublic = matchesPartialName(file.getFileName().toString(), partialName);
+ if (samePackage || maybePublic) {
+ result.addAll(accessibleClasses(file, partialName, packageName));
+ }
+ }
+ }
+ }
+
+ private List<Completion> accessibleClasses(Path file, String partialName, String fromPackage) {
+ var parse = Parser.parse(file);
+ var toPackage = Objects.toString(parse.getPackageName(), "");
+ var samePackage = fromPackage.equals(toPackage) || toPackage.isEmpty();
+ var result = new ArrayList<Completion>();
+ for (var t : parse.getTypeDecls()) {
+ if (!(t instanceof ClassTree)) continue;
+ var cls = (ClassTree) t;
+ var isPublic = cls.getModifiers().getFlags().contains(Modifier.PUBLIC);
+ if (isPublic || samePackage) {
+ var name = cls.getSimpleName().toString();
+ if (matchesPartialName(name, partialName)) {
+ if (parse.getPackageName() != null) {
+ name = parse.getPackageName() + "." + name;
}
+ result.add(Completion.ofClassName(name, isImported(name)));
}
}
}
+ return result;
}
private List<Element> staticImports(URI file, String contents, String partialName) {
diff --git a/src/main/java/org/javacs/JavaCompilerService.java b/src/main/java/org/javacs/JavaCompilerService.java
index ddcb82f..3dce659 100644
--- a/src/main/java/org/javacs/JavaCompilerService.java
+++ b/src/main/java/org/javacs/JavaCompilerService.java
@@ -89,6 +89,21 @@ public class JavaCompilerService {
return list;
}
+ String pathBasedPackageName(Path javaFile) {
+ if (!javaFile.getFileName().toString().endsWith(".java")) {
+ LOG.warning(javaFile + " does not end in .java");
+ return "???";
+ }
+ for (var dir : sourcePath) {
+ if (!javaFile.startsWith(dir)) continue;
+ var packageDir = javaFile.getParent();
+ var relative = dir.relativize(packageDir);
+ return relative.toString().replace('/', '.');
+ }
+ LOG.warning(javaFile + " is not in the source path " + sourcePath);
+ return "???";
+ }
+
private Collection<Path> removeModuleInfo(Collection<Path> files) {
var result = new ArrayList<Path>();
for (var f : files) {
diff --git a/src/test/java/org/javacs/CompletionsBase.java b/src/test/java/org/javacs/CompletionsBase.java
index 30af123..1a6b161 100644
--- a/src/test/java/org/javacs/CompletionsBase.java
+++ b/src/test/java/org/javacs/CompletionsBase.java
@@ -10,6 +10,8 @@ import org.javacs.lsp.*;
public class CompletionsBase {
protected static final Logger LOG = Logger.getLogger("main");
+ protected static final JavaLanguageServer server = LanguageServerFixture.getJavaLanguageServer();
+
protected Set<String> insertTemplate(String file, int row, int column) {
var items = items(file, row, column);
@@ -81,8 +83,6 @@ public class CompletionsBase {
.collect(Collectors.toSet());
}
- protected static final JavaLanguageServer server = LanguageServerFixture.getJavaLanguageServer();
-
protected List<? extends CompletionItem> items(String file, int row, int column) {
var uri = FindResource.uri(file);
var position =
diff --git a/src/test/java/org/javacs/CompletionsTest.java b/src/test/java/org/javacs/CompletionsTest.java
index b09ae92..37e46f4 100644
--- a/src/test/java/org/javacs/CompletionsTest.java
+++ b/src/test/java/org/javacs/CompletionsTest.java
@@ -3,6 +3,10 @@ package org.javacs;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
import java.util.stream.Collectors;
import org.javacs.lsp.*;
import org.junit.Ignore;
@@ -796,4 +800,27 @@ public class CompletionsTest extends CompletionsBase {
assertThat(suggestions, hasItem(containsString("util")));
}
+
+ @Test
+ public void newlyCreatedClass() throws IOException {
+ var file = FindResource.path("/org/javacs/example/NewlyCreatedFile.java");
+ try {
+ // Create a file that didn't exist when we created the server
+ try (var writer = Files.newBufferedWriter(file, StandardOpenOption.CREATE_NEW)) {
+ writer.write("package org.javacs.example;\nclass NewlyCreatedFile { }");
+ }
+ // Send a 'file created' notification
+ var created = new FileEvent();
+ created.uri = file.toUri();
+ created.type = FileChangeType.Created;
+ var changes = new DidChangeWatchedFilesParams();
+ changes.changes = List.of(created);
+ server.didChangeWatchedFiles(changes);
+ // Autocomplete `New`
+ var suggestions = insertText("/org/javacs/example/AutocompleteNewFile.java", 5, 12);
+ assertThat(suggestions, hasItem(containsString("NewlyCreatedFile")));
+ } finally {
+ Files.delete(file);
+ }
+ }
}
diff --git a/src/test/java/org/javacs/DocsTest.java b/src/test/java/org/javacs/DocsTest.java
index 583dea0..dd89e46 100644
--- a/src/test/java/org/javacs/DocsTest.java
+++ b/src/test/java/org/javacs/DocsTest.java
@@ -9,7 +9,7 @@ import org.junit.Test;
public class DocsTest {
@Test
public void classDoc() {
- var sourcePath = Set.of(JavaCompilerServiceTest.resourcesDir());
+ var sourcePath = Set.of(JavaCompilerServiceTest.simpleProjectSrc());
var docs = new Docs(sourcePath);
var tree = docs.classDoc("ClassDoc");
assertTrue(tree.isPresent());
@@ -18,7 +18,7 @@ public class DocsTest {
@Test
public void memberDoc() {
- var sourcePath = Set.of(JavaCompilerServiceTest.resourcesDir());
+ var sourcePath = Set.of(JavaCompilerServiceTest.simpleProjectSrc());
var docs = new Docs(sourcePath);
var tree = docs.memberDoc("LocalMethodDoc", "targetMethod");
assertTrue(tree.isPresent());
diff --git a/src/test/java/org/javacs/FindResource.java b/src/test/java/org/javacs/FindResource.java
index 897f85b..ce07a04 100644
--- a/src/test/java/org/javacs/FindResource.java
+++ b/src/test/java/org/javacs/FindResource.java
@@ -1,18 +1,20 @@
package org.javacs;
import java.net.URI;
+import java.nio.file.Path;
import java.nio.file.Paths;
/** Find java sources in test-project/workspace/src */
public class FindResource {
public static URI uri(String resourcePath) {
- if (resourcePath.startsWith("/")) resourcePath = resourcePath.substring(1);
+ var path = path(resourcePath);
- var path = Paths.get("./src/test/test-project/workspace/src").resolve(resourcePath).normalize();
- var file = path.toAbsolutePath().toFile();
+ return path.toUri();
+ }
- if (!file.exists()) throw new RuntimeException(file + " does not exist");
+ public static Path path(String resourcePath) {
+ if (resourcePath.startsWith("/")) resourcePath = resourcePath.substring(1);
- return URI.create("file://" + file);
+ return Paths.get("./src/test/test-project/workspace/src").resolve(resourcePath).normalize();
}
}
diff --git a/src/test/java/org/javacs/JavaCompilerServiceTest.java b/src/test/java/org/javacs/JavaCompilerServiceTest.java
index c211014..8c67cdf 100644
--- a/src/test/java/org/javacs/JavaCompilerServiceTest.java
+++ b/src/test/java/org/javacs/JavaCompilerServiceTest.java
@@ -30,22 +30,22 @@ public class JavaCompilerServiceTest {
private JavaCompilerService compiler =
new JavaCompilerService(
- Collections.singleton(resourcesDir()),
+ Collections.singleton(simpleProjectSrc()),
JavaCompilerServiceTest::allJavaFiles,
Collections.emptySet(),
Collections.emptySet());
- static Path resourcesDir() {
- try {
- return Paths.get(JavaCompilerServiceTest.class.getResource("/HelloWorld.java").toURI()).getParent();
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
+ static Path mavenProjectSrc() {
+ return Paths.get("src/test/test-project/workspace/src").normalize();
+ }
+
+ static Path simpleProjectSrc() {
+ return Paths.get("src/test/test-project/simple").normalize();
}
static Set<Path> allJavaFiles() {
try {
- return Files.walk(resourcesDir())
+ return Files.walk(simpleProjectSrc())
.filter(f -> f.getFileName().toString().endsWith(".java"))
.collect(Collectors.toSet());
} catch (IOException e) {
@@ -319,4 +319,17 @@ public class JavaCompilerServiceTest {
assertTrue(CompileFocus.matchesPartialName("foobar", "foo"));
assertFalse(CompileFocus.matchesPartialName("foo", "foobar"));
}
+
+ @Test
+ public void packageName() {
+ var compiler =
+ new JavaCompilerService(
+ Collections.singleton(mavenProjectSrc()),
+ JavaCompilerServiceTest::allJavaFiles,
+ Collections.emptySet(),
+ Collections.emptySet());
+ assertThat(
+ compiler.pathBasedPackageName(FindResource.path("/org/javacs/example/Goto.java")),
+ equalTo("org.javacs.example"));
+ }
}
diff --git a/src/test/java/org/javacs/LanguageServerFixture.java b/src/test/java/org/javacs/LanguageServerFixture.java
index 2c93283..f2da3b7 100644
--- a/src/test/java/org/javacs/LanguageServerFixture.java
+++ b/src/test/java/org/javacs/LanguageServerFixture.java
@@ -9,7 +9,7 @@ import org.javacs.lsp.*;
class LanguageServerFixture {
- public static Path DEFAULT_WORKSPACE_ROOT = Paths.get("src/test/test-project/workspace").toAbsolutePath();
+ public static Path DEFAULT_WORKSPACE_ROOT = Paths.get("src/test/test-project/workspace").normalize();
static {
Main.setRootFormat();
diff --git a/src/test/java/org/javacs/ParserFixImportsTest.java b/src/test/java/org/javacs/ParserFixImportsTest.java
index e935962..8eb1fcb 100644
--- a/src/test/java/org/javacs/ParserFixImportsTest.java
+++ b/src/test/java/org/javacs/ParserFixImportsTest.java
@@ -12,7 +12,7 @@ public class ParserFixImportsTest {
@Test
public void findExistingImports() throws IOException {
var allJavaFiles =
- Files.walk(JavaCompilerServiceTest.resourcesDir())
+ Files.walk(JavaCompilerServiceTest.simpleProjectSrc())
.filter(f -> f.getFileName().toString().endsWith(".java"))
.collect(Collectors.toSet());
assertThat(allJavaFiles, not(empty()));
diff --git a/src/test/resources/BuildUpScope.java b/src/test/test-project/simple/BuildUpScope.java
index 171d816..171d816 100644
--- a/src/test/resources/BuildUpScope.java
+++ b/src/test/test-project/simple/BuildUpScope.java
diff --git a/src/test/resources/ClassDoc.java b/src/test/test-project/simple/ClassDoc.java
index 9106496..9106496 100644
--- a/src/test/resources/ClassDoc.java
+++ b/src/test/test-project/simple/ClassDoc.java
diff --git a/src/test/resources/CompleteClass.java b/src/test/test-project/simple/CompleteClass.java
index 5f16fb8..5f16fb8 100644
--- a/src/test/resources/CompleteClass.java
+++ b/src/test/test-project/simple/CompleteClass.java
diff --git a/src/test/resources/CompleteExpression.java b/src/test/test-project/simple/CompleteExpression.java
index 9b9dd00..9b9dd00 100644
--- a/src/test/resources/CompleteExpression.java
+++ b/src/test/test-project/simple/CompleteExpression.java
diff --git a/src/test/resources/CompleteIdentifiers.java b/src/test/test-project/simple/CompleteIdentifiers.java
index 8ba5e39..8ba5e39 100644
--- a/src/test/resources/CompleteIdentifiers.java
+++ b/src/test/test-project/simple/CompleteIdentifiers.java
diff --git a/src/test/resources/CompleteImports.java b/src/test/test-project/simple/CompleteImports.java
index 1b0dc80..1b0dc80 100644
--- a/src/test/resources/CompleteImports.java
+++ b/src/test/test-project/simple/CompleteImports.java
diff --git a/src/test/resources/CompleteInMiddle.java b/src/test/test-project/simple/CompleteInMiddle.java
index 981e71e..981e71e 100644
--- a/src/test/resources/CompleteInMiddle.java
+++ b/src/test/test-project/simple/CompleteInMiddle.java
diff --git a/src/test/resources/CompleteMembers.java b/src/test/test-project/simple/CompleteMembers.java
index 168dc65..168dc65 100644
--- a/src/test/resources/CompleteMembers.java
+++ b/src/test/test-project/simple/CompleteMembers.java
diff --git a/src/test/resources/GotoDefinition.java b/src/test/test-project/simple/GotoDefinition.java
index 1f8866c..1f8866c 100644
--- a/src/test/resources/GotoDefinition.java
+++ b/src/test/test-project/simple/GotoDefinition.java
diff --git a/src/test/resources/HasError.java b/src/test/test-project/simple/HasError.java
index ad2fbe2..ad2fbe2 100644
--- a/src/test/resources/HasError.java
+++ b/src/test/test-project/simple/HasError.java
diff --git a/src/test/resources/HasImport.java b/src/test/test-project/simple/HasImport.java
index 2b4f66e..2b4f66e 100644
--- a/src/test/resources/HasImport.java
+++ b/src/test/test-project/simple/HasImport.java
diff --git a/src/test/resources/HelloWorld.java b/src/test/test-project/simple/HelloWorld.java
index b86724f..b86724f 100644
--- a/src/test/resources/HelloWorld.java
+++ b/src/test/test-project/simple/HelloWorld.java
diff --git a/src/test/resources/LocalMethodDoc.java b/src/test/test-project/simple/LocalMethodDoc.java
index a240753..a240753 100644
--- a/src/test/resources/LocalMethodDoc.java
+++ b/src/test/test-project/simple/LocalMethodDoc.java
diff --git a/src/test/resources/MissingImport.java b/src/test/test-project/simple/MissingImport.java
index 79f0d92..79f0d92 100644
--- a/src/test/resources/MissingImport.java
+++ b/src/test/test-project/simple/MissingImport.java
diff --git a/src/test/resources/Overloads.java b/src/test/test-project/simple/Overloads.java
index e686971..e686971 100644
--- a/src/test/resources/Overloads.java
+++ b/src/test/test-project/simple/Overloads.java
diff --git a/src/test/resources/PruneDot.java b/src/test/test-project/simple/PruneDot.java
index 2ea5e1d..2ea5e1d 100644
--- a/src/test/resources/PruneDot.java
+++ b/src/test/test-project/simple/PruneDot.java
diff --git a/src/test/resources/PruneDot_erased.java b/src/test/test-project/simple/PruneDot_erased.java
index 2ea5e1d..2ea5e1d 100644
--- a/src/test/resources/PruneDot_erased.java
+++ b/src/test/test-project/simple/PruneDot_erased.java
diff --git a/src/test/resources/PruneMethods.java b/src/test/test-project/simple/PruneMethods.java
index 474cee2..474cee2 100644
--- a/src/test/resources/PruneMethods.java
+++ b/src/test/test-project/simple/PruneMethods.java
diff --git a/src/test/resources/PruneMethods_erased.java b/src/test/test-project/simple/PruneMethods_erased.java
index e3d1a4b..e3d1a4b 100644
--- a/src/test/resources/PruneMethods_erased.java
+++ b/src/test/test-project/simple/PruneMethods_erased.java
diff --git a/src/test/resources/PruneMiddle.java b/src/test/test-project/simple/PruneMiddle.java
index 1916250..1916250 100644
--- a/src/test/resources/PruneMiddle.java
+++ b/src/test/test-project/simple/PruneMiddle.java
diff --git a/src/test/resources/PruneMiddle_erased.java b/src/test/test-project/simple/PruneMiddle_erased.java
index 5b208b3..5b208b3 100644
--- a/src/test/resources/PruneMiddle_erased.java
+++ b/src/test/test-project/simple/PruneMiddle_erased.java
diff --git a/src/test/resources/PruneToEndOfBlock.java b/src/test/test-project/simple/PruneToEndOfBlock.java
index 9174589..9174589 100644
--- a/src/test/resources/PruneToEndOfBlock.java
+++ b/src/test/test-project/simple/PruneToEndOfBlock.java
diff --git a/src/test/resources/PruneToEndOfBlock_erased.java b/src/test/test-project/simple/PruneToEndOfBlock_erased.java
index fafee1f..fafee1f 100644
--- a/src/test/resources/PruneToEndOfBlock_erased.java
+++ b/src/test/test-project/simple/PruneToEndOfBlock_erased.java
diff --git a/src/test/test-project/workspace/src/org/javacs/example/AutocompleteNewFile.java b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteNewFile.java
new file mode 100644
index 0000000..431f3cf
--- /dev/null
+++ b/src/test/test-project/workspace/src/org/javacs/example/AutocompleteNewFile.java
@@ -0,0 +1,7 @@
+package org.javacs.example;
+
+class AutocompleteNewFile {
+ void main() {
+ New
+ }
+} \ No newline at end of file