typescript-language-server 0.11.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +160 -27
  3. package/lib/calls.d.ts +3 -3
  4. package/lib/calls.d.ts.map +1 -1
  5. package/lib/calls.js +143 -195
  6. package/lib/calls.js.map +1 -1
  7. package/lib/cli.js +9 -33
  8. package/lib/cli.js.map +1 -1
  9. package/lib/commands.d.ts +1 -0
  10. package/lib/commands.d.ts.map +1 -1
  11. package/lib/commands.js +4 -5
  12. package/lib/commands.js.map +1 -1
  13. package/lib/completion.d.ts +8 -11
  14. package/lib/completion.d.ts.map +1 -1
  15. package/lib/completion.js +121 -163
  16. package/lib/completion.js.map +1 -1
  17. package/lib/configuration-manager.d.ts +47 -0
  18. package/lib/configuration-manager.d.ts.map +1 -0
  19. package/lib/configuration-manager.js +105 -0
  20. package/lib/configuration-manager.js.map +1 -0
  21. package/lib/diagnostic-queue.d.ts +10 -9
  22. package/lib/diagnostic-queue.d.ts.map +1 -1
  23. package/lib/diagnostic-queue.js +13 -21
  24. package/lib/diagnostic-queue.js.map +1 -1
  25. package/lib/document-symbol.d.ts +2 -2
  26. package/lib/document-symbol.d.ts.map +1 -1
  27. package/lib/document-symbol.js +20 -25
  28. package/lib/document-symbol.js.map +1 -1
  29. package/lib/document.d.ts +1 -1
  30. package/lib/document.d.ts.map +1 -1
  31. package/lib/document.js +6 -34
  32. package/lib/document.js.map +1 -1
  33. package/lib/features/fix-all.d.ts +4 -4
  34. package/lib/features/fix-all.d.ts.map +1 -1
  35. package/lib/features/fix-all.js +104 -147
  36. package/lib/features/fix-all.js.map +1 -1
  37. package/lib/features/inlay-hints.d.ts +11 -0
  38. package/lib/features/inlay-hints.d.ts.map +1 -0
  39. package/lib/features/inlay-hints.js +70 -0
  40. package/lib/features/inlay-hints.js.map +1 -0
  41. package/lib/features/source-definition.d.ts +11 -0
  42. package/lib/features/source-definition.d.ts.map +1 -0
  43. package/lib/features/source-definition.js +50 -0
  44. package/lib/features/source-definition.js.map +1 -0
  45. package/lib/file-lsp-server.spec.js +26 -36
  46. package/lib/file-lsp-server.spec.js.map +1 -1
  47. package/lib/hover.d.ts +4 -3
  48. package/lib/hover.d.ts.map +1 -1
  49. package/lib/hover.js +53 -17
  50. package/lib/hover.js.map +1 -1
  51. package/lib/logger.d.ts +12 -4
  52. package/lib/logger.d.ts.map +1 -1
  53. package/lib/logger.js +37 -44
  54. package/lib/logger.js.map +1 -1
  55. package/lib/lsp-client.d.ts +13 -17
  56. package/lib/lsp-client.d.ts.map +1 -1
  57. package/lib/lsp-client.js +32 -91
  58. package/lib/lsp-client.js.map +1 -1
  59. package/lib/lsp-connection.d.ts +1 -1
  60. package/lib/lsp-connection.d.ts.map +1 -1
  61. package/lib/lsp-connection.js +13 -39
  62. package/lib/lsp-connection.js.map +1 -1
  63. package/lib/lsp-protocol.calls.proposed.d.ts +1 -1
  64. package/lib/lsp-protocol.calls.proposed.d.ts.map +1 -1
  65. package/lib/lsp-protocol.calls.proposed.js +7 -32
  66. package/lib/lsp-protocol.calls.proposed.js.map +1 -1
  67. package/lib/lsp-protocol.inlayHints.proposed.d.ts +2 -11
  68. package/lib/lsp-protocol.inlayHints.proposed.d.ts.map +1 -1
  69. package/lib/lsp-protocol.inlayHints.proposed.js +2 -28
  70. package/lib/lsp-protocol.inlayHints.proposed.js.map +1 -1
  71. package/lib/lsp-server.d.ts +27 -28
  72. package/lib/lsp-server.d.ts.map +1 -1
  73. package/lib/lsp-server.js +868 -926
  74. package/lib/lsp-server.js.map +1 -1
  75. package/lib/lsp-server.spec.js +956 -606
  76. package/lib/lsp-server.spec.js.map +1 -1
  77. package/lib/organize-imports.d.ts +3 -3
  78. package/lib/organize-imports.d.ts.map +1 -1
  79. package/lib/organize-imports.js +5 -32
  80. package/lib/organize-imports.js.map +1 -1
  81. package/lib/organize-imports.spec.js +17 -42
  82. package/lib/organize-imports.spec.js.map +1 -1
  83. package/lib/protocol-translation.d.ts +5 -10
  84. package/lib/protocol-translation.d.ts.map +1 -1
  85. package/lib/protocol-translation.js +39 -168
  86. package/lib/protocol-translation.js.map +1 -1
  87. package/lib/quickfix.d.ts +3 -3
  88. package/lib/quickfix.d.ts.map +1 -1
  89. package/lib/quickfix.js +7 -35
  90. package/lib/quickfix.js.map +1 -1
  91. package/lib/refactor.d.ts +2 -2
  92. package/lib/refactor.d.ts.map +1 -1
  93. package/lib/refactor.js +11 -36
  94. package/lib/refactor.js.map +1 -1
  95. package/lib/semantic-tokens.d.ts +1 -1
  96. package/lib/semantic-tokens.d.ts.map +1 -1
  97. package/lib/semantic-tokens.js +1 -5
  98. package/lib/semantic-tokens.js.map +1 -1
  99. package/lib/test-utils.d.ts +11 -5
  100. package/lib/test-utils.d.ts.map +1 -1
  101. package/lib/test-utils.js +137 -120
  102. package/lib/test-utils.js.map +1 -1
  103. package/lib/ts-protocol.d.ts +8 -20
  104. package/lib/ts-protocol.d.ts.map +1 -1
  105. package/lib/ts-protocol.js +4 -31
  106. package/lib/ts-protocol.js.map +1 -1
  107. package/lib/tsp-client.d.ts +46 -43
  108. package/lib/tsp-client.d.ts.map +1 -1
  109. package/lib/tsp-client.js +31 -52
  110. package/lib/tsp-client.js.map +1 -1
  111. package/lib/tsp-client.spec.js +48 -75
  112. package/lib/tsp-client.spec.js.map +1 -1
  113. package/lib/tsp-command-types.d.ts +1 -0
  114. package/lib/tsp-command-types.d.ts.map +1 -1
  115. package/lib/tsp-command-types.js +4 -8
  116. package/lib/tsp-command-types.js.map +1 -1
  117. package/lib/utils/SnippetString.js +1 -4
  118. package/lib/utils/SnippetString.js.map +1 -1
  119. package/lib/utils/api.d.ts +1 -0
  120. package/lib/utils/api.d.ts.map +1 -1
  121. package/lib/utils/api.js +3 -28
  122. package/lib/utils/api.js.map +1 -1
  123. package/lib/utils/configuration.d.ts +2 -2
  124. package/lib/utils/configuration.d.ts.map +1 -1
  125. package/lib/utils/configuration.js +1 -2
  126. package/lib/utils/errorCodes.js +11 -14
  127. package/lib/utils/errorCodes.js.map +1 -1
  128. package/lib/utils/fixNames.js +13 -16
  129. package/lib/utils/fixNames.js.map +1 -1
  130. package/lib/utils/modules-resolver.js +7 -34
  131. package/lib/utils/modules-resolver.js.map +1 -1
  132. package/lib/utils/modules-resolver.spec.d.ts +1 -1
  133. package/lib/utils/modules-resolver.spec.d.ts.map +1 -1
  134. package/lib/utils/modules-resolver.spec.js +11 -34
  135. package/lib/utils/modules-resolver.spec.js.map +1 -1
  136. package/lib/utils/typeConverters.d.ts +20 -2
  137. package/lib/utils/typeConverters.d.ts.map +1 -1
  138. package/lib/utils/typeConverters.js +105 -9
  139. package/lib/utils/typeConverters.js.map +1 -1
  140. package/lib/utils/types.js +2 -29
  141. package/lib/utils/types.js.map +1 -1
  142. package/lib/utils/versionProvider.d.ts +3 -3
  143. package/lib/utils/versionProvider.d.ts.map +1 -1
  144. package/lib/utils/versionProvider.js +52 -60
  145. package/lib/utils/versionProvider.js.map +1 -1
  146. package/lib/utils.d.ts.map +1 -1
  147. package/lib/utils.js +3 -5
  148. package/lib/utils.js.map +1 -1
  149. package/package.json +38 -33
package/lib/lsp-server.js CHANGED
@@ -1,70 +1,37 @@
1
- "use strict";
2
1
  /*
3
2
  * Copyright (C) 2017, 2018 TypeFox and others.
4
3
  *
5
4
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
6
5
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
7
6
  */
8
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
- if (k2 === undefined) k2 = k;
10
- var desc = Object.getOwnPropertyDescriptor(m, k);
11
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
- desc = { enumerable: true, get: function() { return m[k]; } };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- }) : (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- }));
19
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
- Object.defineProperty(o, "default", { enumerable: true, value: v });
21
- }) : function(o, v) {
22
- o["default"] = v;
23
- });
24
- var __importStar = (this && this.__importStar) || function (mod) {
25
- if (mod && mod.__esModule) return mod;
26
- var result = {};
27
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
- __setModuleDefault(result, mod);
29
- return result;
30
- };
31
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
32
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
33
- return new (P || (P = Promise))(function (resolve, reject) {
34
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
35
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
36
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
37
- step((generator = generator.apply(thisArg, _arguments || [])).next());
38
- });
39
- };
40
- var __importDefault = (this && this.__importDefault) || function (mod) {
41
- return (mod && mod.__esModule) ? mod : { "default": mod };
42
- };
43
- Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.LspServer = void 0;
45
- const path = __importStar(require("path"));
46
- const tempy_1 = __importDefault(require("tempy"));
47
- const lsp = __importStar(require("vscode-languageserver/node"));
48
- const lspcalls = __importStar(require("./lsp-protocol.calls.proposed"));
49
- const lspsemanticTokens = __importStar(require("./semantic-tokens"));
50
- const fs = __importStar(require("fs-extra"));
51
- const p_debounce_1 = __importDefault(require("p-debounce"));
52
- const logger_1 = require("./logger");
53
- const tsp_client_1 = require("./tsp-client");
54
- const diagnostic_queue_1 = require("./diagnostic-queue");
55
- const protocol_translation_1 = require("./protocol-translation");
56
- const document_1 = require("./document");
57
- const completion_1 = require("./completion");
58
- const hover_1 = require("./hover");
59
- const commands_1 = require("./commands");
60
- const quickfix_1 = require("./quickfix");
61
- const refactor_1 = require("./refactor");
62
- const organize_imports_1 = require("./organize-imports");
63
- const document_symbol_1 = require("./document-symbol");
64
- const calls_1 = require("./calls");
65
- const versionProvider_1 = require("./utils/versionProvider");
66
- const fix_all_1 = require("./features/fix-all");
67
- const types_1 = require("./utils/types");
7
+ import * as path from 'node:path';
8
+ import fs from 'fs-extra';
9
+ import debounce from 'p-debounce';
10
+ import { temporaryFile } from 'tempy';
11
+ import * as lsp from 'vscode-languageserver';
12
+ import * as lspcalls from './lsp-protocol.calls.proposed.js';
13
+ import * as lspsemanticTokens from './semantic-tokens.js';
14
+ import API from './utils/api.js';
15
+ import { PrefixingLogger } from './logger.js';
16
+ import { TspClient } from './tsp-client.js';
17
+ import { DiagnosticEventQueue } from './diagnostic-queue.js';
18
+ import { toDocumentHighlight, asTagsDocumentation, uriToPath, toSymbolKind, toLocation, pathToUri, toTextEdit, asPlainText, normalizePath } from './protocol-translation.js';
19
+ import { LspDocuments } from './document.js';
20
+ import { asCompletionItem, asResolvedCompletionItem, getCompletionTriggerCharacter } from './completion.js';
21
+ import { asSignatureHelp, toTsTriggerReason } from './hover.js';
22
+ import { Commands } from './commands.js';
23
+ import { provideQuickFix } from './quickfix.js';
24
+ import { provideRefactors } from './refactor.js';
25
+ import { provideOrganizeImports } from './organize-imports.js';
26
+ import { collectDocumentSymbols, collectSymbolInformation } from './document-symbol.js';
27
+ import { computeCallers, computeCallees } from './calls.js';
28
+ import { TypeScriptVersionProvider } from './utils/versionProvider.js';
29
+ import { TypeScriptAutoFixProvider } from './features/fix-all.js';
30
+ import { TypeScriptInlayHintsProvider } from './features/inlay-hints.js';
31
+ import { SourceDefinitionCommand } from './features/source-definition.js';
32
+ import { Position, Range } from './utils/typeConverters.js';
33
+ import { CodeActionKind } from './utils/types.js';
34
+ import { ConfigurationManager } from './configuration-manager.js';
68
35
  class ServerInitializingIndicator {
69
36
  constructor(lspClient) {
70
37
  this.lspClient = lspClient;
@@ -73,47 +40,74 @@ class ServerInitializingIndicator {
73
40
  if (this._loadingProjectName) {
74
41
  this._loadingProjectName = undefined;
75
42
  if (this._progressReporter) {
76
- this._progressReporter.end();
43
+ this._progressReporter.done();
77
44
  this._progressReporter = undefined;
78
45
  }
79
46
  }
80
47
  }
81
- startedLoadingProject(projectName) {
48
+ async startedLoadingProject(projectName) {
82
49
  // TS projects are loaded sequentially. Cancel existing task because it should always be resolved before
83
50
  // the incoming project loading task is.
84
51
  this.reset();
85
52
  this._loadingProjectName = projectName;
86
- this._progressReporter = this.lspClient.createProgressReporter();
53
+ this._progressReporter = await this.lspClient.createProgressReporter();
87
54
  this._progressReporter.begin('Initializing JS/TS language features…');
88
55
  }
89
56
  finishedLoadingProject(projectName) {
90
57
  if (this._loadingProjectName === projectName) {
91
58
  this._loadingProjectName = undefined;
92
59
  if (this._progressReporter) {
93
- this._progressReporter.end();
60
+ this._progressReporter.done();
94
61
  this._progressReporter = undefined;
95
62
  }
96
63
  }
97
64
  }
98
65
  }
99
- class LspServer {
66
+ export class LspServer {
100
67
  constructor(options) {
101
68
  this.options = options;
102
- this.documents = new document_1.LspDocuments();
69
+ this._tspClient = null;
70
+ this._loadingIndicator = null;
71
+ this.initializeParams = null;
72
+ this.typeScriptAutoFixProvider = null;
73
+ this.features = {};
74
+ this.documents = new LspDocuments();
103
75
  // True if diagnostic request is currently debouncing or the request is in progress. False only if there are
104
76
  // no pending requests.
105
77
  this.pendingDebouncedRequest = false;
106
- this.doRequestDiagnosticsDebounced = (0, p_debounce_1.default)(() => this.doRequestDiagnostics(), 200);
107
- this.logger = new logger_1.PrefixingLogger(options.logger, '[lspserver]');
108
- this.workspaceConfiguration = {};
78
+ this.doRequestDiagnosticsDebounced = debounce(() => this.doRequestDiagnostics(), 200);
79
+ this.configurationManager = new ConfigurationManager(this.documents);
80
+ this.logger = new PrefixingLogger(options.logger, '[lspserver]');
109
81
  }
110
82
  closeAll() {
111
83
  for (const file of [...this.documents.files]) {
112
84
  this.closeDocument(file);
113
85
  }
114
86
  }
87
+ shutdown() {
88
+ if (this._tspClient) {
89
+ this._tspClient.shutdown();
90
+ this._tspClient = null;
91
+ }
92
+ if (this._loadingIndicator) {
93
+ this._loadingIndicator.reset();
94
+ this._loadingIndicator = null;
95
+ }
96
+ }
97
+ get tspClient() {
98
+ if (!this._tspClient) {
99
+ throw new Error('TS client not created. Did you forget to send the "initialize" request?');
100
+ }
101
+ return this._tspClient;
102
+ }
103
+ get loadingIndicator() {
104
+ if (!this._loadingIndicator) {
105
+ throw new Error('Loading indicator not created. Did you forget to send the "initialize" request?');
106
+ }
107
+ return this._loadingIndicator;
108
+ }
115
109
  findTypescriptVersion() {
116
- const typescriptVersionProvider = new versionProvider_1.TypeScriptVersionProvider(this.options, this.logger);
110
+ const typescriptVersionProvider = new TypeScriptVersionProvider(this.options, this.logger);
117
111
  // User-provided tsserver path.
118
112
  const userSettingVersion = typescriptVersionProvider.getUserSettingVersion();
119
113
  if (userSettingVersion) {
@@ -136,157 +130,180 @@ class LspServer {
136
130
  }
137
131
  return null;
138
132
  }
139
- initialize(params) {
140
- var _a, _b, _c;
141
- return __awaiter(this, void 0, void 0, function* () {
142
- this.logger.log('initialize', params);
143
- this.initializeParams = params;
144
- const clientCapabilities = this.initializeParams.capabilities;
145
- this.options.lspClient.setClientCapabilites(clientCapabilities);
146
- this.loadingIndicator = new ServerInitializingIndicator(this.options.lspClient);
147
- this.workspaceRoot = this.initializeParams.rootUri ? (0, protocol_translation_1.uriToPath)(this.initializeParams.rootUri) : this.initializeParams.rootPath || undefined;
148
- this.diagnosticQueue = new diagnostic_queue_1.DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.documents, (_a = clientCapabilities.textDocument) === null || _a === void 0 ? void 0 : _a.publishDiagnostics, this.logger);
149
- const userInitializationOptions = this.initializeParams.initializationOptions || {};
150
- const { disableAutomaticTypingAcquisition, hostInfo, maxTsServerMemory, npmLocation, locale } = userInitializationOptions;
151
- const { logVerbosity, plugins, preferences } = {
152
- logVerbosity: userInitializationOptions.logVerbosity || this.options.tsserverLogVerbosity,
153
- plugins: userInitializationOptions.plugins || [],
154
- preferences: Object.assign({ allowIncompleteCompletions: true, allowRenameOfImportPath: true, allowTextChangesInNewFiles: true, displayPartsForJSDoc: true, generateReturnInDocTemplate: true, includeAutomaticOptionalChainCompletions: true, includeCompletionsForImportStatements: true, includeCompletionsForModuleExports: true, includeCompletionsWithClassMemberSnippets: true, includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: true, jsxAttributeCompletionStyle: 'auto', providePrefixAndSuffixTextForRename: true }, userInitializationOptions.preferences)
155
- };
156
- const logFile = this.getLogFile(logVerbosity);
157
- const globalPlugins = [];
158
- const pluginProbeLocations = [];
159
- for (const plugin of plugins) {
160
- globalPlugins.push(plugin.name);
161
- pluginProbeLocations.push(plugin.location);
162
- }
163
- const typescriptVersion = this.findTypescriptVersion();
164
- if (typescriptVersion) {
165
- this.logger.info(`Using Typescript version (${typescriptVersion.source}) ${typescriptVersion.versionString} from path "${typescriptVersion.tsServerPath}"`);
166
- }
167
- else {
168
- throw Error('Could not find a valid tsserver executable in the workspace or in the $PATH. Please ensure that the "typescript" dependency is installed in either location. Exiting.');
133
+ async initialize(params) {
134
+ this.logger.log('initialize', params);
135
+ if (this._tspClient) {
136
+ throw new Error('The "initialize" request has already called before.');
137
+ }
138
+ this.initializeParams = params;
139
+ const clientCapabilities = this.initializeParams.capabilities;
140
+ this._loadingIndicator = new ServerInitializingIndicator(this.options.lspClient);
141
+ this.workspaceRoot = this.initializeParams.rootUri ? uriToPath(this.initializeParams.rootUri) : this.initializeParams.rootPath || undefined;
142
+ const userInitializationOptions = this.initializeParams.initializationOptions || {};
143
+ const { disableAutomaticTypingAcquisition, hostInfo, maxTsServerMemory, npmLocation, locale } = userInitializationOptions;
144
+ const { logVerbosity, plugins } = {
145
+ logVerbosity: userInitializationOptions.logVerbosity || this.options.tsserverLogVerbosity,
146
+ plugins: userInitializationOptions.plugins || [],
147
+ };
148
+ const logFile = this.getLogFile(logVerbosity);
149
+ const globalPlugins = [];
150
+ const pluginProbeLocations = [];
151
+ for (const plugin of plugins) {
152
+ globalPlugins.push(plugin.name);
153
+ pluginProbeLocations.push(plugin.location);
154
+ }
155
+ const typescriptVersion = this.findTypescriptVersion();
156
+ if (typescriptVersion) {
157
+ this.logger.info(`Using Typescript version (${typescriptVersion.source}) ${typescriptVersion.versionString} from path "${typescriptVersion.tsServerPath}"`);
158
+ }
159
+ else {
160
+ throw Error('Could not find a valid TypeScript installation. Please ensure that the "typescript" dependency is installed in the workspace or that a valid --tsserver-path is specified. Exiting.');
161
+ }
162
+ this.configurationManager.mergeTsPreferences(userInitializationOptions.preferences || {});
163
+ // Setup supported features.
164
+ const { textDocument } = clientCapabilities;
165
+ this.features.definitionLinkSupport = textDocument?.definition?.linkSupport && typescriptVersion.version?.gte(API.v270);
166
+ const completionCapabilities = textDocument?.completion;
167
+ if (completionCapabilities?.completionItem) {
168
+ if (this.configurationManager.tsPreferences.useLabelDetailsInCompletionEntries
169
+ && completionCapabilities.completionItem.labelDetailsSupport
170
+ && typescriptVersion.version?.gte(API.v470)) {
171
+ this.features.completionLabelDetails = true;
172
+ }
173
+ if (completionCapabilities.completionItem.snippetSupport) {
174
+ this.features.completionSnippets = true;
175
+ }
176
+ if (textDocument?.publishDiagnostics?.tagSupport) {
177
+ this.features.diagnosticsTagSupport = true;
169
178
  }
170
- this.tspClient = new tsp_client_1.TspClient({
171
- tsserverPath: typescriptVersion.tsServerPath,
172
- logFile,
173
- logVerbosity,
174
- disableAutomaticTypingAcquisition,
175
- maxTsServerMemory,
176
- npmLocation,
177
- locale,
178
- globalPlugins,
179
- pluginProbeLocations,
180
- logger: this.options.logger,
181
- onEvent: this.onTsEvent.bind(this),
182
- onExit: (exitCode, signal) => {
179
+ }
180
+ this.configurationManager.mergeTsPreferences({
181
+ useLabelDetailsInCompletionEntries: this.features.completionLabelDetails,
182
+ });
183
+ this.diagnosticQueue = new DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.documents, this.features, this.logger);
184
+ this._tspClient = new TspClient({
185
+ apiVersion: typescriptVersion.version || API.defaultVersion,
186
+ tsserverPath: typescriptVersion.tsServerPath,
187
+ logFile,
188
+ logVerbosity,
189
+ disableAutomaticTypingAcquisition,
190
+ maxTsServerMemory,
191
+ npmLocation,
192
+ locale,
193
+ globalPlugins,
194
+ pluginProbeLocations,
195
+ logger: this.options.logger,
196
+ onEvent: this.onTsEvent.bind(this),
197
+ onExit: (exitCode, signal) => {
198
+ if (exitCode) {
183
199
  this.logger.error(`tsserver process has exited (exit code: ${exitCode}, signal: ${signal}). Stopping the server.`);
184
- // Allow the log to be dispatched to the client.
185
- setTimeout(() => process.exit(1));
186
- }
187
- });
188
- const started = this.tspClient.start();
189
- if (!started) {
190
- throw new Error('tsserver process has failed to start.');
191
- }
192
- process.on('exit', () => {
193
- this.tspClient.shutdown();
194
- if (this.loadingIndicator) {
195
- this.loadingIndicator.reset();
196
200
  }
197
- });
198
- process.on('SIGINT', () => {
199
- process.exit();
200
- });
201
- this.typeScriptAutoFixProvider = new fix_all_1.TypeScriptAutoFixProvider(this.tspClient);
202
- yield Promise.all([
203
- this.tspClient.request("configure" /* Configure */, Object.assign(Object.assign({}, hostInfo ? { hostInfo } : {}), { formatOptions: {
204
- // We can use \n here since the editor should normalize later on to its line endings.
205
- newLineCharacter: '\n'
206
- }, preferences })),
207
- this.tspClient.request("compilerOptionsForInferredProjects" /* CompilerOptionsForInferredProjects */, {
208
- options: {
209
- module: "CommonJS" /* CommonJS */,
210
- target: "ES2016" /* ES2016 */,
211
- jsx: "Preserve" /* Preserve */,
212
- allowJs: true,
213
- allowSyntheticDefaultImports: true,
214
- allowNonTsExtensions: true
215
- }
216
- })
217
- ]);
218
- const logFileUri = logFile && (0, protocol_translation_1.pathToUri)(logFile, undefined);
219
- this.initializeResult = {
220
- capabilities: {
221
- textDocumentSync: lsp.TextDocumentSyncKind.Incremental,
222
- completionProvider: {
223
- triggerCharacters: ['.', '"', '\'', '/', '@', '<'],
224
- resolveProvider: true
225
- },
226
- codeActionProvider: ((_c = (_b = clientCapabilities.textDocument) === null || _b === void 0 ? void 0 : _b.codeAction) === null || _c === void 0 ? void 0 : _c.codeActionLiteralSupport)
227
- ? { codeActionKinds: [...fix_all_1.TypeScriptAutoFixProvider.kinds.map(kind => kind.value), types_1.CodeActionKind.SourceOrganizeImportsTs.value] } : true,
228
- definitionProvider: true,
229
- documentFormattingProvider: true,
230
- documentRangeFormattingProvider: true,
231
- documentHighlightProvider: true,
232
- documentSymbolProvider: true,
233
- executeCommandProvider: {
234
- commands: [
235
- commands_1.Commands.APPLY_WORKSPACE_EDIT,
236
- commands_1.Commands.APPLY_CODE_ACTION,
237
- commands_1.Commands.APPLY_REFACTORING,
238
- commands_1.Commands.ORGANIZE_IMPORTS,
239
- commands_1.Commands.APPLY_RENAME_FILE
240
- ]
241
- },
242
- hoverProvider: true,
243
- renameProvider: true,
244
- referencesProvider: true,
245
- signatureHelpProvider: {
246
- triggerCharacters: ['(', ',', '<']
201
+ this.shutdown();
202
+ },
203
+ });
204
+ const started = this.tspClient.start();
205
+ if (!started) {
206
+ throw new Error('tsserver process has failed to start.');
207
+ }
208
+ process.on('exit', () => {
209
+ this.shutdown();
210
+ });
211
+ process.on('SIGINT', () => {
212
+ process.exit();
213
+ });
214
+ this.typeScriptAutoFixProvider = new TypeScriptAutoFixProvider(this.tspClient);
215
+ await Promise.all([
216
+ this.configurationManager.setAndConfigureTspClient(this._tspClient, hostInfo),
217
+ this.tspClient.request("compilerOptionsForInferredProjects" /* CommandTypes.CompilerOptionsForInferredProjects */, {
218
+ options: {
219
+ module: "CommonJS" /* tsp.ModuleKind.CommonJS */,
220
+ target: "ES2016" /* tsp.ScriptTarget.ES2016 */,
221
+ jsx: "Preserve" /* tsp.JsxEmit.Preserve */,
222
+ allowJs: true,
223
+ allowSyntheticDefaultImports: true,
224
+ allowNonTsExtensions: true,
225
+ },
226
+ }),
227
+ ]);
228
+ const logFileUri = logFile && pathToUri(logFile, undefined);
229
+ const initializeResult = {
230
+ capabilities: {
231
+ textDocumentSync: lsp.TextDocumentSyncKind.Incremental,
232
+ completionProvider: {
233
+ triggerCharacters: ['.', '"', '\'', '/', '@', '<'],
234
+ resolveProvider: true,
235
+ },
236
+ codeActionProvider: clientCapabilities.textDocument?.codeAction?.codeActionLiteralSupport
237
+ ? { codeActionKinds: [
238
+ ...TypeScriptAutoFixProvider.kinds.map(kind => kind.value),
239
+ CodeActionKind.SourceOrganizeImportsTs.value,
240
+ CodeActionKind.QuickFix.value,
241
+ CodeActionKind.Refactor.value,
242
+ ] } : true,
243
+ definitionProvider: true,
244
+ documentFormattingProvider: true,
245
+ documentRangeFormattingProvider: true,
246
+ documentHighlightProvider: true,
247
+ documentSymbolProvider: true,
248
+ executeCommandProvider: {
249
+ commands: [
250
+ Commands.APPLY_WORKSPACE_EDIT,
251
+ Commands.APPLY_CODE_ACTION,
252
+ Commands.APPLY_REFACTORING,
253
+ Commands.ORGANIZE_IMPORTS,
254
+ Commands.APPLY_RENAME_FILE,
255
+ Commands.SOURCE_DEFINITION,
256
+ ],
257
+ },
258
+ hoverProvider: true,
259
+ inlayHintProvider: true,
260
+ renameProvider: true,
261
+ referencesProvider: true,
262
+ signatureHelpProvider: {
263
+ triggerCharacters: ['(', ',', '<'],
264
+ retriggerCharacters: [')'],
265
+ },
266
+ workspaceSymbolProvider: true,
267
+ implementationProvider: true,
268
+ typeDefinitionProvider: true,
269
+ foldingRangeProvider: true,
270
+ semanticTokensProvider: {
271
+ documentSelector: null,
272
+ legend: {
273
+ // list taken from: https://github.com/microsoft/TypeScript/blob/main/src/services/classifier2020.ts#L10
274
+ tokenTypes: [
275
+ 'class',
276
+ 'enum',
277
+ 'interface',
278
+ 'namespace',
279
+ 'typeParameter',
280
+ 'type',
281
+ 'parameter',
282
+ 'variable',
283
+ 'enumMember',
284
+ 'property',
285
+ 'function',
286
+ 'member',
287
+ ],
288
+ // token from: https://github.com/microsoft/TypeScript/blob/main/src/services/classifier2020.ts#L14
289
+ tokenModifiers: [
290
+ 'declaration',
291
+ 'static',
292
+ 'async',
293
+ 'readonly',
294
+ 'defaultLibrary',
295
+ 'local',
296
+ ],
247
297
  },
248
- workspaceSymbolProvider: true,
249
- implementationProvider: true,
250
- typeDefinitionProvider: true,
251
- foldingRangeProvider: true,
252
- semanticTokensProvider: {
253
- documentSelector: null,
254
- legend: {
255
- // list taken from: https://github.com/microsoft/TypeScript/blob/main/src/services/classifier2020.ts#L10
256
- tokenTypes: [
257
- 'class',
258
- 'enum',
259
- 'interface',
260
- 'namespace',
261
- 'typeParameter',
262
- 'type',
263
- 'parameter',
264
- 'variable',
265
- 'enumMember',
266
- 'property',
267
- 'function',
268
- 'member'
269
- ],
270
- // token from: https://github.com/microsoft/TypeScript/blob/main/src/services/classifier2020.ts#L14
271
- tokenModifiers: [
272
- 'declaration',
273
- 'static',
274
- 'async',
275
- 'readonly',
276
- 'defaultLibrary',
277
- 'local'
278
- ]
279
- },
280
- full: true,
281
- range: true
282
- }
298
+ full: true,
299
+ range: true,
283
300
  },
284
- logFileUri
285
- };
286
- this.initializeResult.capabilities.callsProvider = true;
287
- this.logger.log('onInitialize result', this.initializeResult);
288
- return this.initializeResult;
289
- });
301
+ },
302
+ logFileUri,
303
+ };
304
+ initializeResult.capabilities.callsProvider = true;
305
+ this.logger.log('onInitialize result', initializeResult);
306
+ return initializeResult;
290
307
  }
291
308
  getLogFile(logVerbosity) {
292
309
  if (logVerbosity === undefined || logVerbosity === 'off') {
@@ -297,7 +314,7 @@ class LspServer {
297
314
  fs.ensureFileSync(logFile);
298
315
  return logFile;
299
316
  }
300
- return tempy_1.default.file({ name: 'tsserver.log' });
317
+ return temporaryFile({ name: 'tsserver.log' });
301
318
  }
302
319
  doGetLogFile() {
303
320
  if (process.env.TSSERVER_LOG_FILE) {
@@ -312,19 +329,9 @@ class LspServer {
312
329
  return undefined;
313
330
  }
314
331
  didChangeConfiguration(params) {
315
- var _a, _b;
316
- this.workspaceConfiguration = params.settings || {};
317
- const ignoredDiagnosticCodes = ((_a = this.workspaceConfiguration.diagnostics) === null || _a === void 0 ? void 0 : _a.ignoredCodes) || [];
318
- (_b = this.diagnosticQueue) === null || _b === void 0 ? void 0 : _b.updateIgnoredDiagnosticCodes(ignoredDiagnosticCodes);
319
- }
320
- getWorkspacePreferencesForDocument(file) {
321
- var _a;
322
- const doc = this.documents.get(file);
323
- if (!doc) {
324
- return {};
325
- }
326
- const preferencesKey = doc.languageId.startsWith('typescript') ? 'typescript' : 'javascript';
327
- return (_a = this.workspaceConfiguration[preferencesKey]) !== null && _a !== void 0 ? _a : {};
332
+ this.configurationManager.setWorkspaceConfiguration(params.settings || {});
333
+ const ignoredDiagnosticCodes = this.configurationManager.workspaceConfiguration.diagnostics?.ignoredCodes || [];
334
+ this.diagnosticQueue?.updateIgnoredDiagnosticCodes(ignoredDiagnosticCodes);
328
335
  }
329
336
  interuptDiagnostics(f) {
330
337
  if (!this.diagnosticsTokenSource) {
@@ -335,28 +342,24 @@ class LspServer {
335
342
  this.requestDiagnostics();
336
343
  return result;
337
344
  }
338
- requestDiagnostics() {
339
- return __awaiter(this, void 0, void 0, function* () {
340
- this.pendingDebouncedRequest = true;
341
- yield this.doRequestDiagnosticsDebounced();
342
- });
345
+ async requestDiagnostics() {
346
+ this.pendingDebouncedRequest = true;
347
+ await this.doRequestDiagnosticsDebounced();
343
348
  }
344
- doRequestDiagnostics() {
345
- return __awaiter(this, void 0, void 0, function* () {
346
- this.cancelDiagnostics();
347
- const geterrTokenSource = new lsp.CancellationTokenSource();
348
- this.diagnosticsTokenSource = geterrTokenSource;
349
- const { files } = this.documents;
350
- try {
351
- return yield this.tspClient.request("geterr" /* Geterr */, { delay: 0, files }, this.diagnosticsTokenSource.token);
352
- }
353
- finally {
354
- if (this.diagnosticsTokenSource === geterrTokenSource) {
355
- this.diagnosticsTokenSource = undefined;
356
- this.pendingDebouncedRequest = false;
357
- }
349
+ async doRequestDiagnostics() {
350
+ this.cancelDiagnostics();
351
+ const geterrTokenSource = new lsp.CancellationTokenSource();
352
+ this.diagnosticsTokenSource = geterrTokenSource;
353
+ const { files } = this.documents;
354
+ try {
355
+ return await this.tspClient.request("geterr" /* CommandTypes.Geterr */, { delay: 0, files }, this.diagnosticsTokenSource.token);
356
+ }
357
+ finally {
358
+ if (this.diagnosticsTokenSource === geterrTokenSource) {
359
+ this.diagnosticsTokenSource = undefined;
360
+ this.pendingDebouncedRequest = false;
358
361
  }
359
- });
362
+ }
360
363
  }
361
364
  cancelDiagnostics() {
362
365
  if (this.diagnosticsTokenSource) {
@@ -364,17 +367,17 @@ class LspServer {
364
367
  }
365
368
  }
366
369
  didOpenTextDocument(params) {
367
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
370
+ const file = uriToPath(params.textDocument.uri);
368
371
  this.logger.log('onDidOpenTextDocument', params, file);
369
372
  if (!file) {
370
373
  return;
371
374
  }
372
375
  if (this.documents.open(file, params.textDocument)) {
373
- this.tspClient.notify("open" /* Open */, {
376
+ this.tspClient.notify("open" /* CommandTypes.Open */, {
374
377
  file,
375
378
  fileContent: params.textDocument.text,
376
379
  scriptKindName: this.getScriptKindName(params.textDocument.languageId),
377
- projectRootPath: this.workspaceRoot
380
+ projectRootPath: this.workspaceRoot,
378
381
  });
379
382
  this.requestDiagnostics();
380
383
  }
@@ -384,9 +387,9 @@ class LspServer {
384
387
  textDocument: params.textDocument,
385
388
  contentChanges: [
386
389
  {
387
- text: params.textDocument.text
388
- }
389
- ]
390
+ text: params.textDocument.text,
391
+ },
392
+ ],
390
393
  });
391
394
  }
392
395
  }
@@ -400,7 +403,7 @@ class LspServer {
400
403
  return undefined;
401
404
  }
402
405
  didCloseTextDocument(params) {
403
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
406
+ const file = uriToPath(params.textDocument.uri);
404
407
  this.logger.log('onDidCloseTextDocument', params, file);
405
408
  if (!file) {
406
409
  return;
@@ -412,17 +415,17 @@ class LspServer {
412
415
  if (!document) {
413
416
  return;
414
417
  }
415
- this.tspClient.notify("close" /* Close */, { file });
418
+ this.tspClient.notify("close" /* CommandTypes.Close */, { file });
416
419
  // We won't be updating diagnostics anymore for that file, so clear them
417
420
  // so we don't leave stale ones.
418
421
  this.options.lspClient.publishDiagnostics({
419
422
  uri: document.uri,
420
- diagnostics: []
423
+ diagnostics: [],
421
424
  });
422
425
  }
423
426
  didChangeTextDocument(params) {
424
427
  const { textDocument } = params;
425
- const file = (0, protocol_translation_1.uriToPath)(textDocument.uri);
428
+ const file = uriToPath(textDocument.uri);
426
429
  this.logger.log('onDidChangeTextDocument', params, file);
427
430
  if (!file) {
428
431
  return;
@@ -453,13 +456,13 @@ class LspServer {
453
456
  endLine = endPos.line + 1;
454
457
  endOffset = endPos.character + 1;
455
458
  }
456
- this.tspClient.notify("change" /* Change */, {
459
+ this.tspClient.notify("change" /* CommandTypes.Change */, {
457
460
  file,
458
461
  line,
459
462
  offset,
460
463
  endLine,
461
464
  endOffset,
462
- insertString: change.text
465
+ insertString: change.text,
463
466
  });
464
467
  document.applyEdit(textDocument.version, change);
465
468
  }
@@ -468,76 +471,94 @@ class LspServer {
468
471
  didSaveTextDocument(_params) {
469
472
  // do nothing
470
473
  }
471
- definition(params) {
472
- return __awaiter(this, void 0, void 0, function* () {
473
- // TODO: implement version checking and if semver.gte(version, 270) use `definitionAndBoundSpan` instead
474
- return this.getDefinition({
475
- type: 'definition',
476
- params
477
- });
474
+ async definition(params) {
475
+ return this.getDefinition({
476
+ type: this.features.definitionLinkSupport ? "definitionAndBoundSpan" /* CommandTypes.DefinitionAndBoundSpan */ : "definition" /* CommandTypes.Definition */,
477
+ params,
478
478
  });
479
479
  }
480
- implementation(params) {
481
- return __awaiter(this, void 0, void 0, function* () {
482
- return this.getDefinition({
483
- type: 'implementation',
484
- params
485
- });
480
+ async implementation(params) {
481
+ return this.getSymbolLocations({
482
+ type: "implementation" /* CommandTypes.Implementation */,
483
+ params,
486
484
  });
487
485
  }
488
- typeDefinition(params) {
489
- return __awaiter(this, void 0, void 0, function* () {
490
- return this.getDefinition({
491
- type: 'typeDefinition',
492
- params
493
- });
486
+ async typeDefinition(params) {
487
+ return this.getSymbolLocations({
488
+ type: "typeDefinition" /* CommandTypes.TypeDefinition */,
489
+ params,
494
490
  });
495
491
  }
496
- getDefinition({ type, params }) {
497
- return __awaiter(this, void 0, void 0, function* () {
498
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
499
- this.logger.log(type, params, file);
500
- if (!file) {
501
- return [];
492
+ async getDefinition({ type, params }) {
493
+ const file = uriToPath(params.textDocument.uri);
494
+ this.logger.log(type, params, file);
495
+ if (!file) {
496
+ return undefined;
497
+ }
498
+ if (type === "definitionAndBoundSpan" /* CommandTypes.DefinitionAndBoundSpan */) {
499
+ const args = Position.toFileLocationRequestArgs(file, params.position);
500
+ const response = await this.tspClient.request(type, args);
501
+ if (response.type !== 'response' || !response.body) {
502
+ return undefined;
502
503
  }
503
- const result = yield this.tspClient.request(type, {
504
- file,
505
- line: params.position.line + 1,
506
- offset: params.position.character + 1
504
+ const span = Range.fromTextSpan(response.body.textSpan);
505
+ return response.body.definitions
506
+ .map((location) => {
507
+ const target = toLocation(location, this.documents);
508
+ const targetRange = location.contextStart && location.contextEnd
509
+ ? Range.fromLocations(location.contextStart, location.contextEnd)
510
+ : target.range;
511
+ return {
512
+ originSelectionRange: span,
513
+ targetRange,
514
+ targetUri: target.uri,
515
+ targetSelectionRange: target.range,
516
+ };
507
517
  });
508
- return result.body ? result.body.map(fileSpan => (0, protocol_translation_1.toLocation)(fileSpan, this.documents)) : [];
509
- });
518
+ }
519
+ return this.getSymbolLocations({ type: "definition" /* CommandTypes.Definition */, params });
510
520
  }
511
- documentSymbol(params) {
512
- return __awaiter(this, void 0, void 0, function* () {
513
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
514
- this.logger.log('symbol', params, file);
515
- if (!file) {
516
- return [];
517
- }
518
- const response = yield this.tspClient.request("navtree" /* NavTree */, {
519
- file
520
- });
521
- const tree = response.body;
522
- if (!tree || !tree.childItems) {
523
- return [];
524
- }
525
- if (this.supportHierarchicalDocumentSymbol) {
526
- const symbols = [];
527
- for (const item of tree.childItems) {
528
- (0, document_symbol_1.collectDocumentSymbols)(item, symbols);
529
- }
530
- return symbols;
531
- }
521
+ async getSymbolLocations({ type, params }) {
522
+ const file = uriToPath(params.textDocument.uri);
523
+ this.logger.log(type, params, file);
524
+ if (!file) {
525
+ return [];
526
+ }
527
+ const args = Position.toFileLocationRequestArgs(file, params.position);
528
+ const response = await this.tspClient.request(type, args);
529
+ if (response.type !== 'response' || !response.body) {
530
+ return undefined;
531
+ }
532
+ return response.body.map(fileSpan => toLocation(fileSpan, this.documents));
533
+ }
534
+ async documentSymbol(params) {
535
+ const file = uriToPath(params.textDocument.uri);
536
+ this.logger.log('symbol', params, file);
537
+ if (!file) {
538
+ return [];
539
+ }
540
+ const response = await this.tspClient.request("navtree" /* CommandTypes.NavTree */, {
541
+ file,
542
+ });
543
+ const tree = response.body;
544
+ if (!tree || !tree.childItems) {
545
+ return [];
546
+ }
547
+ if (this.supportHierarchicalDocumentSymbol) {
532
548
  const symbols = [];
533
549
  for (const item of tree.childItems) {
534
- (0, document_symbol_1.collectSymbolInformation)(params.textDocument.uri, item, symbols);
550
+ collectDocumentSymbols(item, symbols);
535
551
  }
536
552
  return symbols;
537
- });
553
+ }
554
+ const symbols = [];
555
+ for (const item of tree.childItems) {
556
+ collectSymbolInformation(params.textDocument.uri, item, symbols);
557
+ }
558
+ return symbols;
538
559
  }
539
560
  get supportHierarchicalDocumentSymbol() {
540
- const textDocument = this.initializeParams.capabilities.textDocument;
561
+ const textDocument = this.initializeParams?.capabilities.textDocument;
541
562
  const documentSymbol = textDocument && textDocument.documentSymbol;
542
563
  return !!documentSymbol && !!documentSymbol.hierarchicalDocumentSymbolSupport;
543
564
  }
@@ -545,541 +566,477 @@ class LspServer {
545
566
  * implemented based on
546
567
  * https://github.com/Microsoft/vscode/blob/master/extensions/typescript-language-features/src/features/completions.ts
547
568
  */
548
- completion(params) {
549
- return __awaiter(this, void 0, void 0, function* () {
550
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
551
- this.logger.log('completion', params, file);
552
- if (!file) {
553
- return lsp.CompletionList.create([]);
554
- }
555
- const document = this.documents.get(file);
556
- if (!document) {
557
- throw new Error('The document should be opened for completion, file: ' + file);
558
- }
559
- try {
560
- const result = yield this.interuptDiagnostics(() => {
561
- var _a, _b;
562
- return this.tspClient.request("completionInfo" /* CompletionInfo */, {
563
- file,
564
- line: params.position.line + 1,
565
- offset: params.position.character + 1,
566
- triggerCharacter: (0, completion_1.getCompletionTriggerCharacter)((_a = params.context) === null || _a === void 0 ? void 0 : _a.triggerCharacter),
567
- triggerKind: (_b = params.context) === null || _b === void 0 ? void 0 : _b.triggerKind
568
- });
569
- });
570
- const { body } = result;
571
- const completions = (body ? body.entries : [])
572
- .filter(entry => entry.kind !== 'warning')
573
- .map(entry => (0, completion_1.asCompletionItem)(entry, file, params.position, document));
574
- return lsp.CompletionList.create(completions, body === null || body === void 0 ? void 0 : body.isIncomplete);
575
- }
576
- catch (error) {
577
- if (error.message === 'No content available.') {
578
- this.logger.info('No content was available for completion request');
579
- return null;
569
+ async completion(params) {
570
+ const file = uriToPath(params.textDocument.uri);
571
+ this.logger.log('completion', params, file);
572
+ if (!file) {
573
+ return lsp.CompletionList.create([]);
574
+ }
575
+ const document = this.documents.get(file);
576
+ if (!document) {
577
+ throw new Error('The document should be opened for completion, file: ' + file);
578
+ }
579
+ try {
580
+ const result = await this.interuptDiagnostics(() => this.tspClient.request("completionInfo" /* CommandTypes.CompletionInfo */, {
581
+ file,
582
+ line: params.position.line + 1,
583
+ offset: params.position.character + 1,
584
+ triggerCharacter: getCompletionTriggerCharacter(params.context?.triggerCharacter),
585
+ triggerKind: params.context?.triggerKind,
586
+ }));
587
+ const { body } = result;
588
+ const completions = [];
589
+ for (const entry of body?.entries ?? []) {
590
+ if (entry.kind === 'warning') {
591
+ continue;
580
592
  }
581
- else {
582
- throw error;
593
+ const completion = asCompletionItem(entry, file, params.position, document, this.features);
594
+ if (!completion) {
595
+ continue;
583
596
  }
597
+ completions.push(completion);
584
598
  }
585
- });
586
- }
587
- completionResolve(item) {
588
- return __awaiter(this, void 0, void 0, function* () {
589
- this.logger.log('completion/resolve', item);
590
- yield this.tspClient.request("configure" /* Configure */, {
591
- formatOptions: this.getWorkspacePreferencesForDocument(item.data.file).format
592
- });
593
- const { body } = yield this.interuptDiagnostics(() => this.tspClient.request("completionEntryDetails" /* CompletionDetails */, item.data));
594
- const details = body && body.length && body[0];
595
- if (!details) {
596
- return item;
597
- }
598
- return (0, completion_1.asResolvedCompletionItem)(item, details, this.tspClient, this.workspaceConfiguration.completions || {});
599
- });
600
- }
601
- hover(params) {
602
- return __awaiter(this, void 0, void 0, function* () {
603
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
604
- this.logger.log('hover', params, file);
605
- if (!file) {
606
- return { contents: [] };
607
- }
608
- const result = yield this.interuptDiagnostics(() => this.getQuickInfo(file, params.position));
609
- if (!result || !result.body) {
610
- return { contents: [] };
599
+ return lsp.CompletionList.create(completions, body?.isIncomplete);
600
+ }
601
+ catch (error) {
602
+ if (error.message === 'No content available.') {
603
+ this.logger.info('No content was available for completion request');
604
+ return null;
611
605
  }
612
- const range = (0, protocol_translation_1.asRange)(result.body);
613
- const contents = [];
614
- if (result.body.displayString) {
615
- contents.push({ language: 'typescript', value: result.body.displayString });
606
+ else {
607
+ throw error;
616
608
  }
617
- const tags = (0, protocol_translation_1.asTagsDocumentation)(result.body.tags);
618
- const documentation = (0, protocol_translation_1.asPlainText)(result.body.documentation);
619
- contents.push(documentation + (tags ? '\n\n' + tags : ''));
620
- return {
621
- contents,
622
- range
623
- };
624
- });
609
+ }
625
610
  }
626
- getQuickInfo(file, position) {
627
- return __awaiter(this, void 0, void 0, function* () {
628
- try {
629
- return yield this.tspClient.request("quickinfo" /* Quickinfo */, {
630
- file,
631
- line: position.line + 1,
632
- offset: position.character + 1
633
- });
634
- }
635
- catch (err) {
636
- return undefined;
637
- }
638
- });
611
+ async completionResolve(item) {
612
+ this.logger.log('completion/resolve', item);
613
+ await this.configurationManager.configureGloballyFromDocument(item.data.file);
614
+ const { body } = await this.interuptDiagnostics(() => this.tspClient.request("completionEntryDetails" /* CommandTypes.CompletionDetails */, item.data));
615
+ const details = body && body.length && body[0];
616
+ if (!details) {
617
+ return item;
618
+ }
619
+ return asResolvedCompletionItem(item, details, this.tspClient, this.configurationManager.workspaceConfiguration.completions || {}, this.features);
639
620
  }
640
- rename(params) {
641
- return __awaiter(this, void 0, void 0, function* () {
642
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
643
- this.logger.log('onRename', params, file);
644
- if (!file) {
645
- return undefined;
646
- }
647
- const result = yield this.tspClient.request("rename" /* Rename */, {
621
+ async hover(params) {
622
+ const file = uriToPath(params.textDocument.uri);
623
+ this.logger.log('hover', params, file);
624
+ if (!file) {
625
+ return { contents: [] };
626
+ }
627
+ const result = await this.interuptDiagnostics(() => this.getQuickInfo(file, params.position));
628
+ if (!result || !result.body) {
629
+ return { contents: [] };
630
+ }
631
+ const range = Range.fromTextSpan(result.body);
632
+ const contents = [];
633
+ if (result.body.displayString) {
634
+ contents.push({ language: 'typescript', value: result.body.displayString });
635
+ }
636
+ const tags = asTagsDocumentation(result.body.tags);
637
+ const documentation = asPlainText(result.body.documentation);
638
+ contents.push(documentation + (tags ? '\n\n' + tags : ''));
639
+ return {
640
+ contents,
641
+ range,
642
+ };
643
+ }
644
+ async getQuickInfo(file, position) {
645
+ try {
646
+ return await this.tspClient.request("quickinfo" /* CommandTypes.Quickinfo */, {
648
647
  file,
649
- line: params.position.line + 1,
650
- offset: params.position.character + 1
648
+ line: position.line + 1,
649
+ offset: position.character + 1,
651
650
  });
652
- if (!result.body || !result.body.info.canRename || result.body.locs.length === 0) {
653
- return undefined;
654
- }
655
- const workspaceEdit = {
656
- changes: {}
657
- };
658
- result.body.locs
659
- .forEach((spanGroup) => {
660
- const uri = (0, protocol_translation_1.pathToUri)(spanGroup.file, this.documents), textEdits = workspaceEdit.changes[uri] || (workspaceEdit.changes[uri] = []);
661
- spanGroup.locs.forEach((textSpan) => {
662
- textEdits.push({
663
- newText: `${textSpan.prefixText || ''}${params.newName}${textSpan.suffixText || ''}`,
664
- range: {
665
- start: (0, protocol_translation_1.toPosition)(textSpan.start),
666
- end: (0, protocol_translation_1.toPosition)(textSpan.end)
667
- }
668
- });
651
+ }
652
+ catch (err) {
653
+ return undefined;
654
+ }
655
+ }
656
+ async rename(params) {
657
+ const file = uriToPath(params.textDocument.uri);
658
+ this.logger.log('onRename', params, file);
659
+ if (!file) {
660
+ return undefined;
661
+ }
662
+ const result = await this.tspClient.request("rename" /* CommandTypes.Rename */, {
663
+ file,
664
+ line: params.position.line + 1,
665
+ offset: params.position.character + 1,
666
+ });
667
+ if (!result.body || !result.body.info.canRename || result.body.locs.length === 0) {
668
+ return undefined;
669
+ }
670
+ const workspaceEdit = {};
671
+ result.body.locs
672
+ .forEach((spanGroup) => {
673
+ const uri = pathToUri(spanGroup.file, this.documents);
674
+ if (!workspaceEdit.changes) {
675
+ workspaceEdit.changes = {};
676
+ }
677
+ const textEdits = workspaceEdit.changes[uri] || (workspaceEdit.changes[uri] = []);
678
+ spanGroup.locs.forEach((textSpan) => {
679
+ textEdits.push({
680
+ newText: `${textSpan.prefixText || ''}${params.newName}${textSpan.suffixText || ''}`,
681
+ range: {
682
+ start: Position.fromLocation(textSpan.start),
683
+ end: Position.fromLocation(textSpan.end),
684
+ },
669
685
  });
670
686
  });
671
- return workspaceEdit;
672
687
  });
688
+ return workspaceEdit;
673
689
  }
674
- references(params) {
675
- return __awaiter(this, void 0, void 0, function* () {
676
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
677
- this.logger.log('onReferences', params, file);
678
- if (!file) {
679
- return [];
680
- }
681
- const result = yield this.tspClient.request("references" /* References */, {
682
- file,
683
- line: params.position.line + 1,
684
- offset: params.position.character + 1
685
- });
686
- if (!result.body) {
687
- return [];
688
- }
689
- return result.body.refs
690
- .filter(fileSpan => params.context.includeDeclaration || !fileSpan.isDefinition)
691
- .map(fileSpan => (0, protocol_translation_1.toLocation)(fileSpan, this.documents));
690
+ async references(params) {
691
+ const file = uriToPath(params.textDocument.uri);
692
+ this.logger.log('onReferences', params, file);
693
+ if (!file) {
694
+ return [];
695
+ }
696
+ const result = await this.tspClient.request("references" /* CommandTypes.References */, {
697
+ file,
698
+ line: params.position.line + 1,
699
+ offset: params.position.character + 1,
692
700
  });
701
+ if (!result.body) {
702
+ return [];
703
+ }
704
+ return result.body.refs
705
+ .filter(fileSpan => params.context.includeDeclaration || !fileSpan.isDefinition)
706
+ .map(fileSpan => toLocation(fileSpan, this.documents));
693
707
  }
694
- documentFormatting(params) {
695
- return __awaiter(this, void 0, void 0, function* () {
696
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
697
- this.logger.log('documentFormatting', params, file);
698
- if (!file) {
699
- return [];
700
- }
701
- const formatOptions = this.getFormattingOptions(file, params.options);
702
- // options are not yet supported in tsserver, but we can send a configure request first
703
- yield this.tspClient.request("configure" /* Configure */, {
704
- formatOptions
705
- });
706
- const response = yield this.tspClient.request("format" /* Format */, {
707
- file,
708
- line: 1,
709
- offset: 1,
710
- endLine: Number.MAX_SAFE_INTEGER,
711
- endOffset: Number.MAX_SAFE_INTEGER,
712
- options: formatOptions
713
- });
714
- if (response.body) {
715
- return response.body.map(e => (0, protocol_translation_1.toTextEdit)(e));
716
- }
708
+ async documentFormatting(params) {
709
+ const file = uriToPath(params.textDocument.uri);
710
+ this.logger.log('documentFormatting', params, file);
711
+ if (!file) {
717
712
  return [];
713
+ }
714
+ const formatOptions = params.options;
715
+ await this.configurationManager.configureGloballyFromDocument(file, formatOptions);
716
+ const response = await this.tspClient.request("format" /* CommandTypes.Format */, {
717
+ file,
718
+ line: 1,
719
+ offset: 1,
720
+ endLine: Number.MAX_SAFE_INTEGER,
721
+ endOffset: Number.MAX_SAFE_INTEGER,
722
+ options: formatOptions,
718
723
  });
724
+ if (response.body) {
725
+ return response.body.map(e => toTextEdit(e));
726
+ }
727
+ return [];
719
728
  }
720
- documentRangeFormatting(params) {
721
- return __awaiter(this, void 0, void 0, function* () {
722
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
723
- this.logger.log('documentRangeFormatting', params, file);
724
- if (!file) {
725
- return [];
726
- }
727
- const formatOptions = this.getFormattingOptions(file, params.options);
728
- // options are not yet supported in tsserver, but we can send a configure request first
729
- yield this.tspClient.request("configure" /* Configure */, {
730
- formatOptions
731
- });
732
- const response = yield this.tspClient.request("format" /* Format */, {
733
- file,
734
- line: params.range.start.line + 1,
735
- offset: params.range.start.character + 1,
736
- endLine: params.range.end.line + 1,
737
- endOffset: params.range.end.character + 1,
738
- options: formatOptions
739
- });
740
- if (response.body) {
741
- return response.body.map(e => (0, protocol_translation_1.toTextEdit)(e));
742
- }
729
+ async documentRangeFormatting(params) {
730
+ const file = uriToPath(params.textDocument.uri);
731
+ this.logger.log('documentRangeFormatting', params, file);
732
+ if (!file) {
743
733
  return [];
734
+ }
735
+ const formatOptions = params.options;
736
+ await this.configurationManager.configureGloballyFromDocument(file, formatOptions);
737
+ const response = await this.tspClient.request("format" /* CommandTypes.Format */, {
738
+ file,
739
+ line: params.range.start.line + 1,
740
+ offset: params.range.start.character + 1,
741
+ endLine: params.range.end.line + 1,
742
+ endOffset: params.range.end.character + 1,
743
+ options: formatOptions,
744
744
  });
745
- }
746
- getFormattingOptions(file, requestOptions) {
747
- const workspacePreference = this.getWorkspacePreferencesForDocument(file);
748
- let opts = Object.assign(Object.assign({}, (workspacePreference === null || workspacePreference === void 0 ? void 0 : workspacePreference.format) || {}), requestOptions);
749
- // translate
750
- if (opts.convertTabsToSpaces === undefined) {
751
- opts.convertTabsToSpaces = requestOptions.insertSpaces;
745
+ if (response.body) {
746
+ return response.body.map(e => toTextEdit(e));
752
747
  }
753
- if (opts.indentSize === undefined) {
754
- opts.indentSize = requestOptions.tabSize;
748
+ return [];
749
+ }
750
+ async signatureHelp(params) {
751
+ const file = uriToPath(params.textDocument.uri);
752
+ this.logger.log('signatureHelp', params, file);
753
+ if (!file) {
754
+ return undefined;
755
755
  }
756
- if (this.workspaceRoot) {
757
- try {
758
- opts = JSON.parse(fs.readFileSync(this.workspaceRoot + '/tsfmt.json', 'utf-8'));
759
- }
760
- catch (err) {
761
- this.logger.log(`No formatting options found ${err}`);
762
- }
756
+ const response = await this.interuptDiagnostics(() => this.getSignatureHelp(file, params));
757
+ if (!response || !response.body) {
758
+ return undefined;
763
759
  }
764
- return opts;
765
- }
766
- signatureHelp(params) {
767
- return __awaiter(this, void 0, void 0, function* () {
768
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
769
- this.logger.log('signatureHelp', params, file);
770
- if (!file) {
771
- return undefined;
772
- }
773
- const response = yield this.interuptDiagnostics(() => this.getSignatureHelp(file, params.position));
774
- if (!response || !response.body) {
775
- return undefined;
776
- }
777
- return (0, hover_1.asSignatureHelp)(response.body);
778
- });
760
+ return asSignatureHelp(response.body, params.context);
779
761
  }
780
- getSignatureHelp(file, position) {
781
- return __awaiter(this, void 0, void 0, function* () {
782
- try {
783
- return yield this.tspClient.request("signatureHelp" /* SignatureHelp */, {
784
- file,
785
- line: position.line + 1,
786
- offset: position.character + 1
787
- });
788
- }
789
- catch (err) {
790
- return undefined;
791
- }
792
- });
762
+ async getSignatureHelp(file, params) {
763
+ try {
764
+ const { position, context } = params;
765
+ return await this.tspClient.request("signatureHelp" /* CommandTypes.SignatureHelp */, {
766
+ file,
767
+ line: position.line + 1,
768
+ offset: position.character + 1,
769
+ triggerReason: context ? toTsTriggerReason(context) : undefined,
770
+ });
771
+ }
772
+ catch (err) {
773
+ return undefined;
774
+ }
793
775
  }
794
- codeAction(params) {
795
- var _a, _b;
796
- return __awaiter(this, void 0, void 0, function* () {
797
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
798
- this.logger.log('codeAction', params, file);
799
- if (!file) {
800
- return [];
801
- }
802
- const args = (0, protocol_translation_1.toFileRangeRequestArgs)(file, params.range);
803
- const actions = [];
804
- const kinds = (_a = params.context.only) === null || _a === void 0 ? void 0 : _a.map(kind => new types_1.CodeActionKind(kind));
805
- if (!kinds || kinds.some(kind => kind.contains(types_1.CodeActionKind.QuickFix))) {
806
- const errorCodes = params.context.diagnostics.map(diagnostic => Number(diagnostic.code));
807
- actions.push(...(0, quickfix_1.provideQuickFix)(yield this.getCodeFixes(Object.assign(Object.assign({}, args), { errorCodes })), this.documents));
808
- }
809
- if (!kinds || kinds.some(kind => kind.contains(types_1.CodeActionKind.Refactor))) {
810
- actions.push(...(0, refactor_1.provideRefactors)(yield this.getRefactors(args), args));
811
- }
812
- // organize import is provided by tsserver for any line, so we only get it if explicitly requested
813
- if (kinds === null || kinds === void 0 ? void 0 : kinds.some(kind => kind.contains(types_1.CodeActionKind.SourceOrganizeImportsTs))) {
814
- // see this issue for more context about how this argument is used
815
- // https://github.com/microsoft/TypeScript/issues/43051
816
- const skipDestructiveCodeActions = params.context.diagnostics.some(
817
- // assume no severity is an error
818
- d => { var _a; return ((_a = d.severity) !== null && _a !== void 0 ? _a : 0) <= 2; });
819
- const response = yield this.getOrganizeImports({
820
- scope: { type: 'file', args },
821
- skipDestructiveCodeActions
822
- });
823
- actions.push(...(0, organize_imports_1.provideOrganizeImports)(response, this.documents));
824
- }
825
- // TODO: Since we rely on diagnostics pointing at errors in the correct places, we can't proceed if we are not
826
- // sure that diagnostics are up-to-date. Thus we check `pendingDebouncedRequest` to see if there are *any*
827
- // pending diagnostic requests (regardless of for which file).
828
- // In general would be better to replace the whole diagnostics handling logic with the one from
829
- // bufferSyncSupport.ts in VSCode's typescript language features.
830
- if (kinds && !this.pendingDebouncedRequest) {
831
- const diagnostics = ((_b = this.diagnosticQueue) === null || _b === void 0 ? void 0 : _b.getDiagnosticsForFile(file)) || [];
832
- if (diagnostics.length) {
833
- actions.push(...yield this.typeScriptAutoFixProvider.provideCodeActions(kinds, file, diagnostics, this.documents));
834
- }
776
+ async codeAction(params) {
777
+ const file = uriToPath(params.textDocument.uri);
778
+ this.logger.log('codeAction', params, file);
779
+ if (!file) {
780
+ return [];
781
+ }
782
+ const args = Range.toFileRangeRequestArgs(file, params.range);
783
+ const actions = [];
784
+ const kinds = params.context.only?.map(kind => new CodeActionKind(kind));
785
+ if (!kinds || kinds.some(kind => kind.contains(CodeActionKind.QuickFix))) {
786
+ const errorCodes = params.context.diagnostics.map(diagnostic => Number(diagnostic.code));
787
+ actions.push(...provideQuickFix(await this.getCodeFixes({ ...args, errorCodes }), this.documents));
788
+ }
789
+ if (!kinds || kinds.some(kind => kind.contains(CodeActionKind.Refactor))) {
790
+ actions.push(...provideRefactors(await this.getRefactors(args), args));
791
+ }
792
+ // organize import is provided by tsserver for any line, so we only get it if explicitly requested
793
+ if (kinds?.some(kind => kind.contains(CodeActionKind.SourceOrganizeImportsTs))) {
794
+ // see this issue for more context about how this argument is used
795
+ // https://github.com/microsoft/TypeScript/issues/43051
796
+ const skipDestructiveCodeActions = params.context.diagnostics.some(
797
+ // assume no severity is an error
798
+ d => (d.severity ?? 0) <= 2);
799
+ const response = await this.getOrganizeImports({
800
+ scope: { type: 'file', args },
801
+ skipDestructiveCodeActions,
802
+ });
803
+ actions.push(...provideOrganizeImports(response, this.documents));
804
+ }
805
+ // TODO: Since we rely on diagnostics pointing at errors in the correct places, we can't proceed if we are not
806
+ // sure that diagnostics are up-to-date. Thus we check `pendingDebouncedRequest` to see if there are *any*
807
+ // pending diagnostic requests (regardless of for which file).
808
+ // In general would be better to replace the whole diagnostics handling logic with the one from
809
+ // bufferSyncSupport.ts in VSCode's typescript language features.
810
+ if (kinds && !this.pendingDebouncedRequest) {
811
+ const diagnostics = this.diagnosticQueue?.getDiagnosticsForFile(file) || [];
812
+ if (diagnostics.length) {
813
+ actions.push(...await this.typeScriptAutoFixProvider.provideCodeActions(kinds, file, diagnostics, this.documents));
835
814
  }
836
- return actions;
837
- });
815
+ }
816
+ return actions;
838
817
  }
839
- getCodeFixes(args) {
840
- return __awaiter(this, void 0, void 0, function* () {
841
- try {
842
- return yield this.tspClient.request("getCodeFixes" /* GetCodeFixes */, args);
843
- }
844
- catch (err) {
845
- return undefined;
846
- }
847
- });
818
+ async getCodeFixes(args) {
819
+ try {
820
+ return await this.tspClient.request("getCodeFixes" /* CommandTypes.GetCodeFixes */, args);
821
+ }
822
+ catch (err) {
823
+ return undefined;
824
+ }
848
825
  }
849
- getRefactors(args) {
850
- return __awaiter(this, void 0, void 0, function* () {
851
- try {
852
- return yield this.tspClient.request("getApplicableRefactors" /* GetApplicableRefactors */, args);
853
- }
854
- catch (err) {
855
- return undefined;
856
- }
857
- });
826
+ async getRefactors(args) {
827
+ try {
828
+ return await this.tspClient.request("getApplicableRefactors" /* CommandTypes.GetApplicableRefactors */, args);
829
+ }
830
+ catch (err) {
831
+ return undefined;
832
+ }
858
833
  }
859
- getOrganizeImports(args) {
860
- return __awaiter(this, void 0, void 0, function* () {
861
- try {
862
- // Pass format options to organize imports
863
- yield this.tspClient.request("configure" /* Configure */, {
864
- formatOptions: this.getWorkspacePreferencesForDocument(args.scope.args.file).format
865
- });
866
- return yield this.tspClient.request("organizeImports" /* OrganizeImports */, args);
867
- }
868
- catch (err) {
869
- return undefined;
870
- }
871
- });
834
+ async getOrganizeImports(args) {
835
+ try {
836
+ await this.configurationManager.configureGloballyFromDocument(args.scope.args.file);
837
+ return await this.tspClient.request("organizeImports" /* CommandTypes.OrganizeImports */, args);
838
+ }
839
+ catch (err) {
840
+ return undefined;
841
+ }
872
842
  }
873
- executeCommand(arg) {
874
- return __awaiter(this, void 0, void 0, function* () {
875
- this.logger.log('executeCommand', arg);
876
- if (arg.command === commands_1.Commands.APPLY_WORKSPACE_EDIT && arg.arguments) {
877
- const edit = arg.arguments[0];
878
- yield this.options.lspClient.applyWorkspaceEdit({
879
- edit
880
- });
881
- }
882
- else if (arg.command === commands_1.Commands.APPLY_CODE_ACTION && arg.arguments) {
883
- const codeAction = arg.arguments[0];
884
- if (!(yield this.applyFileCodeEdits(codeAction.changes))) {
885
- return;
886
- }
887
- if (codeAction.commands && codeAction.commands.length) {
888
- for (const command of codeAction.commands) {
889
- yield this.tspClient.request("applyCodeActionCommand" /* ApplyCodeActionCommand */, { command });
890
- }
891
- }
892
- }
893
- else if (arg.command === commands_1.Commands.APPLY_REFACTORING && arg.arguments) {
894
- const args = arg.arguments[0];
895
- const { body } = yield this.tspClient.request("getEditsForRefactor" /* GetEditsForRefactor */, args);
896
- if (!body || !body.edits.length) {
897
- return;
898
- }
899
- for (const edit of body.edits) {
900
- yield fs.ensureFile(edit.fileName);
901
- }
902
- if (!(yield this.applyFileCodeEdits(body.edits))) {
903
- return;
904
- }
905
- const renameLocation = body.renameLocation;
906
- if (renameLocation) {
907
- yield this.options.lspClient.rename({
908
- textDocument: {
909
- uri: (0, protocol_translation_1.pathToUri)(args.file, this.documents)
910
- },
911
- position: (0, protocol_translation_1.toPosition)(renameLocation)
912
- });
843
+ async executeCommand(arg, token, workDoneProgress) {
844
+ this.logger.log('executeCommand', arg);
845
+ if (arg.command === Commands.APPLY_WORKSPACE_EDIT && arg.arguments) {
846
+ const edit = arg.arguments[0];
847
+ await this.options.lspClient.applyWorkspaceEdit({ edit });
848
+ }
849
+ else if (arg.command === Commands.APPLY_CODE_ACTION && arg.arguments) {
850
+ const codeAction = arg.arguments[0];
851
+ if (!await this.applyFileCodeEdits(codeAction.changes)) {
852
+ return;
853
+ }
854
+ if (codeAction.commands && codeAction.commands.length) {
855
+ for (const command of codeAction.commands) {
856
+ await this.tspClient.request("applyCodeActionCommand" /* CommandTypes.ApplyCodeActionCommand */, { command });
913
857
  }
914
858
  }
915
- else if (arg.command === commands_1.Commands.ORGANIZE_IMPORTS && arg.arguments) {
916
- const file = arg.arguments[0];
917
- const additionalArguments = arg.arguments[1] || {};
918
- yield this.tspClient.request("configure" /* Configure */, {
919
- formatOptions: this.getWorkspacePreferencesForDocument(file).format
920
- });
921
- const { body } = yield this.tspClient.request("organizeImports" /* OrganizeImports */, {
922
- scope: {
923
- type: 'file',
924
- args: { file }
859
+ }
860
+ else if (arg.command === Commands.APPLY_REFACTORING && arg.arguments) {
861
+ const args = arg.arguments[0];
862
+ const { body } = await this.tspClient.request("getEditsForRefactor" /* CommandTypes.GetEditsForRefactor */, args);
863
+ if (!body || !body.edits.length) {
864
+ return;
865
+ }
866
+ for (const edit of body.edits) {
867
+ await fs.ensureFile(edit.fileName);
868
+ }
869
+ if (!await this.applyFileCodeEdits(body.edits)) {
870
+ return;
871
+ }
872
+ const renameLocation = body.renameLocation;
873
+ if (renameLocation) {
874
+ await this.options.lspClient.rename({
875
+ textDocument: {
876
+ uri: pathToUri(args.file, this.documents),
925
877
  },
926
- skipDestructiveCodeActions: additionalArguments.skipDestructiveCodeActions
878
+ position: Position.fromLocation(renameLocation),
927
879
  });
928
- yield this.applyFileCodeEdits(body);
929
880
  }
930
- else if (arg.command === commands_1.Commands.APPLY_RENAME_FILE && arg.arguments) {
931
- const { sourceUri, targetUri } = arg.arguments[0];
932
- this.applyRenameFile(sourceUri, targetUri);
933
- }
934
- else if (arg.command === commands_1.Commands.APPLY_COMPLETION_CODE_ACTION && arg.arguments) {
935
- const [_, codeActions] = arg.arguments;
936
- for (const codeAction of codeActions) {
937
- yield this.applyFileCodeEdits(codeAction.changes);
938
- if (codeAction.commands && codeAction.commands.length) {
939
- for (const command of codeAction.commands) {
940
- yield this.tspClient.request("applyCodeActionCommand" /* ApplyCodeActionCommand */, { command });
941
- }
881
+ }
882
+ else if (arg.command === Commands.ORGANIZE_IMPORTS && arg.arguments) {
883
+ const file = arg.arguments[0];
884
+ const additionalArguments = arg.arguments[1] || {};
885
+ await this.configurationManager.configureGloballyFromDocument(file);
886
+ const { body } = await this.tspClient.request("organizeImports" /* CommandTypes.OrganizeImports */, {
887
+ scope: {
888
+ type: 'file',
889
+ args: { file },
890
+ },
891
+ skipDestructiveCodeActions: additionalArguments.skipDestructiveCodeActions,
892
+ });
893
+ await this.applyFileCodeEdits(body);
894
+ }
895
+ else if (arg.command === Commands.APPLY_RENAME_FILE && arg.arguments) {
896
+ const { sourceUri, targetUri } = arg.arguments[0];
897
+ this.applyRenameFile(sourceUri, targetUri);
898
+ }
899
+ else if (arg.command === Commands.APPLY_COMPLETION_CODE_ACTION && arg.arguments) {
900
+ const [_, codeActions] = arg.arguments;
901
+ for (const codeAction of codeActions) {
902
+ await this.applyFileCodeEdits(codeAction.changes);
903
+ if (codeAction.commands && codeAction.commands.length) {
904
+ for (const command of codeAction.commands) {
905
+ await this.tspClient.request("applyCodeActionCommand" /* CommandTypes.ApplyCodeActionCommand */, { command });
942
906
  }
943
- // Execute only the first code action.
944
- break;
945
907
  }
908
+ // Execute only the first code action.
909
+ break;
946
910
  }
947
- else {
948
- this.logger.error(`Unknown command ${arg.command}.`);
949
- }
950
- });
911
+ }
912
+ else if (arg.command === Commands.SOURCE_DEFINITION) {
913
+ const [uri, position] = (arg.arguments || []);
914
+ const reporter = await this.options.lspClient.createProgressReporter(token, workDoneProgress);
915
+ return SourceDefinitionCommand.execute(uri, position, this.documents, this.tspClient, this.options.lspClient, reporter);
916
+ }
917
+ else {
918
+ this.logger.error(`Unknown command ${arg.command}.`);
919
+ }
951
920
  }
952
- applyFileCodeEdits(edits) {
953
- return __awaiter(this, void 0, void 0, function* () {
954
- if (!edits.length) {
955
- return false;
956
- }
957
- const changes = {};
958
- for (const edit of edits) {
959
- changes[(0, protocol_translation_1.pathToUri)(edit.fileName, this.documents)] = edit.textChanges.map(protocol_translation_1.toTextEdit);
960
- }
961
- const { applied } = yield this.options.lspClient.applyWorkspaceEdit({
962
- edit: { changes }
963
- });
964
- return applied;
921
+ async applyFileCodeEdits(edits) {
922
+ if (!edits.length) {
923
+ return false;
924
+ }
925
+ const changes = {};
926
+ for (const edit of edits) {
927
+ changes[pathToUri(edit.fileName, this.documents)] = edit.textChanges.map(toTextEdit);
928
+ }
929
+ const { applied } = await this.options.lspClient.applyWorkspaceEdit({
930
+ edit: { changes },
965
931
  });
932
+ return applied;
966
933
  }
967
- applyRenameFile(sourceUri, targetUri) {
968
- return __awaiter(this, void 0, void 0, function* () {
969
- const edits = yield this.getEditsForFileRename(sourceUri, targetUri);
970
- this.applyFileCodeEdits(edits);
971
- });
934
+ async applyRenameFile(sourceUri, targetUri) {
935
+ const edits = await this.getEditsForFileRename(sourceUri, targetUri);
936
+ this.applyFileCodeEdits(edits);
972
937
  }
973
- getEditsForFileRename(sourceUri, targetUri) {
974
- return __awaiter(this, void 0, void 0, function* () {
975
- const newFilePath = (0, protocol_translation_1.uriToPath)(targetUri);
976
- const oldFilePath = (0, protocol_translation_1.uriToPath)(sourceUri);
977
- if (!newFilePath || !oldFilePath) {
978
- return [];
979
- }
980
- try {
981
- const { body } = yield this.tspClient.request("getEditsForFileRename" /* GetEditsForFileRename */, {
982
- oldFilePath,
983
- newFilePath
984
- });
985
- return body;
986
- }
987
- catch (err) {
988
- return [];
989
- }
990
- });
938
+ async getEditsForFileRename(sourceUri, targetUri) {
939
+ const newFilePath = uriToPath(targetUri);
940
+ const oldFilePath = uriToPath(sourceUri);
941
+ if (!newFilePath || !oldFilePath) {
942
+ return [];
943
+ }
944
+ try {
945
+ const { body } = await this.tspClient.request("getEditsForFileRename" /* CommandTypes.GetEditsForFileRename */, {
946
+ oldFilePath,
947
+ newFilePath,
948
+ });
949
+ return body;
950
+ }
951
+ catch (err) {
952
+ return [];
953
+ }
991
954
  }
992
- documentHighlight(arg) {
993
- return __awaiter(this, void 0, void 0, function* () {
994
- const file = (0, protocol_translation_1.uriToPath)(arg.textDocument.uri);
995
- this.logger.log('documentHighlight', arg, file);
996
- if (!file) {
997
- return [];
998
- }
999
- let response;
1000
- try {
1001
- response = yield this.tspClient.request("documentHighlights" /* DocumentHighlights */, {
1002
- file,
1003
- line: arg.position.line + 1,
1004
- offset: arg.position.character + 1,
1005
- filesToSearch: [file]
1006
- });
1007
- }
1008
- catch (err) {
1009
- return [];
1010
- }
1011
- if (!response.body) {
1012
- return [];
1013
- }
1014
- const result = [];
1015
- for (const item of response.body) {
1016
- // tsp returns item.file with POSIX path delimiters, whereas file is platform specific.
1017
- // Converting to a URI and back to a path ensures consistency.
1018
- if ((0, protocol_translation_1.normalizePath)(item.file) === file) {
1019
- const highlights = (0, protocol_translation_1.toDocumentHighlight)(item);
1020
- result.push(...highlights);
1021
- }
955
+ async documentHighlight(arg) {
956
+ const file = uriToPath(arg.textDocument.uri);
957
+ this.logger.log('documentHighlight', arg, file);
958
+ if (!file) {
959
+ return [];
960
+ }
961
+ let response;
962
+ try {
963
+ response = await this.tspClient.request("documentHighlights" /* CommandTypes.DocumentHighlights */, {
964
+ file,
965
+ line: arg.position.line + 1,
966
+ offset: arg.position.character + 1,
967
+ filesToSearch: [file],
968
+ });
969
+ }
970
+ catch (err) {
971
+ return [];
972
+ }
973
+ if (!response.body) {
974
+ return [];
975
+ }
976
+ const result = [];
977
+ for (const item of response.body) {
978
+ // tsp returns item.file with POSIX path delimiters, whereas file is platform specific.
979
+ // Converting to a URI and back to a path ensures consistency.
980
+ if (normalizePath(item.file) === file) {
981
+ const highlights = toDocumentHighlight(item);
982
+ result.push(...highlights);
1022
983
  }
1023
- return result;
1024
- });
984
+ }
985
+ return result;
1025
986
  }
1026
987
  lastFileOrDummy() {
1027
988
  return this.documents.files[0] || this.workspaceRoot;
1028
989
  }
1029
- workspaceSymbol(params) {
1030
- return __awaiter(this, void 0, void 0, function* () {
1031
- const result = yield this.tspClient.request("navto" /* Navto */, {
1032
- file: this.lastFileOrDummy(),
1033
- searchValue: params.query
1034
- });
1035
- if (!result.body) {
1036
- return [];
1037
- }
1038
- return result.body.map(item => {
1039
- return {
1040
- location: {
1041
- uri: (0, protocol_translation_1.pathToUri)(item.file, this.documents),
1042
- range: {
1043
- start: (0, protocol_translation_1.toPosition)(item.start),
1044
- end: (0, protocol_translation_1.toPosition)(item.end)
1045
- }
990
+ async workspaceSymbol(params) {
991
+ const result = await this.tspClient.request("navto" /* CommandTypes.Navto */, {
992
+ file: this.lastFileOrDummy(),
993
+ searchValue: params.query,
994
+ });
995
+ if (!result.body) {
996
+ return [];
997
+ }
998
+ return result.body.map(item => {
999
+ return {
1000
+ location: {
1001
+ uri: pathToUri(item.file, this.documents),
1002
+ range: {
1003
+ start: Position.fromLocation(item.start),
1004
+ end: Position.fromLocation(item.end),
1046
1005
  },
1047
- kind: (0, protocol_translation_1.toSymbolKind)(item.kind),
1048
- name: item.name
1049
- };
1050
- });
1006
+ },
1007
+ kind: toSymbolKind(item.kind),
1008
+ name: item.name,
1009
+ };
1051
1010
  });
1052
1011
  }
1053
1012
  /**
1054
1013
  * implemented based on https://github.com/Microsoft/vscode/blob/master/extensions/typescript-language-features/src/features/folding.ts
1055
1014
  */
1056
- foldingRanges(params) {
1057
- return __awaiter(this, void 0, void 0, function* () {
1058
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
1059
- this.logger.log('foldingRanges', params, file);
1060
- if (!file) {
1061
- return undefined;
1062
- }
1063
- const document = this.documents.get(file);
1064
- if (!document) {
1065
- throw new Error("The document should be opened for foldingRanges', file: " + file);
1066
- }
1067
- const { body } = yield this.tspClient.request("getOutliningSpans" /* GetOutliningSpans */, { file });
1068
- if (!body) {
1069
- return undefined;
1070
- }
1071
- const foldingRanges = [];
1072
- for (const span of body) {
1073
- const foldingRange = this.asFoldingRange(span, document);
1074
- if (foldingRange) {
1075
- foldingRanges.push(foldingRange);
1076
- }
1015
+ async foldingRanges(params) {
1016
+ const file = uriToPath(params.textDocument.uri);
1017
+ this.logger.log('foldingRanges', params, file);
1018
+ if (!file) {
1019
+ return undefined;
1020
+ }
1021
+ const document = this.documents.get(file);
1022
+ if (!document) {
1023
+ throw new Error("The document should be opened for foldingRanges', file: " + file);
1024
+ }
1025
+ const { body } = await this.tspClient.request("getOutliningSpans" /* CommandTypes.GetOutliningSpans */, { file });
1026
+ if (!body) {
1027
+ return undefined;
1028
+ }
1029
+ const foldingRanges = [];
1030
+ for (const span of body) {
1031
+ const foldingRange = this.asFoldingRange(span, document);
1032
+ if (foldingRange) {
1033
+ foldingRanges.push(foldingRange);
1077
1034
  }
1078
- return foldingRanges;
1079
- });
1035
+ }
1036
+ return foldingRanges;
1080
1037
  }
1081
1038
  asFoldingRange(span, document) {
1082
- const range = (0, protocol_translation_1.asRange)(span.textSpan);
1039
+ const range = Range.fromTextSpan(span.textSpan);
1083
1040
  const kind = this.asFoldingRangeKind(span);
1084
1041
  // workaround for https://github.com/Microsoft/vscode/issues/49904
1085
1042
  if (span.kind === 'comment') {
@@ -1094,7 +1051,7 @@ class LspServer {
1094
1051
  return {
1095
1052
  startLine,
1096
1053
  endLine,
1097
- kind
1054
+ kind,
1098
1055
  };
1099
1056
  }
1100
1057
  asFoldingRangeKind(span) {
@@ -1106,151 +1063,136 @@ class LspServer {
1106
1063
  default: return undefined;
1107
1064
  }
1108
1065
  }
1109
- onTsEvent(event) {
1110
- var _a;
1111
- if (event.event === "semanticDiag" /* SementicDiag */ ||
1112
- event.event === "syntaxDiag" /* SyntaxDiag */ ||
1113
- event.event === "suggestionDiag" /* SuggestionDiag */) {
1114
- (_a = this.diagnosticQueue) === null || _a === void 0 ? void 0 : _a.updateDiagnostics(event.event, event);
1066
+ async onTsEvent(event) {
1067
+ if (event.event === "semanticDiag" /* EventTypes.SementicDiag */ ||
1068
+ event.event === "syntaxDiag" /* EventTypes.SyntaxDiag */ ||
1069
+ event.event === "suggestionDiag" /* EventTypes.SuggestionDiag */) {
1070
+ this.diagnosticQueue?.updateDiagnostics(event.event, event);
1115
1071
  }
1116
- else if (event.event === "projectLoadingStart" /* ProjectLoadingStart */) {
1117
- this.loadingIndicator.startedLoadingProject(event.body.projectName);
1072
+ else if (event.event === "projectLoadingStart" /* EventTypes.ProjectLoadingStart */) {
1073
+ await this.loadingIndicator.startedLoadingProject(event.body.projectName);
1118
1074
  }
1119
- else if (event.event === "projectLoadingFinish" /* ProjectLoadingFinish */) {
1075
+ else if (event.event === "projectLoadingFinish" /* EventTypes.ProjectLoadingFinish */) {
1120
1076
  this.loadingIndicator.finishedLoadingProject(event.body.projectName);
1121
1077
  }
1122
1078
  else {
1123
1079
  this.logger.log('Ignored event', {
1124
- event: event.event
1080
+ event: event.event,
1125
1081
  });
1126
1082
  }
1127
1083
  }
1128
- calls(params) {
1129
- return __awaiter(this, void 0, void 0, function* () {
1130
- let callsResult = { calls: [] };
1131
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
1132
- this.logger.log('calls', params, file);
1133
- if (!file) {
1134
- return callsResult;
1135
- }
1136
- if (params.direction === lspcalls.CallDirection.Outgoing) {
1137
- const documentProvider = (file) => this.documents.get(file);
1138
- callsResult = yield (0, calls_1.computeCallees)(this.tspClient, params, documentProvider);
1139
- }
1140
- else {
1141
- callsResult = yield (0, calls_1.computeCallers)(this.tspClient, params);
1142
- }
1084
+ async calls(params) {
1085
+ let callsResult = { calls: [] };
1086
+ const file = uriToPath(params.textDocument.uri);
1087
+ this.logger.log('calls', params, file);
1088
+ if (!file) {
1143
1089
  return callsResult;
1144
- });
1145
- }
1146
- inlayHints(params) {
1147
- var _a, _b, _c, _d, _e, _f;
1148
- return __awaiter(this, void 0, void 0, function* () {
1149
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
1150
- this.logger.log('inlayHints', params, file);
1151
- if (!file) {
1152
- return { inlayHints: [] };
1153
- }
1154
- yield this.tspClient.request("configure" /* Configure */, {
1155
- preferences: this.getInlayHintsOptions(file)
1156
- });
1157
- const doc = this.documents.get(file);
1158
- if (!doc) {
1159
- return { inlayHints: [] };
1160
- }
1161
- const start = doc.offsetAt((_b = (_a = params.range) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : {
1162
- line: 0,
1163
- character: 0
1164
- });
1165
- const end = doc.offsetAt((_d = (_c = params.range) === null || _c === void 0 ? void 0 : _c.end) !== null && _d !== void 0 ? _d : {
1166
- line: doc.lineCount + 1,
1167
- character: 0
1168
- });
1169
- try {
1170
- const result = yield this.tspClient.request("provideInlayHints" /* ProvideInlayHints */, {
1171
- file,
1172
- start: start,
1173
- length: end - start
1174
- });
1175
- return {
1176
- inlayHints: (_f = (_e = result.body) === null || _e === void 0 ? void 0 : _e.map((item) => ({
1177
- text: item.text,
1178
- position: (0, protocol_translation_1.toPosition)(item.position),
1179
- whitespaceAfter: item.whitespaceAfter,
1180
- whitespaceBefore: item.whitespaceBefore,
1181
- kind: item.kind
1182
- }))) !== null && _f !== void 0 ? _f : []
1183
- };
1184
- }
1185
- catch (_g) {
1186
- return {
1187
- inlayHints: []
1188
- };
1189
- }
1190
- });
1090
+ }
1091
+ if (params.direction === lspcalls.CallDirection.Outgoing) {
1092
+ const documentProvider = (file) => this.documents.get(file);
1093
+ callsResult = await computeCallees(this.tspClient, params, documentProvider);
1094
+ }
1095
+ else {
1096
+ callsResult = await computeCallers(this.tspClient, params);
1097
+ }
1098
+ return callsResult;
1191
1099
  }
1192
- getInlayHintsOptions(file) {
1193
- var _a, _b;
1194
- const workspacePreference = this.getWorkspacePreferencesForDocument(file);
1195
- const userPreferences = ((_a = this.initializeParams.initializationOptions) === null || _a === void 0 ? void 0 : _a.preferences) || {};
1196
- return Object.assign(Object.assign({}, userPreferences), (_b = workspacePreference.inlayHints) !== null && _b !== void 0 ? _b : {});
1100
+ async inlayHints(params) {
1101
+ return await TypeScriptInlayHintsProvider.provideInlayHints(params.textDocument.uri, params.range, this.documents, this.tspClient, this.options.lspClient, this.configurationManager);
1197
1102
  }
1198
- semanticTokensFull(params) {
1199
- return __awaiter(this, void 0, void 0, function* () {
1200
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
1201
- this.logger.log('semanticTokensFull', params, file);
1202
- if (!file) {
1203
- return { data: [] };
1204
- }
1205
- const doc = this.documents.get(file);
1206
- if (!doc) {
1207
- return { data: [] };
1208
- }
1209
- const start = doc.offsetAt({
1210
- line: 0,
1211
- character: 0
1212
- });
1213
- const end = doc.offsetAt({
1214
- line: doc.lineCount,
1215
- character: 0
1216
- });
1217
- return this.getSemanticTokens(doc, file, start, end);
1103
+ async inlayHintsLegacy(params) {
1104
+ this.options.lspClient.logMessage({
1105
+ message: 'Support for experimental "typescript/inlayHints" request is deprecated. Use spec-compliant "textDocument/inlayHint" instead.',
1106
+ type: lsp.MessageType.Warning,
1218
1107
  });
1219
- }
1220
- semanticTokensRange(params) {
1221
- return __awaiter(this, void 0, void 0, function* () {
1222
- const file = (0, protocol_translation_1.uriToPath)(params.textDocument.uri);
1223
- this.logger.log('semanticTokensRange', params, file);
1224
- if (!file) {
1225
- return { data: [] };
1226
- }
1227
- const doc = this.documents.get(file);
1228
- if (!doc) {
1229
- return { data: [] };
1230
- }
1231
- const start = doc.offsetAt(params.range.start);
1232
- const end = doc.offsetAt(params.range.end);
1233
- return this.getSemanticTokens(doc, file, start, end);
1108
+ const file = uriToPath(params.textDocument.uri);
1109
+ this.logger.log('inlayHints', params, file);
1110
+ if (!file) {
1111
+ return { inlayHints: [] };
1112
+ }
1113
+ await this.configurationManager.configureGloballyFromDocument(file);
1114
+ const doc = this.documents.get(file);
1115
+ if (!doc) {
1116
+ return { inlayHints: [] };
1117
+ }
1118
+ const start = doc.offsetAt(params.range?.start ?? {
1119
+ line: 0,
1120
+ character: 0,
1234
1121
  });
1122
+ const end = doc.offsetAt(params.range?.end ?? {
1123
+ line: doc.lineCount + 1,
1124
+ character: 0,
1125
+ });
1126
+ try {
1127
+ const result = await this.tspClient.request("provideInlayHints" /* CommandTypes.ProvideInlayHints */, {
1128
+ file,
1129
+ start: start,
1130
+ length: end - start,
1131
+ });
1132
+ return {
1133
+ inlayHints: result.body?.map((item) => ({
1134
+ text: item.text,
1135
+ position: Position.fromLocation(item.position),
1136
+ whitespaceAfter: item.whitespaceAfter,
1137
+ whitespaceBefore: item.whitespaceBefore,
1138
+ kind: item.kind,
1139
+ })) ?? [],
1140
+ };
1141
+ }
1142
+ catch {
1143
+ return {
1144
+ inlayHints: [],
1145
+ };
1146
+ }
1235
1147
  }
1236
- getSemanticTokens(doc, file, startOffset, endOffset) {
1237
- var _a, _b;
1238
- return __awaiter(this, void 0, void 0, function* () {
1239
- try {
1240
- const result = yield this.tspClient.request("encodedSemanticClassifications-full" /* EncodedSemanticClassificationsFull */, {
1241
- file,
1242
- start: startOffset,
1243
- length: endOffset - startOffset,
1244
- format: '2020'
1245
- });
1246
- const spans = (_b = (_a = result.body) === null || _a === void 0 ? void 0 : _a.spans) !== null && _b !== void 0 ? _b : [];
1247
- return { data: lspsemanticTokens.transformSpans(doc, spans) };
1248
- }
1249
- catch (_c) {
1250
- return { data: [] };
1251
- }
1148
+ async semanticTokensFull(params) {
1149
+ const file = uriToPath(params.textDocument.uri);
1150
+ this.logger.log('semanticTokensFull', params, file);
1151
+ if (!file) {
1152
+ return { data: [] };
1153
+ }
1154
+ const doc = this.documents.get(file);
1155
+ if (!doc) {
1156
+ return { data: [] };
1157
+ }
1158
+ const start = doc.offsetAt({
1159
+ line: 0,
1160
+ character: 0,
1161
+ });
1162
+ const end = doc.offsetAt({
1163
+ line: doc.lineCount,
1164
+ character: 0,
1252
1165
  });
1166
+ return this.getSemanticTokens(doc, file, start, end);
1167
+ }
1168
+ async semanticTokensRange(params) {
1169
+ const file = uriToPath(params.textDocument.uri);
1170
+ this.logger.log('semanticTokensRange', params, file);
1171
+ if (!file) {
1172
+ return { data: [] };
1173
+ }
1174
+ const doc = this.documents.get(file);
1175
+ if (!doc) {
1176
+ return { data: [] };
1177
+ }
1178
+ const start = doc.offsetAt(params.range.start);
1179
+ const end = doc.offsetAt(params.range.end);
1180
+ return this.getSemanticTokens(doc, file, start, end);
1181
+ }
1182
+ async getSemanticTokens(doc, file, startOffset, endOffset) {
1183
+ try {
1184
+ const result = await this.tspClient.request("encodedSemanticClassifications-full" /* CommandTypes.EncodedSemanticClassificationsFull */, {
1185
+ file,
1186
+ start: startOffset,
1187
+ length: endOffset - startOffset,
1188
+ format: '2020',
1189
+ });
1190
+ const spans = result.body?.spans ?? [];
1191
+ return { data: lspsemanticTokens.transformSpans(doc, spans) };
1192
+ }
1193
+ catch {
1194
+ return { data: [] };
1195
+ }
1253
1196
  }
1254
1197
  }
1255
- exports.LspServer = LspServer;
1256
1198
  //# sourceMappingURL=lsp-server.js.map