diff options
author | George Fraser <george@fivetran.com> | 2019-01-08 00:10:18 -0800 |
---|---|---|
committer | George Fraser <george@fivetran.com> | 2019-01-08 00:10:18 -0800 |
commit | 46e72551e73f1de2417102fd3d7fbc358a42cfa6 (patch) | |
tree | c6bce16cec95ebd660657b4dd662cb3ec754a82a | |
parent | 297dd5f8fb1c72f5807595c3029acf40ce6afcd9 (diff) | |
download | java-language-server-46e72551e73f1de2417102fd3d7fbc358a42cfa6.zip |
Hide module-info.java
-rw-r--r-- | src/main/java/org/javacs/FileStore.java | 9 | ||||
-rw-r--r-- | src/main/java/org/javacs/Profiler.java | 27 | ||||
-rw-r--r-- | src/main/java/org/javacs/SourceFileManager.java | 19 | ||||
-rw-r--r-- | src/main/java/org/javacs/SourceFileObject.java | 1 | ||||
-rw-r--r-- | src/main/java/org/javacs/SourcePath.java | 6 | ||||
-rw-r--r-- | src/test/java/org/javacs/SourceFileManagerTest.java | 69 |
6 files changed, 103 insertions, 28 deletions
diff --git a/src/main/java/org/javacs/FileStore.java b/src/main/java/org/javacs/FileStore.java index 7c5e2ad..3c10a64 100644 --- a/src/main/java/org/javacs/FileStore.java +++ b/src/main/java/org/javacs/FileStore.java @@ -25,6 +25,8 @@ import org.javacs.lsp.DidCloseTextDocumentParams; import org.javacs.lsp.DidOpenTextDocumentParams; import org.javacs.lsp.TextDocumentContentChangeEvent; +// TODO get rid of SourcePath and track source path dynamically here + class FileStore { private static final Map<URI, VersionedContent> activeDocuments = new HashMap<>(); @@ -60,7 +62,9 @@ class FileStore { for (var file : afterDir) { if (!SourcePath.isJavaFile(file)) continue; if (!file.startsWith(dir)) break; - if (file.startsWith(packageDir)) list.add(file); + if (file.getParent().equals(packageDir)) { + list.add(file); + } } return list; } @@ -141,8 +145,7 @@ class FileStore { static String contents(URI file) { if (!SourcePath.isJavaFile(file)) { - LOG.warning("Ignoring non-java file " + file); - return ""; + throw new RuntimeException(file + " is not a java file"); } if (activeDocuments.containsKey(file)) { return activeDocuments.get(file).content; diff --git a/src/main/java/org/javacs/Profiler.java b/src/main/java/org/javacs/Profiler.java index b4fab4d..c7b6911 100644 --- a/src/main/java/org/javacs/Profiler.java +++ b/src/main/java/org/javacs/Profiler.java @@ -9,33 +9,38 @@ import java.util.logging.Logger; class Profiler implements TaskListener { Set<URI> files = new HashSet<>(); - Map<TaskEvent.Kind, Instant> started = new EnumMap<>(TaskEvent.Kind.class); + Map<URI, Map<TaskEvent.Kind, Instant>> started = new HashMap<>(); Map<TaskEvent.Kind, Duration> profile = new EnumMap<>(TaskEvent.Kind.class); @Override public void started(TaskEvent e) { - started.put(e.getKind(), Instant.now()); - files.add(e.getSourceFile().toUri()); + var uri = e.getSourceFile().toUri(); + var kind = e.getKind(); + var fileStarted = started.computeIfAbsent(uri, __ -> new EnumMap<>(TaskEvent.Kind.class)); + fileStarted.put(kind, Instant.now()); + files.add(uri); // TODO show the user a warning when we're compiling a lot of files that aren't in the classpath } @Override public void finished(TaskEvent e) { - var k = e.getKind(); - var start = started.getOrDefault(k, Instant.now()); + var uri = e.getSourceFile().toUri(); + var kind = e.getKind(); + var fileStarted = started.computeIfAbsent(uri, __ -> new HashMap<>()); + var start = fileStarted.getOrDefault(kind, Instant.now()); var elapsed = Duration.between(start, Instant.now()); - var soFar = profile.getOrDefault(k, Duration.ZERO); + var soFar = profile.getOrDefault(kind, Duration.ZERO); var total = soFar.plus(elapsed); - profile.put(k, total); + profile.put(kind, total); } void print() { var lines = new StringJoiner("; "); - for (var k : TaskEvent.Kind.values()) { - if (!profile.containsKey(k)) continue; - var elapsed = profile.get(k); + for (var kind : TaskEvent.Kind.values()) { + if (!profile.containsKey(kind)) continue; + var elapsed = profile.get(kind); var s = elapsed.getSeconds() + elapsed.getNano() / 1000.0 / 1000.0 / 1000.0; - lines.add(String.format("%s: %.3fs", k, s)); + lines.add(String.format("%s: %.3fs", kind, s)); } // TODO log names if n is small LOG.info(String.format("Compiled %d files: %s", files.size(), lines)); diff --git a/src/main/java/org/javacs/SourceFileManager.java b/src/main/java/org/javacs/SourceFileManager.java index e457b40..c174d2b 100644 --- a/src/main/java/org/javacs/SourceFileManager.java +++ b/src/main/java/org/javacs/SourceFileManager.java @@ -10,7 +10,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.logging.Logger; -import java.util.stream.Stream; import javax.tools.*; class SourceFileManager implements StandardJavaFileManager { @@ -67,16 +66,7 @@ class SourceFileManager implements StandardJavaFileManager { } private boolean isJavaSource(JavaFileObject file) { - return file.getName().endsWith(".java"); - } - - private Stream<Path> list(Path dir) { - try { - if (!Files.exists(dir)) return Stream.of(); - return Files.walk(dir).filter(Files::isRegularFile); - } catch (IOException e) { - throw new RuntimeException(e); - } + return SourcePath.isJavaFile(file.toUri()); } private JavaFileObject asJavaFileObject(Path file) { @@ -105,7 +95,7 @@ class SourceFileManager implements StandardJavaFileManager { private String binaryName(String relativePath) { var slash = removeExtension(relativePath); - return slash.replace('/', '.'); + return slash.replace(File.separatorChar, '.'); } private String removeExtension(String fileName) { @@ -153,6 +143,7 @@ class SourceFileManager implements StandardJavaFileManager { private JavaFileObject findFileForInput(Location location, String relative) { for (var root : sourcePath) { var absolute = root.resolve(relative); + if (!SourcePath.isJavaFile(absolute)) return null; if (Files.exists(absolute)) { return new SourceFileObject(absolute); } @@ -257,12 +248,12 @@ class SourceFileManager implements StandardJavaFileManager { @Override public void setLocation(Location location, Iterable<? extends File> files) throws IOException { - throw new UnsupportedOperationException(); + delegate.setLocation(location, files); } @Override public Iterable<? extends File> getLocation(Location location) { - throw new UnsupportedOperationException(); + return delegate.getLocation(location); } private static final Logger LOG = Logger.getLogger("main"); diff --git a/src/main/java/org/javacs/SourceFileObject.java b/src/main/java/org/javacs/SourceFileObject.java index 24e7608..46d652d 100644 --- a/src/main/java/org/javacs/SourceFileObject.java +++ b/src/main/java/org/javacs/SourceFileObject.java @@ -27,6 +27,7 @@ class SourceFileObject implements JavaFileObject { } SourceFileObject(Path path, String contents) { + if (!SourcePath.isJavaFile(path)) throw new RuntimeException(path + " is not a java source"); this.path = path; this.contents = contents; } diff --git a/src/main/java/org/javacs/SourcePath.java b/src/main/java/org/javacs/SourcePath.java index 60133bc..9c17252 100644 --- a/src/main/java/org/javacs/SourcePath.java +++ b/src/main/java/org/javacs/SourcePath.java @@ -96,6 +96,12 @@ class SourcePath { static boolean isJavaFile(Path file) { var name = file.getFileName().toString(); + // We hide module-info.java from javac, because when javac sees module-info.java + // it goes into "module mode" and starts looking for classes on the module class path. + // This becomes evident when javac starts recompiling *way too much* on each task, + // because it doesn't realize there are already up-to-date .class files. + // The better solution would be for java-language server to detect the presence of module-info.java, + // and go into its own "module mode" where it infers a module source path and a module class path. return name.endsWith(".java") && !name.equals("module-info.java"); } diff --git a/src/test/java/org/javacs/SourceFileManagerTest.java b/src/test/java/org/javacs/SourceFileManagerTest.java new file mode 100644 index 0000000..ab40c5e --- /dev/null +++ b/src/test/java/org/javacs/SourceFileManagerTest.java @@ -0,0 +1,69 @@ +package org.javacs; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.*; +import java.util.logging.Logger; +import javax.tools.*; +import org.junit.Test; + +public class SourceFileManagerTest { + static final Path src = LanguageServerFixture.DEFAULT_WORKSPACE_ROOT.resolve("src"); + static final Path classes = LanguageServerFixture.DEFAULT_WORKSPACE_ROOT.resolve("target/classes"); + final SourceFileManager sourceFileManager = createSourceFileManager(); + final StandardJavaFileManager standardFileManager = createDelegateFileManager(); + + private static SourceFileManager createSourceFileManager() { + var fileManager = new SourceFileManager(Set.of(src)); + try { + fileManager.setLocationFromPaths(StandardLocation.SOURCE_PATH, List.of(src)); + fileManager.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(classes)); + } catch (IOException e) { + throw new RuntimeException(e); + } + return fileManager; + } + + private static StandardJavaFileManager createDelegateFileManager() { + var compiler = ServiceLoader.load(JavaCompiler.class).iterator().next(); + var fileManager = + compiler.getStandardFileManager( + err -> LOG.severe(err.getMessage(null)), null, Charset.defaultCharset()); + try { + fileManager.setLocationFromPaths(StandardLocation.SOURCE_PATH, List.of(src)); + fileManager.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(classes)); + } catch (IOException e) { + throw new RuntimeException(e); + } + return fileManager; + } + + @Test + public void binaryNameOfPackagePrivateClass() throws IOException { + var standardJava = + standardFileManager.getJavaFileForInput( + StandardLocation.SOURCE_PATH, "com.example.PackagePrivate", JavaFileObject.Kind.SOURCE); + var standardClass = + standardFileManager.getJavaFileForInput( + StandardLocation.CLASS_PATH, "com.example.PackagePrivate", JavaFileObject.Kind.CLASS); + var sourceJava = + sourceFileManager.getJavaFileForInput( + StandardLocation.SOURCE_PATH, "com.example.PackagePrivate", JavaFileObject.Kind.SOURCE); + var sourceClass = + sourceFileManager.getJavaFileForInput( + StandardLocation.CLASS_PATH, "com.example.PackagePrivate", JavaFileObject.Kind.CLASS); + var standardJavaName = standardFileManager.inferBinaryName(StandardLocation.SOURCE_PATH, standardJava); + var standardClassName = standardFileManager.inferBinaryName(StandardLocation.CLASS_PATH, standardClass); + var sourceJavaName = sourceFileManager.inferBinaryName(StandardLocation.SOURCE_PATH, sourceJava); + var sourceClassName = sourceFileManager.inferBinaryName(StandardLocation.CLASS_PATH, sourceClass); + assertThat(standardClassName, equalTo(standardJavaName)); + assertThat(sourceJavaName, equalTo(standardJavaName)); + assertThat(sourceClassName, equalTo(standardJavaName)); + } + + private static final Logger LOG = Logger.getLogger("main"); +} |