Add the concept of client capabilities for TypeScript
For serverless, we will only be able to run the TypeScript syntax server which does not support all features. This change makes this possible by adding the concept of client capabilities. Providers such as rename will only be registered when the client has semantic capabilities
This commit is contained in:
parent
16c6b81b3e
commit
0857489caf
|
@ -3,23 +3,23 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { Api, getExtensionApi } from './api';
|
import { Api, getExtensionApi } from './api';
|
||||||
import { registerCommands } from './commands/index';
|
import { registerCommands } from './commands/index';
|
||||||
import { LanguageConfigurationManager } from './features/languageConfiguration';
|
import { LanguageConfigurationManager } from './features/languageConfiguration';
|
||||||
|
import * as task from './features/task';
|
||||||
import TypeScriptServiceClientHost from './typeScriptServiceClientHost';
|
import TypeScriptServiceClientHost from './typeScriptServiceClientHost';
|
||||||
import { flatten } from './utils/arrays';
|
import { flatten } from './utils/arrays';
|
||||||
import * as electron from './utils/electron';
|
|
||||||
import * as rimraf from 'rimraf';
|
|
||||||
import { CommandManager } from './utils/commandManager';
|
import { CommandManager } from './utils/commandManager';
|
||||||
|
import * as electron from './utils/electron';
|
||||||
import * as fileSchemes from './utils/fileSchemes';
|
import * as fileSchemes from './utils/fileSchemes';
|
||||||
import { standardLanguageDescriptions } from './utils/languageDescription';
|
import { standardLanguageDescriptions } from './utils/languageDescription';
|
||||||
|
import * as ProjectStatus from './utils/largeProjectStatus';
|
||||||
import { lazy, Lazy } from './utils/lazy';
|
import { lazy, Lazy } from './utils/lazy';
|
||||||
import LogDirectoryProvider from './utils/logDirectoryProvider';
|
import LogDirectoryProvider from './utils/logDirectoryProvider';
|
||||||
import ManagedFileContextManager from './utils/managedFileContext';
|
import ManagedFileContextManager from './utils/managedFileContext';
|
||||||
import { PluginManager } from './utils/plugins';
|
import { PluginManager } from './utils/plugins';
|
||||||
import * as ProjectStatus from './utils/largeProjectStatus';
|
|
||||||
import TscTaskProvider from './features/task';
|
|
||||||
|
|
||||||
export function activate(
|
export function activate(
|
||||||
context: vscode.ExtensionContext
|
context: vscode.ExtensionContext
|
||||||
|
@ -38,7 +38,7 @@ export function activate(
|
||||||
});
|
});
|
||||||
|
|
||||||
registerCommands(commandManager, lazyClientHost, pluginManager);
|
registerCommands(commandManager, lazyClientHost, pluginManager);
|
||||||
context.subscriptions.push(vscode.tasks.registerTaskProvider('typescript', new TscTaskProvider(lazyClientHost.map(x => x.serviceClient))));
|
context.subscriptions.push(task.register(lazyClientHost.map(x => x.serviceClient)));
|
||||||
context.subscriptions.push(new LanguageConfigurationManager());
|
context.subscriptions.push(new LanguageConfigurationManager());
|
||||||
|
|
||||||
import('./features/tsconfig').then(module => {
|
import('./features/tsconfig').then(module => {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ITypeScriptServiceClient, ClientCapability } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { coalesce } from '../utils/arrays';
|
import { coalesce } from '../utils/arrays';
|
||||||
import { Delayer } from '../utils/async';
|
import { Delayer } from '../utils/async';
|
||||||
|
@ -302,9 +302,9 @@ class GetErrRequest {
|
||||||
onDone: () => void
|
onDone: () => void
|
||||||
) {
|
) {
|
||||||
const allFiles = coalesce(Array.from(files.entries).map(entry => client.normalizedPath(entry.resource)));
|
const allFiles = coalesce(Array.from(files.entries).map(entry => client.normalizedPath(entry.resource)));
|
||||||
if (!allFiles.length) {
|
if (!allFiles.length || !client.capabilities.has(ClientCapability.Semantic)) {
|
||||||
this._done = true;
|
this._done = true;
|
||||||
onDone();
|
setImmediate(onDone);
|
||||||
} else {
|
} else {
|
||||||
const request = client.configuration.enableProjectDiagnostics
|
const request = client.configuration.enableProjectDiagnostics
|
||||||
// Note that geterrForProject is almost certainly not the api we want here as it ends up computing far
|
// Note that geterrForProject is almost certainly not the api we want here as it ends up computing far
|
||||||
|
|
|
@ -7,11 +7,11 @@ import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import * as PConst from '../protocol.const';
|
import * as PConst from '../protocol.const';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
|
||||||
import { conditionalRegistration, requireConfiguration } from '../utils/dependentRegistration';
|
|
||||||
import { TypeScriptBaseCodeLensProvider, ReferencesCodeLens, getSymbolRange } from './baseCodeLensProvider';
|
|
||||||
import { CachedResponse } from '../tsServer/cachedResponse';
|
import { CachedResponse } from '../tsServer/cachedResponse';
|
||||||
|
import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService';
|
||||||
|
import { conditionalRegistration, requireCapability, requireConfiguration } from '../utils/dependentRegistration';
|
||||||
import * as typeConverters from '../utils/typeConverters';
|
import * as typeConverters from '../utils/typeConverters';
|
||||||
|
import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ export function register(
|
||||||
) {
|
) {
|
||||||
return conditionalRegistration([
|
return conditionalRegistration([
|
||||||
requireConfiguration(modeId, 'implementationsCodeLens.enabled'),
|
requireConfiguration(modeId, 'implementationsCodeLens.enabled'),
|
||||||
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
], () => {
|
], () => {
|
||||||
return vscode.languages.registerCodeLensProvider(selector,
|
return vscode.languages.registerCodeLensProvider(selector,
|
||||||
new TypeScriptImplementationsCodeLensProvider(client, cachedResponse));
|
new TypeScriptImplementationsCodeLensProvider(client, cachedResponse));
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ITypeScriptServiceClient, ClientCapability } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { nulToken } from '../utils/cancellation';
|
import { nulToken } from '../utils/cancellation';
|
||||||
import { applyCodeActionCommands, getEditForCodeAction } from '../utils/codeAction';
|
import { applyCodeActionCommands, getEditForCodeAction } from '../utils/codeAction';
|
||||||
|
@ -18,6 +18,7 @@ import * as typeConverters from '../utils/typeConverters';
|
||||||
import { DiagnosticsManager } from './diagnostics';
|
import { DiagnosticsManager } from './diagnostics';
|
||||||
import FileConfigurationManager from './fileConfigurationManager';
|
import FileConfigurationManager from './fileConfigurationManager';
|
||||||
import { equals } from '../utils/objects';
|
import { equals } from '../utils/objects';
|
||||||
|
import { conditionalRegistration, requireCapability } from '../utils/dependentRegistration';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
@ -409,7 +410,11 @@ export function register(
|
||||||
diagnosticsManager: DiagnosticsManager,
|
diagnosticsManager: DiagnosticsManager,
|
||||||
telemetryReporter: TelemetryReporter
|
telemetryReporter: TelemetryReporter
|
||||||
) {
|
) {
|
||||||
return vscode.languages.registerCodeActionsProvider(selector,
|
return conditionalRegistration([
|
||||||
new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, telemetryReporter),
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
TypeScriptQuickFixProvider.metadata);
|
], () => {
|
||||||
|
return vscode.languages.registerCodeActionsProvider(selector,
|
||||||
|
new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, telemetryReporter),
|
||||||
|
TypeScriptQuickFixProvider.metadata);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { LearnMoreAboutRefactoringsCommand } from '../commands/learnMoreAboutRefactorings';
|
import { LearnMoreAboutRefactoringsCommand } from '../commands/learnMoreAboutRefactorings';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { nulToken } from '../utils/cancellation';
|
import { nulToken } from '../utils/cancellation';
|
||||||
import { Command, CommandManager } from '../utils/commandManager';
|
import { Command, CommandManager } from '../utils/commandManager';
|
||||||
import { conditionalRegistration, requireMinVersion } from '../utils/dependentRegistration';
|
import { conditionalRegistration, requireCapability, requireMinVersion } from '../utils/dependentRegistration';
|
||||||
import * as fileSchemes from '../utils/fileSchemes';
|
import * as fileSchemes from '../utils/fileSchemes';
|
||||||
import { TelemetryReporter } from '../utils/telemetry';
|
import { TelemetryReporter } from '../utils/telemetry';
|
||||||
import * as typeConverters from '../utils/typeConverters';
|
import * as typeConverters from '../utils/typeConverters';
|
||||||
|
@ -403,7 +403,8 @@ export function register(
|
||||||
telemetryReporter: TelemetryReporter,
|
telemetryReporter: TelemetryReporter,
|
||||||
) {
|
) {
|
||||||
return conditionalRegistration([
|
return conditionalRegistration([
|
||||||
requireMinVersion(client, TypeScriptRefactorProvider.minVersion)
|
requireMinVersion(client, TypeScriptRefactorProvider.minVersion),
|
||||||
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
], () => {
|
], () => {
|
||||||
return vscode.languages.registerCodeActionsProvider(selector,
|
return vscode.languages.registerCodeActionsProvider(selector,
|
||||||
new TypeScriptRefactorProvider(client, formattingOptionsManager, commandManager, telemetryReporter),
|
new TypeScriptRefactorProvider(client, formattingOptionsManager, commandManager, telemetryReporter),
|
||||||
|
|
|
@ -8,8 +8,8 @@ import * as nls from 'vscode-nls';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import * as PConst from '../protocol.const';
|
import * as PConst from '../protocol.const';
|
||||||
import { CachedResponse } from '../tsServer/cachedResponse';
|
import { CachedResponse } from '../tsServer/cachedResponse';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ITypeScriptServiceClient, ClientCapability } from '../typescriptService';
|
||||||
import { conditionalRegistration, requireConfiguration } from '../utils/dependentRegistration';
|
import { conditionalRegistration, requireConfiguration, requireCapability } from '../utils/dependentRegistration';
|
||||||
import * as typeConverters from '../utils/typeConverters';
|
import * as typeConverters from '../utils/typeConverters';
|
||||||
import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider';
|
import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider';
|
||||||
|
|
||||||
|
@ -128,7 +128,8 @@ export function register(
|
||||||
cachedResponse: CachedResponse<Proto.NavTreeResponse>,
|
cachedResponse: CachedResponse<Proto.NavTreeResponse>,
|
||||||
) {
|
) {
|
||||||
return conditionalRegistration([
|
return conditionalRegistration([
|
||||||
requireConfiguration(modeId, 'referencesCodeLens.enabled')
|
requireConfiguration(modeId, 'referencesCodeLens.enabled'),
|
||||||
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
], () => {
|
], () => {
|
||||||
return vscode.languages.registerCodeLensProvider(selector,
|
return vscode.languages.registerCodeLensProvider(selector,
|
||||||
new TypeScriptReferencesCodeLensProvider(client, cachedResponse, modeId));
|
new TypeScriptReferencesCodeLensProvider(client, cachedResponse, modeId));
|
||||||
|
|
|
@ -7,8 +7,9 @@ import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
|
import { ClientCapability, ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
|
import { conditionalRegistration, requireCapability } from '../utils/dependentRegistration';
|
||||||
import * as typeConverters from '../utils/typeConverters';
|
import * as typeConverters from '../utils/typeConverters';
|
||||||
import FileConfigurationManager from './fileConfigurationManager';
|
import FileConfigurationManager from './fileConfigurationManager';
|
||||||
|
|
||||||
|
@ -141,6 +142,10 @@ export function register(
|
||||||
client: ITypeScriptServiceClient,
|
client: ITypeScriptServiceClient,
|
||||||
fileConfigurationManager: FileConfigurationManager,
|
fileConfigurationManager: FileConfigurationManager,
|
||||||
) {
|
) {
|
||||||
return vscode.languages.registerRenameProvider(selector,
|
return conditionalRegistration([
|
||||||
new TypeScriptRenameProvider(client, fileConfigurationManager));
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
|
], () => {
|
||||||
|
return vscode.languages.registerRenameProvider(selector,
|
||||||
|
new TypeScriptRenameProvider(client, fileConfigurationManager));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
import { TokenEncodingConsts, TokenModifier, TokenType, VersionRequirement } from 'typescript-vscode-sh-plugin/lib/constants';
|
import { TokenEncodingConsts, TokenModifier, TokenType, VersionRequirement } from 'typescript-vscode-sh-plugin/lib/constants';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as Proto from '../protocol';
|
import * as Proto from '../protocol';
|
||||||
import { ExecConfig, ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
|
import { ClientCapability, ExecConfig, ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { conditionalRegistration, requireMinVersion } from '../utils/dependentRegistration';
|
import { conditionalRegistration, requireCapability, requireMinVersion } from '../utils/dependentRegistration';
|
||||||
|
|
||||||
|
|
||||||
const minTypeScriptVersion = API.fromVersionString(`${VersionRequirement.major}.${VersionRequirement.minor}`);
|
const minTypeScriptVersion = API.fromVersionString(`${VersionRequirement.major}.${VersionRequirement.minor}`);
|
||||||
|
@ -20,6 +20,7 @@ const CONTENT_LENGTH_LIMIT = 100000;
|
||||||
export function register(selector: vscode.DocumentSelector, client: ITypeScriptServiceClient) {
|
export function register(selector: vscode.DocumentSelector, client: ITypeScriptServiceClient) {
|
||||||
return conditionalRegistration([
|
return conditionalRegistration([
|
||||||
requireMinVersion(client, minTypeScriptVersion),
|
requireMinVersion(client, minTypeScriptVersion),
|
||||||
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
], () => {
|
], () => {
|
||||||
const provider = new DocumentSemanticTokensProvider(client);
|
const provider = new DocumentSemanticTokensProvider(client);
|
||||||
return vscode.Disposable.from(
|
return vscode.Disposable.from(
|
||||||
|
|
|
@ -35,7 +35,7 @@ interface TypeScriptTaskDefinition extends vscode.TaskDefinition {
|
||||||
/**
|
/**
|
||||||
* Provides tasks for building `tsconfig.json` files in a project.
|
* Provides tasks for building `tsconfig.json` files in a project.
|
||||||
*/
|
*/
|
||||||
export default class TscTaskProvider implements vscode.TaskProvider {
|
class TscTaskProvider implements vscode.TaskProvider {
|
||||||
|
|
||||||
private readonly projectInfoRequestTimeout = 2000;
|
private readonly projectInfoRequestTimeout = 2000;
|
||||||
private autoDetect: AutoDetect = 'on';
|
private autoDetect: AutoDetect = 'on';
|
||||||
|
@ -291,3 +291,9 @@ export default class TscTaskProvider implements vscode.TaskProvider {
|
||||||
this.autoDetect = typeof type === 'undefined' ? 'on' : type;
|
this.autoDetect = typeof type === 'undefined' ? 'on' : type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function register(
|
||||||
|
lazyClient: Lazy<ITypeScriptServiceClient>,
|
||||||
|
) {
|
||||||
|
return vscode.tasks.registerTaskProvider('typescript', new TscTaskProvider(lazyClient));
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { Delayer } from '../utils/async';
|
import { Delayer } from '../utils/async';
|
||||||
import { nulToken } from '../utils/cancellation';
|
import { nulToken } from '../utils/cancellation';
|
||||||
import { conditionalRegistration, requireMinVersion } from '../utils/dependentRegistration';
|
import { conditionalRegistration, requireCapability, requireMinVersion } from '../utils/dependentRegistration';
|
||||||
import { Disposable } from '../utils/dispose';
|
import { Disposable } from '../utils/dispose';
|
||||||
import * as fileSchemes from '../utils/fileSchemes';
|
import * as fileSchemes from '../utils/fileSchemes';
|
||||||
import { doesResourceLookLikeATypeScriptFile } from '../utils/languageDescription';
|
import { doesResourceLookLikeATypeScriptFile } from '../utils/languageDescription';
|
||||||
|
@ -296,6 +296,7 @@ export function register(
|
||||||
) {
|
) {
|
||||||
return conditionalRegistration([
|
return conditionalRegistration([
|
||||||
requireMinVersion(client, UpdateImportsOnFileRenameHandler.minVersion),
|
requireMinVersion(client, UpdateImportsOnFileRenameHandler.minVersion),
|
||||||
|
requireCapability(client, ClientCapability.Semantic),
|
||||||
], () => {
|
], () => {
|
||||||
return new UpdateImportsOnFileRenameHandler(client, fileConfigurationManager, handles);
|
return new UpdateImportsOnFileRenameHandler(client, fileConfigurationManager, handles);
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ import * as path from 'path';
|
||||||
import * as stream from 'stream';
|
import * as stream from 'stream';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
|
import { ClientCapability } from '../typescriptService';
|
||||||
import API from '../utils/api';
|
import API from '../utils/api';
|
||||||
import { SeparateSyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration';
|
import { SeparateSyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration';
|
||||||
import * as electron from '../utils/electron';
|
import * as electron from '../utils/electron';
|
||||||
|
@ -36,6 +37,9 @@ const enum CompositeServerType {
|
||||||
|
|
||||||
/** Use a separate syntax server while the project is loading */
|
/** Use a separate syntax server while the project is loading */
|
||||||
DynamicSeparateSyntax,
|
DynamicSeparateSyntax,
|
||||||
|
|
||||||
|
/** Only enable the syntax server */
|
||||||
|
SyntaxOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TypeScriptServerSpawner {
|
export class TypeScriptServerSpawner {
|
||||||
|
@ -50,12 +54,13 @@ export class TypeScriptServerSpawner {
|
||||||
|
|
||||||
public spawn(
|
public spawn(
|
||||||
version: TypeScriptVersion,
|
version: TypeScriptVersion,
|
||||||
|
capabilities: Set<ClientCapability>,
|
||||||
configuration: TypeScriptServiceConfiguration,
|
configuration: TypeScriptServiceConfiguration,
|
||||||
pluginManager: PluginManager,
|
pluginManager: PluginManager,
|
||||||
delegate: TsServerDelegate,
|
delegate: TsServerDelegate,
|
||||||
): ITypeScriptServer {
|
): ITypeScriptServer {
|
||||||
let primaryServer: ITypeScriptServer;
|
let primaryServer: ITypeScriptServer;
|
||||||
const serverType = this.getCompositeServerType(version, configuration);
|
const serverType = this.getCompositeServerType(version, capabilities, configuration);
|
||||||
switch (serverType) {
|
switch (serverType) {
|
||||||
case CompositeServerType.SeparateSyntax:
|
case CompositeServerType.SeparateSyntax:
|
||||||
case CompositeServerType.DynamicSeparateSyntax:
|
case CompositeServerType.DynamicSeparateSyntax:
|
||||||
|
@ -72,6 +77,11 @@ export class TypeScriptServerSpawner {
|
||||||
primaryServer = this.spawnTsServer(ServerKind.Main, version, configuration, pluginManager);
|
primaryServer = this.spawnTsServer(ServerKind.Main, version, configuration, pluginManager);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CompositeServerType.SyntaxOnly:
|
||||||
|
{
|
||||||
|
primaryServer = this.spawnTsServer(ServerKind.Syntax, version, configuration, pluginManager);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shouldUseSeparateDiagnosticsServer(configuration)) {
|
if (this.shouldUseSeparateDiagnosticsServer(configuration)) {
|
||||||
|
@ -86,8 +96,13 @@ export class TypeScriptServerSpawner {
|
||||||
|
|
||||||
private getCompositeServerType(
|
private getCompositeServerType(
|
||||||
version: TypeScriptVersion,
|
version: TypeScriptVersion,
|
||||||
|
capabilities: Set<ClientCapability>,
|
||||||
configuration: TypeScriptServiceConfiguration,
|
configuration: TypeScriptServiceConfiguration,
|
||||||
): CompositeServerType {
|
): CompositeServerType {
|
||||||
|
if (!capabilities.has(ClientCapability.Semantic)) {
|
||||||
|
return CompositeServerType.SyntaxOnly;
|
||||||
|
}
|
||||||
|
|
||||||
switch (configuration.separateSyntaxServer) {
|
switch (configuration.separateSyntaxServer) {
|
||||||
case SeparateSyntaxServerConfiguration.Disabled:
|
case SeparateSyntaxServerConfiguration.Disabled:
|
||||||
return CompositeServerType.Single;
|
return CompositeServerType.Single;
|
||||||
|
|
|
@ -85,6 +85,11 @@ export type ExecConfig = {
|
||||||
readonly cancelOnResourceChange?: vscode.Uri
|
readonly cancelOnResourceChange?: vscode.Uri
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum ClientCapability {
|
||||||
|
Syntax,
|
||||||
|
Semantic,
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITypeScriptServiceClient {
|
export interface ITypeScriptServiceClient {
|
||||||
/**
|
/**
|
||||||
* Convert a resource (VS Code) to a normalized path (TypeScript).
|
* Convert a resource (VS Code) to a normalized path (TypeScript).
|
||||||
|
@ -120,6 +125,9 @@ export interface ITypeScriptServiceClient {
|
||||||
readonly onDidEndInstallTypings: vscode.Event<Proto.EndInstallTypesEventBody>;
|
readonly onDidEndInstallTypings: vscode.Event<Proto.EndInstallTypesEventBody>;
|
||||||
readonly onTypesInstallerInitializationFailed: vscode.Event<Proto.TypesInstallerInitializationFailedEventBody>;
|
readonly onTypesInstallerInitializationFailed: vscode.Event<Proto.TypesInstallerInitializationFailedEventBody>;
|
||||||
|
|
||||||
|
readonly capabilities: Set<ClientCapability>;
|
||||||
|
readonly onDidChangeCapabilities: vscode.Event<Set<ClientCapability>>;
|
||||||
|
|
||||||
onReady(f: () => void): Promise<void>;
|
onReady(f: () => void): Promise<void>;
|
||||||
|
|
||||||
showVersionPicker(): void;
|
showVersionPicker(): void;
|
||||||
|
|
|
@ -10,10 +10,11 @@ import * as nls from 'vscode-nls';
|
||||||
import BufferSyncSupport from './features/bufferSyncSupport';
|
import BufferSyncSupport from './features/bufferSyncSupport';
|
||||||
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
|
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
|
||||||
import * as Proto from './protocol';
|
import * as Proto from './protocol';
|
||||||
|
import { EventName } from './protocol.const';
|
||||||
import { ITypeScriptServer } from './tsServer/server';
|
import { ITypeScriptServer } from './tsServer/server';
|
||||||
import { TypeScriptServerError } from './tsServer/serverError';
|
import { TypeScriptServerError } from './tsServer/serverError';
|
||||||
import { TypeScriptServerSpawner } from './tsServer/spawner';
|
import { TypeScriptServerSpawner } from './tsServer/spawner';
|
||||||
import { ExecConfig, ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService';
|
import { ClientCapability, ExecConfig, ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService';
|
||||||
import API from './utils/api';
|
import API from './utils/api';
|
||||||
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
|
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
|
||||||
import { Disposable } from './utils/dispose';
|
import { Disposable } from './utils/dispose';
|
||||||
|
@ -22,12 +23,11 @@ import LogDirectoryProvider from './utils/logDirectoryProvider';
|
||||||
import Logger from './utils/logger';
|
import Logger from './utils/logger';
|
||||||
import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider';
|
import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider';
|
||||||
import { PluginManager } from './utils/plugins';
|
import { PluginManager } from './utils/plugins';
|
||||||
import { TelemetryReporter, VSCodeTelemetryReporter, TelemetryProperties } from './utils/telemetry';
|
import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from './utils/telemetry';
|
||||||
import Tracer from './utils/tracer';
|
import Tracer from './utils/tracer';
|
||||||
import { inferredProjectCompilerOptions, ProjectType } from './utils/tsconfig';
|
import { inferredProjectCompilerOptions, ProjectType } from './utils/tsconfig';
|
||||||
import { TypeScriptVersionManager } from './utils/versionManager';
|
import { TypeScriptVersionManager } from './utils/versionManager';
|
||||||
import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider';
|
import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider';
|
||||||
import { EventName } from './protocol.const';
|
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
@ -203,6 +203,16 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get capabilities() {
|
||||||
|
return new Set<ClientCapability>([
|
||||||
|
ClientCapability.Semantic,
|
||||||
|
ClientCapability.Syntax,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly _onDidChangeCapabilities = this._register(new vscode.EventEmitter<Set<ClientCapability>>());
|
||||||
|
readonly onDidChangeCapabilities = this._onDidChangeCapabilities.event;
|
||||||
|
|
||||||
private cancelInflightRequestsForResource(resource: vscode.Uri): void {
|
private cancelInflightRequestsForResource(resource: vscode.Uri): void {
|
||||||
if (this.serverState.type !== ServerState.Type.Running) {
|
if (this.serverState.type !== ServerState.Type.Running) {
|
||||||
return;
|
return;
|
||||||
|
@ -337,7 +347,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
|
|
||||||
const apiVersion = version.apiVersion || API.defaultVersion;
|
const apiVersion = version.apiVersion || API.defaultVersion;
|
||||||
let mytoken = ++this.token;
|
let mytoken = ++this.token;
|
||||||
const handle = this.typescriptServerSpawner.spawn(version, this.configuration, this.pluginManager, {
|
const handle = this.typescriptServerSpawner.spawn(version, this.capabilities, this.configuration, this.pluginManager, {
|
||||||
onFatalError: (command, err) => this.fatalError(command, err),
|
onFatalError: (command, err) => this.fatalError(command, err),
|
||||||
});
|
});
|
||||||
this.serverState = new ServerState.Running(handle, apiVersion, undefined, true);
|
this.serverState = new ServerState.Running(handle, apiVersion, undefined, true);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ITypeScriptServiceClient, ClientCapability } from '../typescriptService';
|
||||||
import API from './api';
|
import API from './api';
|
||||||
import { Disposable } from './dispose';
|
import { Disposable } from './dispose';
|
||||||
|
|
||||||
|
@ -95,3 +95,13 @@ export function requireConfiguration(
|
||||||
vscode.workspace.onDidChangeConfiguration
|
vscode.workspace.onDidChangeConfiguration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function requireCapability(
|
||||||
|
client: ITypeScriptServiceClient,
|
||||||
|
requiredCapability: ClientCapability,
|
||||||
|
) {
|
||||||
|
return new Condition(
|
||||||
|
() => client.capabilities.has(requiredCapability),
|
||||||
|
client.onDidChangeCapabilities
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue