Интеграция сервера языка
Если вы ищете информацию о том, как использовать LSP Deno с различными редакторами, посетите страницу Настройка вашей среды.
CLI Deno поставляется со встроенным сервером языка, который может обеспечить интеллектуальный опыт редактирования, а также способ легко получить доступ к другим инструментам, встроенным в Deno. Для большинства пользователей использование сервера языка будет осуществляться через редактор, такой как Visual Studio Code или другие редакторы.
Эта страница предназначена для тех, кто создает интеграцию с сервером языка или предоставляет реестр пакетов для Deno, который интегрируется интеллектуально.
Сервер языка Deno предоставляет реализацию сервера Протокола сервера языка, специально разработанного для предоставления представления кода Deno. Он интегрирован в командную строку и может быть запущен с помощью подкоманды lsp.
Структура
При запуске сервера языка создается экземпляр LanguageServer, который хранит все состояние сервера языка. Он также определяет все методы, вызываемые клиентом через протокол RPC сервера языка.
Настройки
Сервер языка поддерживает ряд настроек для рабочей области:
deno.enabledeno.enablePathsdeno.cachedeno.certificateStoresdeno.configdeno.importMapdeno.internalDebugdeno.codeLens.implementationsdeno.codeLens.referencesdeno.codeLens.referencesAllFunctionsdeno.codeLens.testdeno.suggest.completeFunctionCallsdeno.suggest.namesdeno.suggest.pathsdeno.suggest.autoImportsdeno.suggest.imports.autoDiscoverdeno.suggest.imports.hostsdeno.lintdeno.tlsCertificatedeno.unsafelyIgnoreCertificateErrorsdeno.unstable
И существуют настройки, поддерживаемые сервером языка на основе каждого ресурса:
deno.enabledeno.enablePathsdeno.codeLens.test
Deno анализирует эти настройки на нескольких этапах процесса сервера языка. Во-первых, когда запрос initialize поступает от клиента, initializationOptions будет предполагаться как объект, представляющий deno пространство имен опций. Например, следующее значение включит Deno с неустойчивыми API для этого экземпляра сервера языка.
{
"enable": true,
"unstable": true
}
Когда сервер языка получает уведомление workspace/didChangeConfiguration, он оценит, указал ли клиент, обладает ли он возможностью workspaceConfiguration. Если да, он отправит запрос workspace/configuration, который будет включать запрос конфигурации рабочей области, а также конфигурацию всех URI, которые в настоящее время отслеживаются сервером языка.
Если клиент обладает возможностью workspaceConfiguration, сервер языка отправит запрос конфигурации для URI при получении уведомления textDocument/didOpen, чтобы получить настройки, специфичные для ресурсов.
Если клиент не обладает возможностью workspaceConfiguration, сервер языка предположит, что настройки рабочей области применяются ко всем ресурсам.
Команды
Существует несколько команд, которые могут быть выпущены сервером языка клиенту, реализацию которых от него ожидается:
.cache
deno.cache отправляется как код решения действия, когда существует некэшированный спецификатор модуля, который импортируется в модуль. Он будет отправлен с аргументом, содержащим разрешенный спецификатор в виде строки для кеширования.
showReferences
deno.showReferences отправляется как команда для некоторых линз кода для отображения расположений ссылок. Аргументы содержат спецификатор, являющийся объектом команды, начальную позицию целевого объекта и расположения ссылок для отображения.
test
deno.test отправляется в рамках линзы кода для тестирования, от клиента ожидается запуск теста на основе аргументов, которые являются спецификатором, содержащим тест, и именем теста для фильтрации тестов.
Запросы
В настоящее время LSP поддерживает следующие пользовательские запросы. Клиент должен реализовать их, чтобы иметь полностью функционирующий клиент, который хорошо интегрируется с Deno:
/cache
deno/cache укажет Deno попытаться кэшировать модуль и все его зависимости. Если передан только referrer, то все зависимости для спецификатора модуля будут загружены. Если в uris есть значения, то будут кэшированы только эти uris.
Ожидаются параметры:
interface CacheParams {
referrer: TextDocumentIdentifier;
uris: TextDocumentIdentifier[];
}
performance
deno/performance запрашивает возвращение средних значений времени для внутренней инструментации Deno. Не ожидаются параметры.
reloadImportRegistries
deno/reloadImportRegistries перегружает любые кэшированные ответы из реестров импорта. Не ожидаются параметры.
virtualTextDocument
deno/virtualTextDocument запрашивает виртуальный документ текста от LSP, который является только для чтения документом, который может быть отображен в клиенте. Это позволяет клиентам получить доступ к документам в кэше Deno, таким как удаленные модули и файлы библиотек TypeScript, встроенные в Deno. Сервер языка Deno закодирует все внутренние файлы под пользовательской схемой deno:, поэтому клиенты должны направлять все запросы к схеме deno: обратно к API deno/virtualTextDocument.
Он также поддерживает специальный URL deno:/status.md, который предоставляет документ текста в формате Markdown, содержащий подробности о состоянии LSP для отображения пользователю.
Ожидаются параметры:
interface VirtualTextDocumentParams {
textDocument: TextDocumentIdentifier;
}
task
deno/task запрашивает возвращение доступных задач deno, см. task_runner. Не ожидаются параметры.
Уведомления
В настоящее время отправляется одно пользовательское уведомление от сервера клиенту, deno/registryState. Когда deno.suggest.imports.autoDiscover true и источник импорта, добавляемого в документ, не явно задан в deno.suggest.imports.hosts, источник будет проверен, и уведомление будет отправлено клиенту о статусе.
При получении уведомления, если параметр suggestion true, клиент должен предложить пользователю возможность включить источник и добавить его в конфигурацию для deno.suggest.imports.hosts. Если suggestion false, клиент должен добавить его в конфигурацию в качестве false, чтобы остановить сервер языка от попыток обнаружить поддержку предложений.
Параметры уведомления:
interface RegistryStatusNotificationParams {
origin: string;
suggestions: boolean;
}
Идентификаторы языков
Сервер языка поддерживает диагностику и форматирование для следующих идентификаторов языка текстовых документов:
"javascript""javascriptreact"-
"jsx"нестандартный, такой же какjavascriptreact "typescript""typescriptreact"-
"tsx"нестандартный, такой же какtypescriptreact
Сервер языка поддерживает только форматирование для следующих идентификаторов языков:
"json""jsonc""markdown"
Тестирование
Сервер языка Deno поддерживает настраиваемый набор API для включения тестирования. Они построены на предоставлении информации для активации API тестирования vscode, но могут быть использованы другими клиентами сервера языка для предоставления аналогичного интерфейса.
И клиент, и сервер должны поддерживать экспериментальную возможность testingApi.
interface ClientCapabilities {
experimental?: {
testingApi: boolean;
};
}
interface ServerCapabilities {
experimental?: {
testingApi: boolean;
};
}
При возникновении версии Deno, поддерживающей API тестирования, которая сталкивается с клиентом, поддерживающим возможность, она инициирует код, который обрабатывает обнаружение тестов, и начнет предоставлять уведомления, которые его активируют.
Также следует отметить, что при включении возможностей API тестирования линзы кода для тестирования больше не будут отправляться клиенту.
Настройки тестирования
Существуют определенные настройки, которые изменяют поведение сервера языка:
-
deno.testing.args- массив строк, которые будут предоставлены в качестве аргументов при выполнении тестов. Это работает так же, как подкомандаdeno test. -
deno.testing.enable- двоичный флаг, который включает или выключает сервер тестирования
Уведомления о тестировании
Сервер будет отправлять уведомления клиенту при определенных условиях.
deno/testModule
Когда сервер обнаруживает модуль, содержащий тесты, он уведомит клиент, отправив уведомление deno/testModule вместе с полезной нагрузкой TestModuleParams.
Deno структурирует таким образом:
- Модуль может содержать n тестов.
- Тест может содержать n шагов.
- Шаг может содержать n шагов.
Когда Deno выполняет статический анализ модуля теста, он пытается идентифицировать тесты и шаги тестов. Из-за динамичного способа объявления тестов в Deno, их всегда нельзя статически идентифицировать, и их можно идентифицировать только при выполнении модуля. Уведомление разработано для обработки обоих этих ситуаций при обновлении клиента. Когда тесты обнаруживаются статически, уведомление kind "replace", когда тесты или шаги обнаруживаются во время выполнения, уведомление kind "insert".
По мере редактирования документа теста в редакторе и получения уведомлений textDocument/didChange от клиента, статический анализ этих изменений будет выполняться на стороне сервера, и если тесты изменились, клиент получит уведомление.
Когда клиент получает уведомление "replace", он может безопасно «заменить» представление модуля теста, где при получении "insert", он должен рекурсивно пытаться добавить существующие представления.
Для тестовых модулей следует использовать textDocument.uri в качестве уникального идентификатора для любого представления (так как это строка URL уникального модуля). TestData элементы содержат уникальную id строку. Эта id строка представляет собой хэш SHA-256 идентификационной информации, которую сервер отслеживает для теста.
interface TestData {
/** The unique ID for this test/step. */
id: string;
/** The display label for the test/step. */
label: string;
/** Any test steps that are associated with this test/step */
steps?: TestData[];
/** The range of the owning text document that applies to the test. */
range?: Range;
}
interface TestModuleParams {
/** The text document identifier that the tests are related to. */
textDocument: TextDocumentIdentifier;
/** A indication if tests described are _newly_ discovered and should be
* _inserted_ or if the tests associated are a replacement for any existing
* tests. */
kind: "insert" | "replace";
/** The text label for the test module. */
label: string;
/** An array of tests that are owned by this test module. */
tests: TestData[];
}
deno/testModuleDelete
Когда тестовый модуль, который отслеживается сервером, удаляется, сервер выдает уведомление deno/testModuleDelete. При получении уведомления клиент должен удалить представление тестового модуля и всех его дочерних тестов и шагов тестов.
interface TestModuleDeleteParams {
/** The text document identifier that has been removed. */
textDocument: TextDocumentIdentifier;
}
deno/testRunProgress
Когда клиент запрашивает deno/testRun, сервер будет поддерживать прогресс этого выполнения теста через уведомление deno/testRunProgress.
Клиент должен обработать эти сообщения и обновить любое пользовательское представление.
Изменение состояния представлено в свойстве .message.kind объекта TestRunProgressParams. Состояния:
-
"enqueued"- Тест или шаг теста был помещен в очередь для тестирования. -
"skipped"- Тест или шаг теста был пропущен. Это происходит, когда у теста Deno установлен параметрignoreсо значениемtrue. -
"started"- Тест или шаг теста начался. -
"passed"- Тест или шаг теста пройден. -
"failed"- Тест или шаг теста завершился с ошибкой. Это предназначено для обозначения ошибки в инструменте тестирования, а не в самом тесте, но Deno пока не поддерживает это различие. -
"errored"- Тест или шаг теста завершился с ошибкой. Дополнительная информация об ошибке будет в свойстве.message.messages. -
"end"- Выполнение теста завершено.
interface TestIdentifier {
/** The test module the message is related to. */
textDocument: TextDocumentIdentifier;
/** The optional ID of the test. If not present, then the message applies to
* all tests in the test module. */
id?: string;
/** The optional ID of the step. If not present, then the message only applies
* to the test. */
stepId?: string;
}
interface TestMessage {
/** The content of the message. */
message: MarkupContent;
/** An optional string which represents the expected output. */
expectedOutput?: string;
/** An optional string which represents the actual output. */
actualOutput?: string;
/** An optional location related to the message. */
location?: Location;
}
interface TestEnqueuedStartedSkipped {
/** The state change that has occurred to a specific test or test step.
*
* - `"enqueued"` - the test is now enqueued to be tested
* - `"started"` - the test has started
* - `"skipped"` - the test was skipped
*/
type: "enqueued" | "started" | "skipped";
/** The test or test step relating to the state change. */
test: TestIdentifier;
}
interface TestFailedErrored {
/** The state change that has occurred to a specific test or test step.
*
* - `"failed"` - The test failed to run properly, versus the test erroring.
* currently the Deno language server does not support this.
* - `"errored"` - The test errored.
*/
type: "failed" | "errored";
/** The test or test step relating to the state change. */
test: TestIdentifier;
/** Messages related to the state change. */
messages: TestMessage[];
/** An optional duration, in milliseconds from the start to the current
* state. */
duration?: number;
}
interface TestPassed {
/** The state change that has occurred to a specific test or test step. */
type: "passed";
/** The test or test step relating to the state change. */
test: TestIdentifier;
/** An optional duration, in milliseconds from the start to the current
* state. */
duration?: number;
}
interface TestOutput {
/** The test or test step has output information / logged information. */
type: "output";
/** The value of the output. */
value: string;
/** The associated test or test step if there was one. */
test?: TestIdentifier;
/** An optional location associated with the output. */
location?: Location;
}
interface TestEnd {
/** The test run has ended. */
type: "end";
}
type TestRunProgressMessage =
| TestEnqueuedStartedSkipped
| TestFailedErrored
| TestPassed
| TestOutput
| TestEnd;
interface TestRunProgressParams {
/** The test run ID that the progress message applies to. */
id: number;
/** The message*/
message: TestRunProgressMessage;
}
Запросы тестирования
Сервер обрабатывает два разных запроса:
deno/testRun
Для запроса к языковому серверу выполнения набора тестов клиент отправляет запрос deno/testRun, который включает идентификатор выполнения теста, используемый в будущих ответах клиенту, тип выполнения теста и любые тестовые модули или тесты для включения или исключения.
В настоящее время Deno поддерживает только тип выполнения теста "run". "debug" и "coverage" планируется добавить в будущем.
Если не указаны тестовые модули или тесты, это подразумевает, что должны быть выполнены все обнаруженные тестовые модули и тесты. Если указан тестовый модуль, но не указаны идентификаторы тестов, это подразумевает, что должны быть включены все тесты в этом тестовом модуле. После определения всех тестов, исключенные тесты удаляются, и результирующий набор тестов возвращается в ответе как "enqueued".
Включить или исключить шаги тестов через этот API невозможно из-за динамического характера объявления и выполнения шагов тестов.
interface TestRunRequestParams {
/** The id of the test run to be used for future messages. */
id: number;
/** The run kind. Currently Deno only supports `"run"` */
kind: "run" | "coverage" | "debug";
/** Test modules or tests to exclude from the test run. */
exclude?: TestIdentifier[];
/** Test modules or tests to include in the test run. */
include?: TestIdentifier[];
}
interface EnqueuedTestModule {
/** The test module the enqueued test IDs relate to */
textDocument: TextDocumentIdentifier;
/** The test IDs which are now enqueued for testing */
ids: string[];
}
interface TestRunResponseParams {
/** Test modules and test IDs that are now enqueued for testing. */
enqueued: EnqueuedTestModule[];
}
deno/testRunCancel
Если клиент хочет отменить текущее выполнение теста, он отправляет запрос deno/testRunCancel с идентификатором теста для отмены. Ответ будет булевым значением true (если тест отменён) или false (если отмена невозможна). Соответствующие уведомления о прогрессе теста всё равно будут отправляться по мере отмены теста.
interface TestRunCancelParams {
/** The test id to be cancelled. */
id: number;
}
© 2018–2024 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/reference/lsp_integration