diff --git a/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonExtension.java b/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonExtension.java new file mode 100644 index 00000000000..021500602bc --- /dev/null +++ b/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonExtension.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.plugin.json.languageserver; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; + +import java.util.Map; + +/** + * + */ +public interface JsonExtension { + + @JsonNotification(value="json/schemaAssociations", useSegment = false) + void jsonSchemaAssociation(Map associations); +} diff --git a/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonLanguageServerLauncher.java b/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonLanguageServerLauncher.java index 6be52d9e1d9..5b38b31cdb4 100644 --- a/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonLanguageServerLauncher.java +++ b/plugins/plugin-json/che-plugin-json-server/src/main/java/org/eclipse/che/plugin/json/languageserver/JsonLanguageServerLauncher.java @@ -12,11 +12,14 @@ import com.google.inject.Inject; import com.google.inject.Singleton; - import org.eclipse.che.api.languageserver.exception.LanguageServerException; import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncherTemplate; +import org.eclipse.che.api.languageserver.registry.ServerInitializerObserver; import org.eclipse.che.api.languageserver.shared.model.LanguageDescription; +import org.eclipse.lsp4j.ServerCapabilities; +import org.eclipse.lsp4j.jsonrpc.Endpoint; import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints; import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageServer; @@ -24,6 +27,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import static java.util.Arrays.asList; @@ -32,7 +37,7 @@ * @author Anatolii Bazko */ @Singleton -public class JsonLanguageServerLauncher extends LanguageServerLauncherTemplate { +public class JsonLanguageServerLauncher extends LanguageServerLauncherTemplate implements ServerInitializerObserver { private static final String LANGUAGE_ID = "json"; private static final String[] EXTENSIONS = new String[]{"json", "bowerrc", "jshintrc", "jscsrc", "eslintrc", @@ -42,6 +47,8 @@ public class JsonLanguageServerLauncher extends LanguageServerLauncherTemplate { private final Path launchScript; + private LanguageClient client; + @Inject public JsonLanguageServerLauncher() { launchScript = Paths.get(System.getenv("HOME"), "che/ls-json/launch.sh"); @@ -58,6 +65,7 @@ public boolean isAbleToLaunch() { } protected LanguageServer connectToLanguageServer(final Process languageServerProcess, LanguageClient client) { + this.client = client; Launcher launcher = Launcher.createLauncher(client, LanguageServer.class, languageServerProcess.getInputStream(), languageServerProcess.getOutputStream()); @@ -82,4 +90,20 @@ protected Process startLanguageServerProcess(String projectPath) throws Language description.setLanguageId(LANGUAGE_ID); description.setMimeTypes(asList(MIME_TYPES)); } + + @Override + public void onServerInitialized(LanguageServer server, ServerCapabilities capabilities, LanguageDescription languageDescription, String projectPath) { + Endpoint endpoint = ServiceEndpoints.toEndpoint(server); + JsonExtension serviceObject = ServiceEndpoints.toServiceObject(endpoint, JsonExtension.class); + Map associations = new HashMap<>(); + associations.put("/*.schema.json", new String[]{"http://json-schema.org/draft-04/schema#"}); + associations.put("/bower.json", new String[]{"http://json.schemastore.org/bower"}); + associations.put("/.bower.json", new String[]{"http://json.schemastore.org/bower"}); + associations.put("/.bowerrc", new String[]{"http://json.schemastore.org/bowerrc"}); + associations.put("/composer.json", new String[]{"https://getcomposer.org/schema.json"}); + associations.put("/package.json", new String[]{"http://json.schemastore.org/package"}); + associations.put("/jsconfig.json", new String[]{"http://json.schemastore.org/jsconfig"}); + associations.put("/tsconfig.json", new String[]{"http://json.schemastore.org/tsconfig"}); + serviceObject.jsonSchemaAssociation(associations); + } } diff --git a/wsagent/che-core-api-languageserver-shared/src/main/java/org/eclipse/che/api/languageserver/shared/model/ExtendedCompletionItem.java b/wsagent/che-core-api-languageserver-shared/src/main/java/org/eclipse/che/api/languageserver/shared/model/ExtendedCompletionItem.java index 1a55c86536b..2696f1c56ef 100644 --- a/wsagent/che-core-api-languageserver-shared/src/main/java/org/eclipse/che/api/languageserver/shared/model/ExtendedCompletionItem.java +++ b/wsagent/che-core-api-languageserver-shared/src/main/java/org/eclipse/che/api/languageserver/shared/model/ExtendedCompletionItem.java @@ -10,13 +10,13 @@ */ public class ExtendedCompletionItem extends CompletionItem { - private TextDocumentIdentifier documentIdentifier; + private TextDocumentIdentifier textDocumentIdentifier; public TextDocumentIdentifier getTextDocumentIdentifier() { - return documentIdentifier; + return textDocumentIdentifier; } public void setTextDocumentIdentifier(TextDocumentIdentifier documentIdentifier) { - this.documentIdentifier = documentIdentifier; + this.textDocumentIdentifier = documentIdentifier; } } diff --git a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/PublishDiagnosticsParamsJsonRpcTransmitter.java b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/PublishDiagnosticsParamsJsonRpcTransmitter.java index 6223c91abfa..3d2233510c3 100644 --- a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/PublishDiagnosticsParamsJsonRpcTransmitter.java +++ b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/PublishDiagnosticsParamsJsonRpcTransmitter.java @@ -31,7 +31,9 @@ public class PublishDiagnosticsParamsJsonRpcTransmitter { @Inject private void subscribe(EventService eventService, RequestTransmitter requestTransmitter) { eventService.subscribe(event -> { - event.setUri(event.getUri().substring(16)); + if(event.getUri() != null) { + event.setUri(event.getUri().substring(16)); + } endpointIds.forEach(endpointId -> requestTransmitter.newRequest() .endpointId(endpointId) .methodName("textDocument/publishDiagnostics") diff --git a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImpl.java b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImpl.java index c4aae3534de..59735cd6c42 100644 --- a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImpl.java +++ b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImpl.java @@ -12,7 +12,6 @@ import com.google.inject.Inject; import com.google.inject.Singleton; - import org.eclipse.che.api.core.notification.EventService; import org.eclipse.che.api.languageserver.exception.LanguageServerException; import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; @@ -149,7 +148,7 @@ protected LanguageServer doInitialize(LanguageServerLauncher launcher, String pr throw new LanguageServerException( "Can't initialize Language Server " + languageId + " on " + projectPath + ". " + e.getMessage(), e); } - registerCallbacks(server); + registerCallbacks(server, launcher); CompletableFuture completableFuture = server.initialize(initializeParams); try { @@ -166,18 +165,24 @@ protected LanguageServer doInitialize(LanguageServerLauncher launcher, String pr return server; } - protected void registerCallbacks(LanguageServer server) { + protected void registerCallbacks(LanguageServer server, LanguageServerLauncher launcher) { if (server instanceof ServerInitializerObserver) { addObserver((ServerInitializerObserver)server); } + + if (launcher instanceof ServerInitializerObserver) { + addObserver((ServerInitializerObserver) launcher); + } } protected InitializeParams prepareInitializeParams(String projectPath) { InitializeParams initializeParams = new InitializeParams(); initializeParams.setProcessId(PROCESS_ID); initializeParams.setRootPath(projectPath); - initializeParams.setCapabilities(new ClientCapabilities()); + initializeParams.setCapabilities(new ClientCapabilities(){ + + }); initializeParams.setClientName(CLIENT_NAME); return initializeParams; } diff --git a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/service/TextDocumentService.java b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/service/TextDocumentService.java index 558fe175ec7..b100f180700 100644 --- a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/service/TextDocumentService.java +++ b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/service/TextDocumentService.java @@ -11,7 +11,6 @@ package org.eclipse.che.api.languageserver.service; import com.google.inject.Singleton; - import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcException; import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator; import org.eclipse.che.api.languageserver.exception.LanguageServerException; @@ -19,12 +18,12 @@ import org.eclipse.che.api.languageserver.registry.LanguageServerRegistryImpl; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.CompletionItemDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.CompletionListDto; -import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.ExtendedCompletionItemDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.HoverDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.LocationDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.SignatureHelpDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.SymbolInformationDto; import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.TextEditDto; +import org.eclipse.che.api.languageserver.shared.model.ExtendedCompletionItem; import org.eclipse.lsp4j.DidChangeTextDocumentParams; import org.eclipse.lsp4j.DidCloseTextDocumentParams; import org.eclipse.lsp4j.DidOpenTextDocumentParams; @@ -34,6 +33,7 @@ import org.eclipse.lsp4j.DocumentOnTypeFormattingParams; import org.eclipse.lsp4j.DocumentRangeFormattingParams; import org.eclipse.lsp4j.DocumentSymbolParams; +import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.ReferenceParams; import org.eclipse.lsp4j.TextDocumentIdentifier; @@ -81,7 +81,7 @@ public void configureMethods() { dtoToDtoList("references", ReferenceParams.class, LocationDto.class, this::references); dtoToDtoList("onTypeFormatting", DocumentOnTypeFormattingParams.class, TextEditDto.class, this::onTypeFormatting); - dtoToDto("completionItem/resolve", ExtendedCompletionItemDto.class, CompletionItemDto.class, this::completionItemResolve); + dtoToDto("completionItem/resolve", ExtendedCompletionItem.class, CompletionItemDto.class, this::completionItemResolve); dtoToDto("documentHighlight", TextDocumentPositionParams.class, DocumentHighlight.class, this::documentHighlight); dtoToDto("completion", TextDocumentPositionParams.class, CompletionListDto.class, this::completion); dtoToDto("hover", TextDocumentPositionParams.class, HoverDto.class, this::hover); @@ -157,7 +157,7 @@ private List definition(TextDocumentPositionParams textDocumentPosi } } - private CompletionItemDto completionItemResolve(ExtendedCompletionItemDto unresolved) { + private CompletionItemDto completionItemResolve(ExtendedCompletionItem unresolved) { try { LanguageServer server = getServer(prefixURI(unresolved.getTextDocumentIdentifier().getUri())); @@ -173,7 +173,13 @@ private HoverDto hover(TextDocumentPositionParams positionParams) { positionParams.getTextDocument().setUri(prefixURI(positionParams.getTextDocument().getUri())); positionParams.setUri(prefixURI(positionParams.getUri())); LanguageServer server = getServer(positionParams.getTextDocument().getUri()); - return server != null ? new HoverDto(server.getTextDocumentService().hover(positionParams).get()) : null; + if(server != null) { + Hover hover = server.getTextDocumentService().hover(positionParams).get(); + if (hover != null) { + return new HoverDto(hover); + } + } + return null; } catch (InterruptedException | ExecutionException | LanguageServerException e) { throw new JsonRpcException(-27000, e.getMessage()); } diff --git a/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImplTest.java b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImplTest.java index 732844eb441..4154e891605 100644 --- a/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImplTest.java +++ b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/registry/ServerInitializerImplTest.java @@ -69,7 +69,7 @@ public void initializerShouldNotifyObservers() throws Exception { when(launcher.getLanguageDescription()).thenReturn(languageDescription); when(launcher.launch(anyString(), any())).thenReturn(server); - doNothing().when(initializer).registerCallbacks(server); + doNothing().when(initializer).registerCallbacks(server, launcher); initializer.addObserver(observer); LanguageServer languageServer = initializer.initialize(launcher, "/path");