diff --git a/.travis.yml b/.travis.yml index 54ee6a3..ff633d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ # Forked from https://github.com/pubref/rules_protobuf dist: trusty language: java +jdk: openjdk9 os: linux @@ -10,7 +11,7 @@ cache: - $HOME/bazel/outbase before_install: - - BAZEL_VERSION=0.10.0 + - BAZEL_VERSION=0.22.0 - OS=linux - ARCH=x86_64 - GH_BASE="https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION" @@ -28,7 +29,6 @@ script: - | bazel \ --output_base=$HOME/bazel/outbase \ - --batch \ --host_jvm_args=-Xmx500m \ --host_jvm_args=-Xms500m \ test \ @@ -43,6 +43,7 @@ script: --strategy=Closure=worker \ //src/test/... \ $FLAGS + - bazel shutdown notifications: email: false diff --git a/WORKSPACE b/WORKSPACE index dd08cab..f8a05ff 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -5,8 +5,14 @@ maven_jar( maven_jar( name = "com_google_errorprone_javac", - artifact = "com.google.errorprone:javac:1.8.0-u20", - sha1 = "b23b2b0e3f79e3f737496a9eca5bab65cdca791d", + artifact = "com.google.errorprone:javac:9+181-r4173-1", + sha1 = "bdf4c0aa7d540ee1f7bf14d47447aea4bbf450c5", +) + +maven_jar( + name = "com_google_errorprone_javac_shaded", + artifact = "com.google.errorprone:javac-shaded:9+181-r4173-1", + sha1 = "a399ee380b6d6b6ea53af1cfbcb086b108d1efb7", ) maven_jar( @@ -21,6 +27,22 @@ maven_jar( sha1 = "25ea2e8b0c338a877313bd4672d3fe056ea78f0d", ) +maven_jar( + name = "com_google_auto_value_auto_value", + artifact = "com.google.auto.value:auto-value:1.6.2", +) + +maven_jar( + name = "com_google_auto_value_auto_value_annotations", + artifact = "com.google.auto.value:auto-value-annotations:1.6.2", +) + +maven_jar( + name = "com_google_googlejavaformat", + artifact = "com.google.googlejavaformat:google-java-format:1.7", + sha1 = "97cb6afc835d65682edc248e19170a8e4ecfe4c4", +) + #################### # For tests @@ -57,16 +79,6 @@ maven_jar( artifact = "org.objenesis:objenesis:2.4", ) -maven_jar( - name = "com_google_auto_value_auto_value", - artifact = "com.google.auto.value:auto-value:1.6.2", -) - -maven_jar( - name = "com_google_auto_value_auto_value_annotations", - artifact = "com.google.auto.value:auto-value-annotations:1.6.2", -) - maven_jar( name = "org_hamcrest_hamcrest_core_1_3", artifact = "org.hamcrest:hamcrest-core:1.3", diff --git a/src/main/java/org/javacomp/protocol/textdocument/DocumentFormattingParams.java b/src/main/java/org/javacomp/protocol/textdocument/DocumentFormattingParams.java new file mode 100644 index 0000000..db6938e --- /dev/null +++ b/src/main/java/org/javacomp/protocol/textdocument/DocumentFormattingParams.java @@ -0,0 +1,26 @@ +package org.javacomp.protocol.textdocument; + +import org.javacomp.protocol.RequestParams; +import org.javacomp.protocol.TextDocumentIdentifier; + +/** + * Parameters for "textDocument/format" request. + * + *

See https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting + */ +public class DocumentFormattingParams implements RequestParams { + /** The document to format. */ + public TextDocumentIdentifier textDocument; + + /** The format options. */ + public FormattingOptions options; + + /** Value-object describing what options formatting should use. */ + public class FormattingOptions { + /** Size of a tab in spaces. */ + public int tabSize; + + /** Prefer spaces over tabs. */ + public boolean insertSpaces; + } +} diff --git a/src/main/java/org/javacomp/server/JavaComp.java b/src/main/java/org/javacomp/server/JavaComp.java index f81e469..24b1976 100644 --- a/src/main/java/org/javacomp/server/JavaComp.java +++ b/src/main/java/org/javacomp/server/JavaComp.java @@ -37,6 +37,7 @@ import org.javacomp.server.handler.textdocument.DidCloseHandler; import org.javacomp.server.handler.textdocument.DidOpenHandler; import org.javacomp.server.handler.textdocument.DocumentSymbolHandler; +import org.javacomp.server.handler.textdocument.FormattingHandler; import org.javacomp.server.handler.textdocument.HoverHandler; import org.javacomp.server.handler.textdocument.ReferencesHandler; import org.javacomp.server.handler.textdocument.ResolveCompletionItemHandler; @@ -85,6 +86,7 @@ public JavaComp(InputStream inputStream, OutputStream outputStream) { .registerHandler(new DidCloseHandler(this)) .registerHandler(new CompletionHandler(this, gson)) .registerHandler(new DefinitionHandler(this)) + .registerHandler(new FormattingHandler(this)) .registerHandler(new SignatureHelpTextDocumentHandler(this)) .registerHandler(new HoverHandler(this)) .registerHandler(new ResolveCompletionItemHandler(this, gson)) diff --git a/src/main/java/org/javacomp/server/handler/BUILD b/src/main/java/org/javacomp/server/handler/BUILD index ebdcf8a..1d26e76 100644 --- a/src/main/java/org/javacomp/server/handler/BUILD +++ b/src/main/java/org/javacomp/server/handler/BUILD @@ -18,6 +18,7 @@ java_library( "//src/main/java/org/javacomp/server", "//src/main/java/org/javacomp/server:request", "//src/main/java/org/javacomp/server:requestexception", + "//third_party:google_java_format", "//third_party:gson", "//third_party:guava", "//third_party:javac", diff --git a/src/main/java/org/javacomp/server/handler/InitializeHandler.java b/src/main/java/org/javacomp/server/handler/InitializeHandler.java index 705dac0..0d6326a 100644 --- a/src/main/java/org/javacomp/server/handler/InitializeHandler.java +++ b/src/main/java/org/javacomp/server/handler/InitializeHandler.java @@ -39,6 +39,7 @@ public InitializeResult handleRequest(Request request) { result.capabilities.hoverProvider = true; result.capabilities.documentSymbolProvider = true; result.capabilities.referencesProvider = true; + result.capabilities.documentFormattingProvider = true; return result; } } diff --git a/src/main/java/org/javacomp/server/handler/textdocument/FormattingHandler.java b/src/main/java/org/javacomp/server/handler/textdocument/FormattingHandler.java new file mode 100644 index 0000000..523491d --- /dev/null +++ b/src/main/java/org/javacomp/server/handler/textdocument/FormattingHandler.java @@ -0,0 +1,54 @@ +package org.javacomp.server.handler.textdocument; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; +import com.google.googlejavaformat.java.Formatter; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import org.javacomp.logging.JLogger; +import org.javacomp.protocol.Position; +import org.javacomp.protocol.Range; +import org.javacomp.protocol.TextEdit; +import org.javacomp.protocol.textdocument.DocumentFormattingParams; +import org.javacomp.server.Request; +import org.javacomp.server.Server; +import org.javacomp.server.handler.RequestHandler; + +/** + * Handles "textDocument/formatting" request. + * + *

See https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting + */ +public class FormattingHandler extends RequestHandler { + private static final JLogger logger = JLogger.createForEnclosingClass(); + + private static final Splitter LINE_SPLITTER = Splitter.on('\n'); + + private final Server server; + + public FormattingHandler(Server server) { + super("textDocument/formatting", DocumentFormattingParams.class); + this.server = server; + } + + @Override + public ImmutableList handleRequest(Request request) + throws Exception { + Optional content = + server.getFileManager().getFileContent(Paths.get(request.getParams().textDocument.uri)); + if (!content.isPresent()) { + logger.warning("Cannot find file content for %s", request.getParams().textDocument.uri); + return ImmutableList.of(); + } + if (content.get().length() == 0) { + return ImmutableList.of(); + } + String newContent = new Formatter().formatSourceAndFixImports(content.get().toString()); + List lines = LINE_SPLITTER.splitToList(content.get()); + int endLine = lines.size() - 1; + int endColumn = lines.get(endLine).length(); + Range range = new Range(new Position(0, 0), new Position(endLine, endColumn)); + return ImmutableList.of(new TextEdit(range, newContent)); + } +} diff --git a/third_party/BUILD b/third_party/BUILD index 5b1d0ee..4fd2c7b 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -42,6 +42,16 @@ java_plugin( ], ) +java_library( + name = "google_java_format", + exports = [ + "@com_google_googlejavaformat//jar", + ], + runtime_deps = [ + ":javac-shaded", + ], +) + java_library( name = "gson", exports = [ @@ -63,6 +73,13 @@ java_library( ], ) +java_library( + name = "javac-shaded", + exports = [ + "@com_google_errorprone_javac_shaded//jar", + ], +) + java_library( name = "jsr305", exports = [