diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index fca2e03894de5ee91d2f7556caaab13c8242c2cb..46c9257aac495f206193d6302b0582c140d3fa14 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -30,12 +30,21 @@ export const enum LanguageId { * @internal */ export class LanguageIdentifier { + + /** + * A string identifier. Unique across languages. e.g. 'javascript'. + */ public readonly language: string; + + /** + * A numeric identifier. Unique across languages. e.g. 5 + * Will vary at runtime based on registration order, etc. + */ public readonly id: LanguageId; - constructor(sid: string, iid: LanguageId) { - this.language = sid; - this.id = iid; + constructor(language: string, id: LanguageId) { + this.language = language; + this.id = id; } } diff --git a/src/vs/editor/common/services/languagesRegistry.ts b/src/vs/editor/common/services/languagesRegistry.ts index 88eeb2a31971509d66f6ba5fc58bcc50c4fdd79d..6c14559a26d8659b18b214f9f737224affd6b35c 100644 --- a/src/vs/editor/common/services/languagesRegistry.ts +++ b/src/vs/editor/common/services/languagesRegistry.ts @@ -5,7 +5,6 @@ 'use strict'; import { onUnexpectedError } from 'vs/base/common/errors'; -import Event, { Emitter } from 'vs/base/common/event'; import * as mime from 'vs/base/common/mime'; import * as strings from 'vs/base/common/strings'; import { Registry } from 'vs/platform/platform'; @@ -18,7 +17,7 @@ import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/co var hasOwnProperty = Object.prototype.hasOwnProperty; export interface IResolvedLanguage { - id: LanguageId; + identifier: LanguageIdentifier; name: string; mimetypes: string[]; aliases: string[]; @@ -31,22 +30,19 @@ export class LanguagesRegistry { private _nextLanguageId: number; private _languages: { [id: string]: IResolvedLanguage; }; + private _languageIds: string[]; - private mime2LanguageId: { [mimeType: string]: string; }; - private name2LanguageId: { [name: string]: string; }; - private lowerName2Id: { [name: string]: string; }; - private languageIds: string[]; - - private _onDidAddModes: Emitter = new Emitter(); - public onDidAddModes: Event = this._onDidAddModes.event; + private _mimeTypesMap: { [mimeType: string]: LanguageIdentifier; }; + private _nameMap: { [name: string]: LanguageIdentifier; }; + private _lowercaseNameMap: { [name: string]: LanguageIdentifier; }; constructor(useModesRegistry = true) { this._nextLanguageId = 1; this._languages = {}; - this.mime2LanguageId = {}; - this.name2LanguageId = {}; - this.lowerName2Id = {}; - this.languageIds = []; + this._mimeTypesMap = {}; + this._nameMap = {}; + this._lowercaseNameMap = {}; + this._languageIds = []; if (useModesRegistry) { this._registerLanguages(ModesRegistry.getLanguages()); @@ -59,31 +55,28 @@ export class LanguagesRegistry { return; } - let addedModes: string[] = []; for (let i = 0; i < desc.length; i++) { this._registerLanguage(desc[i]); - addedModes.push(desc[i].id); } // Rebuild fast path maps - this.mime2LanguageId = {}; - this.name2LanguageId = {}; - this.lowerName2Id = {}; + this._mimeTypesMap = {}; + this._nameMap = {}; + this._lowercaseNameMap = {}; Object.keys(this._languages).forEach((langId) => { let language = this._languages[langId]; if (language.name) { - this.name2LanguageId[language.name] = langId; + this._nameMap[language.name] = language.identifier; } language.aliases.forEach((alias) => { - this.lowerName2Id[alias.toLowerCase()] = langId; + this._lowercaseNameMap[alias.toLowerCase()] = language.identifier; }); language.mimetypes.forEach((mimetype) => { - this.mime2LanguageId[mimetype] = langId; + this._mimeTypesMap[mimetype] = language.identifier; }); }); Registry.as(Extensions.Configuration).registerOverrideIdentifiers(ModesRegistry.getLanguages().map(language => language.id)); - this._onDidAddModes.fire(addedModes); } private _registerLanguage(lang: ILanguageExtensionPoint): void { @@ -95,7 +88,7 @@ export class LanguagesRegistry { } else { let languageId = this._nextLanguageId++; resolvedLanguage = { - id: languageId, + identifier: new LanguageIdentifier(langId, languageId), name: null, mimetypes: [], aliases: [], @@ -103,7 +96,7 @@ export class LanguagesRegistry { filenames: [], configurationFiles: [] }; - this.languageIds[languageId] = langId; + this._languageIds[languageId] = langId; this._languages[langId] = resolvedLanguage; } @@ -203,7 +196,7 @@ export class LanguagesRegistry { public isRegisteredMode(mimetypeOrModeId: string): boolean { // Is this a known mime type ? - if (hasOwnProperty.call(this.mime2LanguageId, mimetypeOrModeId)) { + if (hasOwnProperty.call(this._mimeTypesMap, mimetypeOrModeId)) { return true; } // Is this a known mode id ? @@ -215,7 +208,7 @@ export class LanguagesRegistry { } public getRegisteredLanguageNames(): string[] { - return Object.keys(this.name2LanguageId); + return Object.keys(this._nameMap); } public getLanguageName(modeId: string): string { @@ -226,7 +219,10 @@ export class LanguagesRegistry { } public getModeIdForLanguageNameLowercase(languageNameLower: string): string { - return this.lowerName2Id[languageNameLower] || null; + if (!hasOwnProperty.call(this._lowercaseNameMap, languageNameLower)) { + return null; + } + return this._lowercaseNameMap[languageNameLower].language; } public getConfigurationFiles(modeId: string): string[] { @@ -236,30 +232,28 @@ export class LanguagesRegistry { return this._languages[modeId].configurationFiles || []; } - public getMimeForMode(theModeId: string): string { - let keys = Object.keys(this.mime2LanguageId); - for (let i = 0, len = keys.length; i < len; i++) { - let _mime = keys[i]; - let modeId = this.mime2LanguageId[_mime]; - if (modeId === theModeId) { - return _mime; - } + public getMimeForMode(modeId: string): string { + if (!hasOwnProperty.call(this._languages, modeId)) { + return null; } - - return null; + const language = this._languages[modeId]; + return (language.mimetypes[0] || null); } - public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIdsOrName: string): string[] { - if (!commaSeparatedMimetypesOrCommaSeparatedIdsOrName) { + public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string): string[] { + if (!commaSeparatedMimetypesOrCommaSeparatedIds) { return []; } return ( - commaSeparatedMimetypesOrCommaSeparatedIdsOrName. + commaSeparatedMimetypesOrCommaSeparatedIds. split(','). - map((mimeTypeOrIdOrName) => mimeTypeOrIdOrName.trim()). - map((mimeTypeOrIdOrName) => { - return this.mime2LanguageId[mimeTypeOrIdOrName] || mimeTypeOrIdOrName; + map((mimeTypeOrId) => mimeTypeOrId.trim()). + map((mimeTypeOrId) => { + if (hasOwnProperty.call(this._mimeTypesMap, mimeTypeOrId)) { + return this._mimeTypesMap[mimeTypeOrId].language; + } + return mimeTypeOrId; }). filter((modeId) => { return hasOwnProperty.call(this._languages, modeId); @@ -276,7 +270,7 @@ export class LanguagesRegistry { if (typeof _modeId === 'string') { modeId = _modeId; } else { - modeId = this.languageIds[_modeId]; + modeId = this._languageIds[_modeId]; if (!modeId) { return null; } @@ -285,15 +279,15 @@ export class LanguagesRegistry { if (!hasOwnProperty.call(this._languages, modeId)) { return null; } - return new LanguageIdentifier(modeId, this._languages[modeId].id); + return this._languages[modeId].identifier; } public getModeIdsFromLanguageName(languageName: string): string[] { if (!languageName) { return []; } - if (hasOwnProperty.call(this.name2LanguageId, languageName)) { - return [this.name2LanguageId[languageName]]; + if (hasOwnProperty.call(this._nameMap, languageName)) { + return [this._nameMap[languageName].language]; } return []; } @@ -307,24 +301,18 @@ export class LanguagesRegistry { } public getExtensions(languageName: string): string[] { - let languageId = this.name2LanguageId[languageName]; - if (!languageId) { - return []; - } - if (!hasOwnProperty.call(this._languages, languageId)) { + if (!hasOwnProperty.call(this._nameMap, languageName)) { return []; } - return this._languages[languageId].extensions; + const languageId = this._nameMap[languageName]; + return this._languages[languageId.language].extensions; } public getFilenames(languageName: string): string[] { - let languageId = this.name2LanguageId[languageName]; - if (!languageId) { - return []; - } - if (!hasOwnProperty.call(this._languages, languageId)) { + if (!hasOwnProperty.call(this._nameMap, languageName)) { return []; } - return this._languages[languageId].filenames; + const languageId = this._nameMap[languageName]; + return this._languages[languageId.language].filenames; } } diff --git a/src/vs/editor/common/services/modeService.ts b/src/vs/editor/common/services/modeService.ts index 558d3030ed5c7a27a99395277e1ecd84c59305c6..9f6810b59f39938cde4cd56a89dcddccba480f97 100644 --- a/src/vs/editor/common/services/modeService.ts +++ b/src/vs/editor/common/services/modeService.ts @@ -41,7 +41,6 @@ export interface IValidLanguageExtensionPoint { export interface IModeService { _serviceBrand: any; - onDidAddModes: Event; onDidCreateMode: Event; // --- reading diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts index 9516075e7ff896dbbb3f860d5be613999c9edbd6..e03585bdb33e7503188c1b90c44e93777b6bc733 100644 --- a/src/vs/editor/common/services/modeServiceImpl.ts +++ b/src/vs/editor/common/services/modeServiceImpl.ts @@ -77,21 +77,16 @@ export const languagesExtPoint: IExtensionPoint = Ext export class ModeServiceImpl implements IModeService { public _serviceBrand: any; - private _instantiatedModes: { [modeId: string]: IMode; }; + private readonly _instantiatedModes: { [modeId: string]: IMode; }; + private readonly _registry: LanguagesRegistry; - private _registry: LanguagesRegistry; - - private _onDidAddModes: Emitter = new Emitter(); - public onDidAddModes: Event = this._onDidAddModes.event; - - private _onDidCreateMode: Emitter = new Emitter(); - public onDidCreateMode: Event = this._onDidCreateMode.event; + private readonly _onDidCreateMode: Emitter = new Emitter(); + public readonly onDidCreateMode: Event = this._onDidCreateMode.event; constructor() { this._instantiatedModes = {}; this._registry = new LanguagesRegistry(); - this._registry.onDidAddModes((modes) => this._onDidAddModes.fire(modes)); } protected _onReady(): TPromise { @@ -195,7 +190,7 @@ export class ModeServiceImpl implements IModeService { }).done(null, onUnexpectedError); return r; } - return undefined; + return null; } public getOrCreateMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): TPromise {