Skip to content

Commit

Permalink
Merge pull request #2567 from salexdv/feature/websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
nixel2007 authored Oct 28, 2022
2 parents 5c5c64a + acc411f commit 2e7c1a4
Show file tree
Hide file tree
Showing 18 changed files with 562 additions and 15 deletions.
4 changes: 3 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ dependencies {

// spring
api("org.springframework.boot:spring-boot-starter")
api("org.springframework.boot:spring-boot-starter-websocket")
api("info.picocli:picocli-spring-boot-starter:4.6.3")

// lsp4j core
api("org.eclipse.lsp4j", "org.eclipse.lsp4j", "0.14.0")
api("org.eclipse.lsp4j", "org.eclipse.lsp4j", "0.17.0")
api("org.eclipse.lsp4j", "org.eclipse.lsp4j.websocket", "0.17.0")

// 1c-syntax
api("com.github.1c-syntax", "bsl-parser", "167aaad827322e09ccde4658a71152dad234de4b") {
Expand Down
53 changes: 49 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [Руководство контрибьютора](contributing/index.md)
* <a href="#capabilities">Возможности</a>
* <a href="#cli">Запуск из командной строки</a>
* <a href="#websocket">Запуск в режиме websocket</a>
* <a href="#analyze">Запуск в режиме анализатора</a>
* <a href="#format">Запуск в режиме форматтера</a>
* <a href="#configuration">Конфигурационный файл</a>
Expand Down Expand Up @@ -127,16 +128,60 @@ Usage: bsl-language-server [-h] [-c=<path>] [COMMAND [ARGS]]
Path to language server configuration file
-h, --help Show this help message and exit
Commands:
analyze, -a, --analyze Run analysis and get diagnostic info
format, -f, --format Format files in source directory
version, -v, --version Print version
lsp, --lsp LSP server mode (default)
analyze, -a, --analyze Run analysis and get diagnostic info
format, -f, --format Format files in source directory
version, -v, --version Print version
lsp, --lsp LSP server mode (default)
websocket, -w, --websocket Websocket server mode
```
При запуске BSL Language Server в обычном режиме будет запущен сам Language Server, взаимодействующий по протоколу [LSP]([language server protocol](https://microsoft.github.io/language-server-protocol/)). Для взаимодействия используются stdin и stdout.
По умолчанию тексты диагностик выдаются на русском языке. Для переключения языка сообщений от движка диагностик необходимо настроить параметр `language` в конфигурационном файле или вызвав событие `workspace/didChangeConfiguration`:
```json
{
"language": "en"
}
```
<a id="websocket"></a>
## Запуск в режиме websocket
По умолчанию взаимодействие с сервером идет через стандартные потоки ввода/вывода.
Но вы можете запустить BSL Language Server со встроенным веб-сервером и взаимодействовать с ним через websocket.
Для этого необходимо запустить BSL Language Server с ключом `--websocket` или `-w`:
```sh
Usage: bsl-language-server websocket [-h] [--app.websocket.lsp-path=<path>]
[-c=<path>] [--server.port=<port>]
Websocket server mode
--app.websocket.lsp-path=<path>
Path to LSP endpoint. Default is /lsp
-c, --configuration=<path> Path to language server configuration file
-h, --help Show this help message and exit
--server.port=<port> Port to listen. Default is 8025
```
После запуска BSL Language Server будет доступен по адресу `ws://localhost:8025/lsp`.
Для переопределения порта к LSP-серверу необходимо использовать параметр `--server.port`, за которым следует номер желаемого порта.
Для переопределения пути к LSP-серверу необходимо использовать параметр `--app.websocket.lsp-path`, за которым следует желаемый путь, начинающийся с `/`.
Пример строки запуска BSL Language Server в режиме websocket с указанием порта 8080:
```sh
java -jar bsl-language-server.jar --websocket --server.port=8080
```
> При работе с большим проектом рекомендуется дополнительно указывать параметр -Xmx, отвечающий за предел оперативной памяти для java процесса. Размер выделяемой памяти зависит от размера анализируемой кодовой базы.
```sh
java -Xmx4g -jar bsl-language-server.jar ...остальные параметры
```
<a id="analyze"></a>
## Запуск в режиме анализатора
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@
import com.github._1c_syntax.bsl.languageserver.cli.FormatCommand;
import com.github._1c_syntax.bsl.languageserver.cli.LanguageServerStartCommand;
import com.github._1c_syntax.bsl.languageserver.cli.VersionCommand;
import com.github._1c_syntax.bsl.languageserver.cli.WebsocketCommand;
import com.github._1c_syntax.utils.CaseInsensitivePattern;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.stereotype.Component;
import picocli.CommandLine;
import picocli.CommandLine.Option;
Expand All @@ -54,11 +57,12 @@
AnalyzeCommand.class,
FormatCommand.class,
VersionCommand.class,
LanguageServerStartCommand.class
LanguageServerStartCommand.class,
WebsocketCommand.class
},
usageHelpAutoWidth = true,
synopsisSubcommandLabel = "[COMMAND [ARGS]]",
footer = "@|green Copyright(c) 2018-2020|@",
footer = "@|green Copyright(c) 2018-2022|@",
header = "@|green BSL language server|@")
@SpringBootApplication
@Component
Expand Down Expand Up @@ -100,7 +104,9 @@ public class BSLLSPLauncher implements Callable<Integer>, CommandLineRunner, Exi
private int exitCode;

public static void main(String[] args) {
var applicationContext = SpringApplication.run(BSLLSPLauncher.class, args);
var applicationContext = new SpringApplicationBuilder(BSLLSPLauncher.class)
.web(getWebApplicationType(args))
.run(args);
var launcher = applicationContext.getBean(BSLLSPLauncher.class);
if (launcher.getExitCode() >= 0) {
System.exit(
Expand Down Expand Up @@ -158,4 +164,15 @@ public Integer call() {
// заглушка, командой как таковой не пользуемся
return 0;
}

private static WebApplicationType getWebApplicationType(String[] args) {
WebApplicationType webApplicationType;
var argsList = Arrays.asList(args);
if (argsList.contains("-w") || argsList.contains("websocket")) {
webApplicationType = WebApplicationType.SERVLET;
} else {
webApplicationType = WebApplicationType.NONE;
}
return webApplicationType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
import org.eclipse.lsp4j.HoverParams;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.LocationLink;
import org.eclipse.lsp4j.PrepareRenameDefaultBehavior;
import org.eclipse.lsp4j.PrepareRenameParams;
import org.eclipse.lsp4j.PrepareRenameResult;
import org.eclipse.lsp4j.Range;
Expand All @@ -87,6 +88,7 @@
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.Either3;
import org.eclipse.lsp4j.services.TextDocumentService;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -380,14 +382,14 @@ public CompletableFuture<Diagnostics> diagnostics(DiagnosticParams params) {
}

@Override
public CompletableFuture<Either<Range, PrepareRenameResult>> prepareRename(PrepareRenameParams params) {
public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaultBehavior>> prepareRename(PrepareRenameParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}

return CompletableFuture.supplyAsync(() ->
Either.forLeft(renameProvider.getPrepareRename(documentContext, params)));
Either3.forFirst(renameProvider.getPrepareRename(documentContext, params)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
aliases = {"-a", "--analyze"},
description = "Run analysis and get diagnostic info",
usageHelpAutoWidth = true,
footer = "@|green Copyright(c) 2018-2020|@")
footer = "@|green Copyright(c) 2018-2022|@")
@Component
@RequiredArgsConstructor
public class AnalyzeCommand implements Callable<Integer> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
aliases = {"-f", "--format"},
description = "Format files in source directory",
usageHelpAutoWidth = true,
footer = "@|green Copyright(c) 2018-2020|@")
footer = "@|green Copyright(c) 2018-2022|@")
@Component
@RequiredArgsConstructor
public class FormatCommand implements Callable<Integer> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
aliases = {"--lsp"},
description = "LSP server mode (default)",
usageHelpAutoWidth = true,
footer = "@|green Copyright(c) 2018-2020|@")
footer = "@|green Copyright(c) 2018-2022|@")
@Component
@RequiredArgsConstructor
public class LanguageServerStartCommand implements Callable<Integer> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
aliases = {"-v", "--version"},
description = "Print version",
usageHelpAutoWidth = true,
footer = "@|green Copyright(c) 2018-2020|@")
footer = "@|green Copyright(c) 2018-2022|@")
@Component
@RequiredArgsConstructor
public class VersionCommand implements Callable<Integer> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2022
* Alexey Sosnoviy <[email protected]>, Nikita Fedkin <[email protected]> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.cli;

import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.concurrent.Callable;

import static picocli.CommandLine.Command;
import static picocli.CommandLine.Option;

/**
* Запускает приложение в режиме Websocket Language Server.
* Ключ команды:
* -w, (--websocket)
* Параметры:
* -c, (--configuration) &lt;arg&gt; - Путь к конфигурационному файлу BSL Language Server (.bsl-language-server.json).
* Возможно указывать как в абсолютном, так и относительном виде.
* Если параметр опущен, то будут использованы настройки по умолчанию.
* --server.port - Порт, на котором открывается соединение. Если параметр опущен,
* то будет использован порт по умолчанию, а именно 8025.
* --app.websocket.lsp-path - Адрес, по которому открывается соединение. Если параметр опущен,
* то будет использован адрес по умолчанию, а именно /lsp.
* Выводимая информация:
* Данный режим используется для взаимодействия с клиентом по протоколу LSP через websocket.
*
*/
@Slf4j
@Command(
name = "websocket",
aliases = {"-w", "--websocket"},
description = "Websocket server mode",
usageHelpAutoWidth = true,
footer = "@|green Copyright(c) 2018-2022|@")
@Component
@RequiredArgsConstructor
public class WebsocketCommand implements Callable<Integer> {
@Option(
names = {"-h", "--help"},
usageHelp = true,
description = "Show this help message and exit")
private boolean usageHelpRequested;

@Option(
names = {"-c", "--configuration"},
description = "Path to language server configuration file",
paramLabel = "<path>",
defaultValue = "")
private String configurationOption;

@Option(
names = {"--server.port"},
description = "Port to listen. Default is 8025",
paramLabel = "<port>",
defaultValue = "8025")
private int serverPort;

@Option(
names = {"--app.websocket.lsp-path"},
description = "Path to LSP endpoint. Default is /lsp",
paramLabel = "<path>",
defaultValue = "/lsp")
private String endpointPath;

private final LanguageServerConfiguration configuration;

public Integer call() {
var configurationFile = new File(configurationOption);
if (configurationFile.exists()) {
configuration.update(configurationFile);
}

return -1;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2022
* Alexey Sosnoviy <[email protected]>, Nikita Fedkin <[email protected]> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.websocket;

import lombok.RequiredArgsConstructor;
import org.eclipse.lsp4j.jsonrpc.Launcher.Builder;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.LanguageServer;
import org.eclipse.lsp4j.websocket.WebSocketEndpoint;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

/**
* Конечная точка для подключения к Language Server через websocket.
*/
@Component
@RequiredArgsConstructor
public class LSPWebSocketEndpoint extends WebSocketEndpoint<LanguageClient> {

private final LanguageServer languageServer;
private final List<LanguageClientAware> languageClientAwares;

@Override
protected void configure(Builder<LanguageClient> builder) {
builder.setLocalService(languageServer);
builder.setRemoteInterface(LanguageClient.class);
}

@Override
protected void connect(Collection<Object> localServices, LanguageClient remoteProxy) {
languageClientAwares.forEach(languageClientAware -> languageClientAware.connect(remoteProxy));
}

}
Loading

0 comments on commit 2e7c1a4

Please sign in to comment.