diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 5cf2b340070..d4a1359982c 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -121,64 +121,59 @@ export interface IMenuService { createMenu(id: MenuId, scopedKeybindingService: IContextKeyService): IMenu; } +export type ICommandsMap = Map; + export interface IMenuRegistry { addCommand(userCommand: ICommandAction): IDisposable; - getCommand(id: string): ICommandAction; + getCommand(id: string): ICommandAction | undefined; getCommands(): ICommandsMap; appendMenuItem(menu: MenuId, item: IMenuItem | ISubmenuItem): IDisposable; getMenuItems(loc: MenuId): Array; readonly onDidChangeMenu: Event; } -export interface ICommandsMap { - [id: string]: ICommandAction; -} - export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry { - private readonly _commands: { [id: string]: ICommandAction } = Object.create(null); - private readonly _menuItems: { [loc: number]: Array } = Object.create(null); + private readonly _commands = new Map(); + private readonly _menuItems = new Map>(); private readonly _onDidChangeMenu = new Emitter(); readonly onDidChangeMenu: Event = this._onDidChangeMenu.event; addCommand(command: ICommandAction): IDisposable { - this._commands[command.id] = command; + this._commands.set(command.id, command); this._onDidChangeMenu.fire(MenuId.CommandPalette); return { dispose: () => { - if (delete this._commands[command.id]) { + if (this._commands.delete(command.id)) { this._onDidChangeMenu.fire(MenuId.CommandPalette); } } }; } - getCommand(id: string): ICommandAction { - return this._commands[id]; + getCommand(id: string): ICommandAction | undefined { + return this._commands.get(id); } getCommands(): ICommandsMap { - const result: ICommandsMap = Object.create(null); - for (const key in this._commands) { - result[key] = this.getCommand(key); - } - return result; + return new Map(this._commands.entries()); } appendMenuItem(id: MenuId, item: IMenuItem | ISubmenuItem): IDisposable { - let array = this._menuItems[id]; + let array = this._menuItems.get(id); if (!array) { - this._menuItems[id] = array = [item]; + array = [item]; + this._menuItems.set(id, array); } else { array.push(item); } this._onDidChangeMenu.fire(id); return { dispose: () => { - const idx = array.indexOf(item); + const idx = array!.indexOf(item); if (idx >= 0) { - array.splice(idx, 1); + array!.splice(idx, 1); this._onDidChangeMenu.fire(id); } } @@ -186,7 +181,7 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry { } getMenuItems(id: MenuId): Array { - const result = (this._menuItems[id] || []).slice(0); + const result = (this._menuItems.get(id) || []).slice(0); if (id === MenuId.CommandPalette) { // CommandPalette is special because it shows @@ -207,9 +202,9 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry { set.add(alt.id); } } - for (let id in this._commands) { + for (const [id, command] of this._commands) { if (!set.has(id)) { - result.push({ command: this._commands[id] }); + result.push({ command }); } } } diff --git a/src/vs/platform/commands/common/commands.ts b/src/vs/platform/commands/common/commands.ts index 91541847a17..7605efb866d 100644 --- a/src/vs/platform/commands/common/commands.ts +++ b/src/vs/platform/commands/common/commands.ts @@ -22,9 +22,7 @@ export interface ICommandService { executeCommand(commandId: string, ...args: any[]): Promise; } -export interface ICommandsMap { - [id: string]: ICommand; -} +export type ICommandsMap = Map; export interface ICommandHandler { (accessor: ServicesAccessor, ...args: any[]): void; @@ -122,10 +120,13 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR } getCommands(): ICommandsMap { - const result: ICommandsMap = Object.create(null); - this._commands.forEach((value, key) => { - result[key] = this.getCommand(key)!; - }); + const result = new Map(); + for (const key of this._commands.keys()) { + const command = this.getCommand(key); + if (command) { + result.set(key, command); + } + } return result; } }; diff --git a/src/vs/platform/commands/test/commands.test.ts b/src/vs/platform/commands/test/commands.test.ts index 02e019154ff..33c613935fb 100644 --- a/src/vs/platform/commands/test/commands.test.ts +++ b/src/vs/platform/commands/test/commands.test.ts @@ -68,10 +68,10 @@ suite('Command Tests', function () { } }); - CommandsRegistry.getCommands()['test'].handler.apply(undefined, [undefined!, 'string']); - CommandsRegistry.getCommands()['test2'].handler.apply(undefined, [undefined!, 'string']); - assert.throws(() => CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined!, 'string'])); - assert.equal(CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined!, 1]), true); + CommandsRegistry.getCommands().get('test')!.handler.apply(undefined, [undefined!, 'string']); + CommandsRegistry.getCommands().get('test2')!.handler.apply(undefined, [undefined!, 'string']); + assert.throws(() => CommandsRegistry.getCommands().get('test3')!.handler.apply(undefined, [undefined!, 'string'])); + assert.equal(CommandsRegistry.getCommands().get('test3')!.handler.apply(undefined, [undefined!, 1]), true); }); }); diff --git a/src/vs/platform/keybinding/common/keybindingResolver.ts b/src/vs/platform/keybinding/common/keybindingResolver.ts index 3e3306d8747..2b36653666d 100644 --- a/src/vs/platform/keybinding/common/keybindingResolver.ts +++ b/src/vs/platform/keybinding/common/keybindingResolver.ts @@ -334,10 +334,10 @@ export class KeybindingResolver { } unboundCommands.push(id); }; - for (const id in MenuRegistry.getCommands()) { + for (const id of MenuRegistry.getCommands().keys()) { addCommand(id, true); } - for (const id in CommandsRegistry.getCommands()) { + for (const id of CommandsRegistry.getCommands().keys()) { addCommand(id, false); } diff --git a/src/vs/workbench/api/browser/mainThreadCommands.ts b/src/vs/workbench/api/browser/mainThreadCommands.ts index fcf82fcfdb8..2f4d043f048 100644 --- a/src/vs/workbench/api/browser/mainThreadCommands.ts +++ b/src/vs/workbench/api/browser/mainThreadCommands.ts @@ -36,10 +36,9 @@ export class MainThreadCommands implements MainThreadCommandsShape { return this._proxy.$getContributedCommandHandlerDescriptions().then(result => { // add local commands const commands = CommandsRegistry.getCommands(); - for (let id in commands) { - let { description } = commands[id]; - if (description) { - result[id] = description; + for (const [id, command] of commands) { + if (command.description) { + result[id] = command.description; } } @@ -79,7 +78,7 @@ export class MainThreadCommands implements MainThreadCommandsShape { } $getCommands(): Promise { - return Promise.resolve(Object.keys(CommandsRegistry.getCommands())); + return Promise.resolve([...CommandsRegistry.getCommands().keys()]); } } diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index 60509939c87..37ead9db496 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -675,8 +675,8 @@ function updateSchema() { }; const allCommands = CommandsRegistry.getCommands(); - for (let commandId in allCommands) { - const commandDescription = allCommands[commandId].description; + for (const [commandId, command] of allCommands) { + const commandDescription = command.description; addKnownCommand(commandId, commandDescription ? commandDescription.description : undefined); @@ -704,7 +704,7 @@ function updateSchema() { } const menuCommands = MenuRegistry.getCommands(); - for (let commandId in menuCommands) { + for (const commandId of menuCommands.keys()) { addKnownCommand(commandId); } } diff --git a/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts b/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts index 0f80e25b1d2..5dde33ee560 100644 --- a/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts +++ b/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts @@ -210,7 +210,7 @@ export class KeybindingsEditorModel extends EditorModel { } private static toKeybindingEntry(command: string, keybindingItem: ResolvedKeybindingItem, workbenchActionsRegistry: IWorkbenchActionRegistry, editorActions: { [id: string]: string; }): IKeybindingItem { - const menuCommand = MenuRegistry.getCommand(command); + const menuCommand = MenuRegistry.getCommand(command)!; const editorActionLabel = editorActions[command]; return { keybinding: keybindingItem.resolvedKeybinding, diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 8eb327c11c7..779c40e9656 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -68,10 +68,11 @@ suite('ExtHostLanguageFeatureCommands', function () { instantiationService.stub(ICommandService, { _serviceBrand: undefined, executeCommand(id: string, args: any): any { - if (!CommandsRegistry.getCommands()[id]) { + const command = CommandsRegistry.getCommands().get(id); + if (!command) { return Promise.reject(new Error(id + ' NOT known')); } - let { handler } = CommandsRegistry.getCommands()[id]; + const { handler } = command; return Promise.resolve(instantiationService.invokeFunction(handler, args)); } });