Remove LanguageIdentifier and ensure tests dispose instantiated LanguagesRegistry objects

This commit is contained in:
Alex Dima
2021-10-18 10:29:16 +02:00
parent 74541dceec
commit 11862795ea
228 changed files with 2402 additions and 1667 deletions

View File

@@ -13,7 +13,7 @@ import * as types from 'vs/base/common/types';
import { equals as equalArray } from 'vs/base/common/arrays';
import { URI } from 'vs/base/common/uri';
import { TokenizationResult, TokenizationResult2 } from 'vs/editor/common/core/token';
import { IState, ITokenizationSupport, LanguageId, TokenMetadata, TokenizationRegistry, StandardTokenType, LanguageIdentifier } from 'vs/editor/common/modes';
import { IState, ITokenizationSupport, LanguageId, TokenMetadata, TokenizationRegistry, StandardTokenType } from 'vs/editor/common/modes';
import { nullTokenize2 } from 'vs/editor/common/modes/nullMode';
import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -34,8 +34,8 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/
export abstract class AbstractTextMateService extends Disposable implements ITextMateService {
public _serviceBrand: undefined;
private readonly _onDidEncounterLanguage: Emitter<LanguageId> = this._register(new Emitter<LanguageId>());
public readonly onDidEncounterLanguage: Event<LanguageId> = this._onDidEncounterLanguage.event;
private readonly _onDidEncounterLanguage: Emitter<string> = this._register(new Emitter<string>());
public readonly onDidEncounterLanguage: Event<string> = this._onDidEncounterLanguage.event;
private readonly _styleElement: HTMLStyleElement;
private readonly _createdModes: string[];
@@ -51,7 +51,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
protected _currentTokenColorMap: string[] | null;
constructor(
@IModeService private readonly _modeService: IModeService,
@IModeService protected readonly _modeService: IModeService,
@IWorkbenchThemeService private readonly _themeService: IWorkbenchThemeService,
@IExtensionResourceLoaderService protected readonly _extensionResourceLoaderService: IExtensionResourceLoaderService,
@INotificationService private readonly _notificationService: INotificationService,
@@ -103,9 +103,9 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
// never hurts to be too careful
continue;
}
let languageIdentifier = this._modeService.getLanguageIdentifier(language);
if (languageIdentifier) {
embeddedLanguages[scope] = languageIdentifier.id;
const validLanguageId = this._modeService.validateLanguageId(language);
if (validLanguageId) {
embeddedLanguages[scope] = this._modeService.languageIdCodec.encodeLanguageId(validLanguageId);
}
}
}
@@ -129,14 +129,14 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
}
}
let languageIdentifier: LanguageIdentifier | null = null;
let validLanguageId: string | null = null;
if (grammar.language) {
languageIdentifier = this._modeService.getLanguageIdentifier(grammar.language);
validLanguageId = this._modeService.validateLanguageId(grammar.language);
}
this._grammarDefinitions.push({
location: grammarLocation,
language: languageIdentifier ? languageIdentifier.id : undefined,
language: validLanguageId ? validLanguageId : undefined,
scopeName: grammar.scopeName,
embeddedLanguages: embeddedLanguages,
tokenTypes: tokenTypes,
@@ -173,9 +173,9 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
}
TokenizationRegistry.setColorMap([null!, defaultForeground, defaultBackground]);
this._modeService.onDidEncounterLanguage((languageIdentifier) => {
this._createdModes.push(languageIdentifier.language);
this._registerDefinitionIfAvailable(languageIdentifier.language);
this._modeService.onDidEncounterLanguage((languageId) => {
this._createdModes.push(languageId);
this._registerDefinitionIfAvailable(languageId);
});
}
@@ -252,35 +252,35 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
return this._grammarFactory;
}
private _registerDefinitionIfAvailable(modeId: string): void {
const languageIdentifier = this._modeService.getLanguageIdentifier(modeId);
if (!languageIdentifier) {
private _registerDefinitionIfAvailable(languageId: string): void {
if (!this._modeService.validateLanguageId(languageId)) {
return;
}
if (!this._canCreateGrammarFactory()) {
return;
}
const languageId = languageIdentifier.id;
const encodedLanguageId = this._modeService.languageIdCodec.encodeLanguageId(languageId);
// Here we must register the promise ASAP (without yielding!)
this._tokenizersRegistrations.push(TokenizationRegistry.registerPromise(modeId, (async () => {
this._tokenizersRegistrations.push(TokenizationRegistry.registerPromise(languageId, (async () => {
try {
const grammarFactory = await this._getOrCreateGrammarFactory();
if (!grammarFactory.has(languageId)) {
return null;
}
const r = await grammarFactory.createGrammar(languageId);
const r = await grammarFactory.createGrammar(languageId, encodedLanguageId);
if (!r.grammar) {
return null;
}
const tokenization = new TMTokenization(r.grammar, r.initialState, r.containsEmbeddedLanguages);
tokenization.onDidEncounterLanguage((languageId) => {
if (!this._encounteredLanguages[languageId]) {
this._encounteredLanguages[languageId] = true;
tokenization.onDidEncounterLanguage((encodedLanguageId) => {
if (!this._encounteredLanguages[encodedLanguageId]) {
const languageId = this._modeService.languageIdCodec.decodeLanguageId(encodedLanguageId);
this._encounteredLanguages[encodedLanguageId] = true;
this._onDidEncounterLanguage.fire(languageId);
}
});
return new TMTokenizationSupport(languageIdentifier, tokenization, this._configurationService);
return new TMTokenizationSupport(languageId, encodedLanguageId, tokenization, this._configurationService);
} catch (err) {
onUnexpectedError(err);
return null;
@@ -370,16 +370,16 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
return true;
}
public async createGrammar(modeId: string): Promise<IGrammar | null> {
const languageId = this._modeService.getLanguageIdentifier(modeId);
if (!languageId) {
public async createGrammar(languageId: string): Promise<IGrammar | null> {
if (!this._modeService.validateLanguageId(languageId)) {
return null;
}
const grammarFactory = await this._getOrCreateGrammarFactory();
if (!grammarFactory.has(languageId.id)) {
if (!grammarFactory.has(languageId)) {
return null;
}
const { grammar } = await grammarFactory.createGrammar(languageId.id);
const encodedLanguageId = this._modeService.languageIdCodec.encodeLanguageId(languageId);
const { grammar } = await grammarFactory.createGrammar(languageId, encodedLanguageId);
return grammar;
}
@@ -413,24 +413,27 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
}
class TMTokenizationSupport implements ITokenizationSupport {
private readonly _languageId: LanguageId;
private readonly _languageId: string;
private readonly _encodedLanguageId: LanguageId;
private readonly _actual: TMTokenization;
private _maxTokenizationLineLength: number;
constructor(
languageId: LanguageIdentifier,
languageId: string,
encodedLanguageId: LanguageId,
actual: TMTokenization,
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
this._languageId = languageId.id;
this._languageId = languageId;
this._encodedLanguageId = encodedLanguageId;
this._actual = actual;
this._maxTokenizationLineLength = this._configurationService.getValue<number>('editor.maxTokenizationLineLength', {
overrideIdentifier: languageId.language
overrideIdentifier: this._languageId
});
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('editor.maxTokenizationLineLength')) {
this._maxTokenizationLineLength = this._configurationService.getValue<number>('editor.maxTokenizationLineLength', {
overrideIdentifier: languageId.language
overrideIdentifier: this._languageId
});
}
});
@@ -451,7 +454,7 @@ class TMTokenizationSupport implements ITokenizationSupport {
// Do not attempt to tokenize if a line is too long
if (line.length >= this._maxTokenizationLineLength) {
return nullTokenize2(this._languageId, line, state, offsetDelta);
return nullTokenize2(this._encodedLanguageId, line, state, offsetDelta);
}
return this._actual.tokenize2(line, state);