diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index 6e5d3549e91..9bc66e21371 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -86,14 +86,14 @@ export class LanguageConfigurationService extends Disposable implements ILanguag .filter(([overrideLangName, keys]) => keys.some((k) => languageConfigKeys.has(k)) ) - .map(([overrideLangName]) => this.languageService.validateLanguageId(overrideLangName)); + .map(([overrideLangName]) => overrideLangName); if (globalConfigChanged) { this.configurations.clear(); this.onDidChangeEmitter.fire(new LanguageConfigurationServiceChangeEvent(undefined)); } else { for (const languageId of localConfigChanged) { - if (languageId) { + if (this.languageService.isRegisteredLanguageId(languageId)) { this.configurations.delete(languageId); this.onDidChangeEmitter.fire(new LanguageConfigurationServiceChangeEvent(languageId)); } @@ -125,11 +125,10 @@ function computeConfig( let languageConfig = LanguageConfigurationRegistry.getLanguageConfiguration(languageId); if (!languageConfig) { - const validLanguageId = languageService.validateLanguageId(languageId); - if (!validLanguageId) { + if (!languageService.isRegisteredLanguageId(languageId)) { throw new Error('Unexpected languageId'); } - languageConfig = new ResolvedLanguageConfiguration(validLanguageId, {}); + languageConfig = new ResolvedLanguageConfiguration(languageId, {}); } const customizedConfig = getCustomizedLanguageConfig(languageConfig.languageId, configurationService); diff --git a/src/vs/editor/common/modes/nullMode.ts b/src/vs/editor/common/modes/nullMode.ts index e82fae45fa3..7a0ca7cb031 100644 --- a/src/vs/editor/common/modes/nullMode.ts +++ b/src/vs/editor/common/modes/nullMode.ts @@ -19,8 +19,6 @@ class NullStateImpl implements IState { export const NULL_STATE: IState = new NullStateImpl(); -export const NULL_MODE_ID = 'vs.editor.nullMode'; - export function nullTokenize(languageId: string, buffer: string, state: IState, deltaOffset: number): TokenizationResult { return new TokenizationResult([new Token(deltaOffset, '', languageId)], state); } diff --git a/src/vs/editor/common/services/languageService.ts b/src/vs/editor/common/services/languageService.ts index 9e8a30466fe..fcf287466e8 100644 --- a/src/vs/editor/common/services/languageService.ts +++ b/src/vs/editor/common/services/languageService.ts @@ -43,13 +43,16 @@ export interface ILanguageService { * An event emitted when a language is needed for the first time. */ onDidEncounterLanguage: Event; + /** * An event emitted when languages have changed. */ onDidChange: Event; + /** + * Check if `languageId` is registered. + */ isRegisteredLanguageId(languageId: string): boolean; - validateLanguageId(languageId: string): string | null; /** * Get a list of all registered languages. diff --git a/src/vs/editor/common/services/languageServiceImpl.ts b/src/vs/editor/common/services/languageServiceImpl.ts index 381c630ae0a..c9c8aa05c9d 100644 --- a/src/vs/editor/common/services/languageServiceImpl.ts +++ b/src/vs/editor/common/services/languageServiceImpl.ts @@ -80,10 +80,6 @@ export class LanguageService extends Disposable implements ILanguageService { return this._registry.isRegisteredLanguageId(languageId); } - public validateLanguageId(languageId: string | null): string | null { - return this._registry.validateLanguageId(languageId); - } - public getRegisteredLanguageIds(): string[] { return this._registry.getRegisteredLanguageIds(); } diff --git a/src/vs/editor/common/services/languagesRegistry.ts b/src/vs/editor/common/services/languagesRegistry.ts index 883268dae80..1ede10dfde8 100644 --- a/src/vs/editor/common/services/languagesRegistry.ts +++ b/src/vs/editor/common/services/languagesRegistry.ts @@ -12,12 +12,12 @@ import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { ILanguageIdCodec, LanguageId } from 'vs/editor/common/modes'; import { ModesRegistry, PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/modes/modesRegistry'; -import { NULL_MODE_ID } from 'vs/editor/common/modes/nullMode'; import { ILanguageExtensionPoint, ILanguageNameIdPair } from 'vs/editor/common/services/languageService'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; const hasOwnProperty = Object.prototype.hasOwnProperty; +const NULL_LANGUAGE_ID = 'vs.editor.nullLanguage'; export interface IResolvedLanguage { identifier: string; @@ -36,7 +36,7 @@ export class LanguageIdCodec implements ILanguageIdCodec { private readonly _languageToLanguageId = new Map(); constructor() { - this._register(NULL_MODE_ID, LanguageId.Null); + this._register(NULL_LANGUAGE_ID, LanguageId.Null); this._register(PLAINTEXT_LANGUAGE_ID, LanguageId.PlainText); this._nextLanguageId = 2; } @@ -59,7 +59,7 @@ export class LanguageIdCodec implements ILanguageIdCodec { } public decodeLanguageId(languageId: LanguageId): string { - return this._languageIdToLanguage[languageId] || NULL_MODE_ID; + return this._languageIdToLanguage[languageId] || NULL_LANGUAGE_ID; } } @@ -269,18 +269,6 @@ export class LanguagesRegistry extends Disposable { return hasOwnProperty.call(this._languages, languageId); } - public validateLanguageId(languageId: string | null | undefined): string | null { - if (!languageId || languageId === NULL_MODE_ID) { - return NULL_MODE_ID; - } - - if (!hasOwnProperty.call(this._languages, languageId)) { - return null; - } - - return languageId; - } - public getRegisteredLanguageIds(): string[] { return Object.keys(this._languages); } diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 33a3e0cdc8e..f9ed51497f5 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -64,11 +64,11 @@ export function onLanguage(languageId: string, callback: () => void): IDisposabl * Set the editing configuration for a language. */ export function setLanguageConfiguration(languageId: string, configuration: LanguageConfiguration): IDisposable { - const validLanguageId = StaticServices.languageService.get().validateLanguageId(languageId); - if (!validLanguageId) { + const languageService = StaticServices.languageService.get(); + if (!languageService.isRegisteredLanguageId(languageId)) { throw new Error(`Cannot set configuration for unknown language ${languageId}`); } - return LanguageConfigurationRegistry.register(validLanguageId, configuration, 100); + return LanguageConfigurationRegistry.register(languageId, configuration, 100); } /** @@ -380,14 +380,14 @@ export function registerTokensProviderFactory(languageId: string, factory: Token * or `registerDocumentRangeSemanticTokensProvider`. */ export function setTokensProvider(languageId: string, provider: TokensProvider | EncodedTokensProvider | Thenable): IDisposable { - const validLanguageId = StaticServices.languageService.get().validateLanguageId(languageId); - if (!validLanguageId) { + const languageService = StaticServices.languageService.get(); + if (!languageService.isRegisteredLanguageId(languageId)) { throw new Error(`Cannot set tokens provider for unknown language ${languageId}`); } if (isThenable(provider)) { return registerTokensProviderFactory(languageId, { create: () => provider }); } - return modes.TokenizationRegistry.register(languageId, createTokenizationSupportAdapter(validLanguageId, provider)); + return modes.TokenizationRegistry.register(languageId, createTokenizationSupportAdapter(languageId, provider)); } /** diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index d7920db1245..4bf13798231 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -775,9 +775,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; } - const validLanguageId = this._languageService.validateLanguageId(languageId); - if (validLanguageId) { - this._registrations.set(handle, LanguageConfigurationRegistry.register(validLanguageId, configuration, 100)); + if (this._languageService.isRegisteredLanguageId(languageId)) { + this._registrations.set(handle, LanguageConfigurationRegistry.register(languageId, configuration, 100)); } } diff --git a/src/vs/workbench/api/browser/mainThreadLanguages.ts b/src/vs/workbench/api/browser/mainThreadLanguages.ts index 0885cb84109..5351cc531d1 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguages.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguages.ts @@ -49,8 +49,7 @@ export class MainThreadLanguages implements MainThreadLanguagesShape { async $changeLanguage(resource: UriComponents, languageId: string): Promise { - const validLanguageId = this._languageService.validateLanguageId(languageId); - if (!validLanguageId || validLanguageId !== languageId) { + if (!this._languageService.isRegisteredLanguageId(languageId)) { return Promise.reject(new Error(`Unknown language id: ${languageId}`)); } diff --git a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts index 24b7cf9fdd9..48797f2f759 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts @@ -177,9 +177,8 @@ export class SnippetCompletionProvider implements CompletionItemProvider { // facing language with a name and the chance to have // snippets, else fall back to the outer language model.tokenizeIfCheap(position.lineNumber); - let languageId: string | null = model.getLanguageIdAtPosition(position.lineNumber, position.column); - languageId = this._languageService.validateLanguageId(languageId); - if (!languageId || !this._languageService.getLanguageName(languageId)) { + let languageId = model.getLanguageIdAtPosition(position.lineNumber, position.column); + if (!this._languageService.getLanguageName(languageId)){ languageId = model.getLanguageId(); } return languageId; diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts index ae2d95c2b22..748ce4083d6 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts @@ -228,11 +228,10 @@ class SnippetsService implements ISnippetsService { const result: Snippet[] = []; const promises: Promise[] = []; - const langName = this._languageService.validateLanguageId(languageId); - if (langName) { + if (this._languageService.isRegisteredLanguageId(languageId)) { for (const file of this._files.values()) { promises.push(file.load() - .then(file => file.select(langName, result)) + .then(file => file.select(languageId, result)) .catch(err => this._logService.error(err, file.location.toString())) ); } @@ -243,13 +242,12 @@ class SnippetsService implements ISnippetsService { getSnippetsSync(languageId: string, opts?: ISnippetGetOptions): Snippet[] { const result: Snippet[] = []; - const langName = this._languageService.validateLanguageId(languageId); - if (langName) { + if (this._languageService.isRegisteredLanguageId(languageId)) { for (const file of this._files.values()) { // kick off loading (which is a noop in case it's already loaded) // and optimistically collect snippets file.load().catch(_err => { /*ignore*/ }); - file.select(langName, result); + file.select(languageId, result); } } return this._filterSnippets(result, opts); diff --git a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts index 8204da66f23..b4f8e244b1d 100644 --- a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts +++ b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts @@ -103,9 +103,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex // never hurts to be too careful continue; } - const validLanguageId = this._languageService.validateLanguageId(language); - if (validLanguageId) { - embeddedLanguages[scope] = this._languageService.languageIdCodec.encodeLanguageId(validLanguageId); + if (this._languageService.isRegisteredLanguageId(language)) { + embeddedLanguages[scope] = this._languageService.languageIdCodec.encodeLanguageId(language); } } } @@ -130,8 +129,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex } let validLanguageId: string | null = null; - if (grammar.language) { - validLanguageId = this._languageService.validateLanguageId(grammar.language); + if (grammar.language && this._languageService.isRegisteredLanguageId(grammar.language)) { + validLanguageId = grammar.language; } this._grammarDefinitions.push({ @@ -258,7 +257,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex private _createFactory(languageId: string): ITokenizationSupportFactory { return { createTokenizationSupport: async (): Promise => { - if (!this._languageService.validateLanguageId(languageId)) { + if (!this._languageService.isRegisteredLanguageId(languageId)) { return null; } if (!this._canCreateGrammarFactory()) { @@ -375,7 +374,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex } public async createGrammar(languageId: string): Promise { - if (!this._languageService.validateLanguageId(languageId)) { + if (!this._languageService.isRegisteredLanguageId(languageId)) { return null; } const grammarFactory = await this._getOrCreateGrammarFactory();