Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View File

@@ -2,13 +2,11 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICommandService, ICommandEvent, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { Event, Emitter } from 'vs/base/common/event';
import { Event, Emitter, filterEvent, toPromise } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { ILogService } from 'vs/platform/log/common/log';
@@ -30,38 +28,42 @@ export class CommandService extends Disposable implements ICommandService {
this._extensionService.whenInstalledExtensionsRegistered().then(value => this._extensionHostIsReady = value);
}
executeCommand<T>(id: string, ...args: any[]): TPromise<T> {
executeCommand<T>(id: string, ...args: any[]): Promise<T> {
this._logService.trace('CommandService#executeCommand', id);
// we always send an activation event, but
// we don't wait for it when the extension
// host didn't yet start and the command is already registered
const activation = this._extensionService.activateByEvent(`onCommand:${id}`);
const activation: Thenable<any> = this._extensionService.activateByEvent(`onCommand:${id}`);
const commandIsRegistered = !!CommandsRegistry.getCommand(id);
if (!this._extensionHostIsReady && commandIsRegistered) {
return this._tryExecuteCommand(id, args);
} else {
let waitFor: TPromise<any> = activation;
let waitFor = activation;
if (!commandIsRegistered) {
waitFor = TPromise.join([activation, this._extensionService.activateByEvent(`*`)]);
waitFor = Promise.race<any>([
// race activation events against command registration
Promise.all([activation, this._extensionService.activateByEvent(`*`)]),
toPromise(filterEvent(CommandsRegistry.onDidRegisterCommand, e => e === id)),
]);
}
return waitFor.then(_ => this._tryExecuteCommand(id, args));
return (waitFor as Promise<any>).then(_ => this._tryExecuteCommand(id, args));
}
}
private _tryExecuteCommand(id: string, args: any[]): TPromise<any> {
private _tryExecuteCommand(id: string, args: any[]): Promise<any> {
const command = CommandsRegistry.getCommand(id);
if (!command) {
return TPromise.wrapError(new Error(`command '${id}' not found`));
return Promise.reject(new Error(`command '${id}' not found`));
}
try {
this._onWillExecuteCommand.fire({ commandId: id });
const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler].concat(args));
return TPromise.as(result);
return Promise.resolve(result);
} catch (err) {
return TPromise.wrapError(err);
return Promise.reject(err);
}
}
}

View File

@@ -2,11 +2,8 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { IDisposable } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/workbench/services/commands/common/commandService';
import { IExtensionService, ExtensionPointContribution, IExtensionDescription, ProfileSession } from 'vs/workbench/services/extensions/common/extensions';
@@ -22,27 +19,35 @@ class SimpleExtensionService implements IExtensionService {
return this._onDidRegisterExtensions.event;
}
onDidChangeExtensionsStatus = null;
activateByEvent(activationEvent: string): TPromise<void> {
onWillActivateByEvent = null;
onDidChangeResponsiveChange = null;
activateByEvent(activationEvent: string): Promise<void> {
return this.whenInstalledExtensionsRegistered().then(() => { });
}
whenInstalledExtensionsRegistered(): TPromise<boolean> {
return TPromise.as(true);
whenInstalledExtensionsRegistered(): Promise<boolean> {
return Promise.resolve(true);
}
readExtensionPointContributions<T>(extPoint: IExtensionPoint<T>): TPromise<ExtensionPointContribution<T>[]> {
return TPromise.as([]);
readExtensionPointContributions<T>(extPoint: IExtensionPoint<T>): Promise<ExtensionPointContribution<T>[]> {
return Promise.resolve([]);
}
getExtensionsStatus() {
return undefined;
}
getExtensions(): TPromise<IExtensionDescription[]> {
return TPromise.wrap([]);
getExtensions(): Promise<IExtensionDescription[]> {
return Promise.resolve([]);
}
getExtension() {
return Promise.resolve(undefined);
}
canProfileExtensionHost() {
return false;
}
startExtensionHostProfile(): TPromise<ProfileSession> {
startExtensionHostProfile(): Promise<ProfileSession> {
throw new Error('Not implemented');
}
getInspectPort(): number {
return 0;
}
restartExtensionHost(): void {
}
startExtensionHost(): void {
@@ -63,12 +68,12 @@ suite('CommandService', function () {
commandRegistration.dispose();
});
test('activateOnCommand', function () {
test('activateOnCommand', () => {
let lastEvent: string;
let service = new CommandService(new InstantiationService(), new class extends SimpleExtensionService {
activateByEvent(activationEvent: string): TPromise<void> {
activateByEvent(activationEvent: string): Promise<void> {
lastEvent = activationEvent;
return super.activateByEvent(activationEvent);
}
@@ -84,13 +89,17 @@ suite('CommandService', function () {
});
});
test('fwd activation error', function () {
test('fwd activation error', async function () {
let service = new CommandService(new InstantiationService(), new class extends SimpleExtensionService {
activateByEvent(activationEvent: string): TPromise<void> {
return TPromise.wrapError<void>(new Error('bad_activate'));
const extensionService = new class extends SimpleExtensionService {
activateByEvent(activationEvent: string): Promise<void> {
return Promise.reject(new Error('bad_activate'));
}
}, new NullLogService());
};
let service = new CommandService(new InstantiationService(), extensionService, new NullLogService());
await extensionService.whenInstalledExtensionsRegistered();
return service.executeCommand('foo').then(() => assert.ok(false), err => {
assert.equal(err.message, 'bad_activate');
@@ -104,7 +113,7 @@ suite('CommandService', function () {
let service = new CommandService(new InstantiationService(), new class extends SimpleExtensionService {
whenInstalledExtensionsRegistered() {
return new TPromise<boolean>(_resolve => { /*ignore*/ });
return new Promise<boolean>(_resolve => { /*ignore*/ });
}
}, new NullLogService());
@@ -117,7 +126,7 @@ suite('CommandService', function () {
let callCounter = 0;
let resolveFunc: Function;
const whenInstalledExtensionsRegistered = new TPromise<boolean>(_resolve => { resolveFunc = _resolve; });
const whenInstalledExtensionsRegistered = new Promise<boolean>(_resolve => { resolveFunc = _resolve; });
let service = new CommandService(new InstantiationService(), new class extends SimpleExtensionService {
whenInstalledExtensionsRegistered() {
@@ -136,4 +145,39 @@ suite('CommandService', function () {
assert.equal(callCounter, 1);
});
});
test('Stop waiting for * extensions to activate when trigger is satisfied #62457', function () {
let callCounter = 0;
let dispoables: IDisposable[] = [];
let events: string[] = [];
let service = new CommandService(new InstantiationService(), new class extends SimpleExtensionService {
activateByEvent(event: string): Promise<void> {
events.push(event);
if (event === '*') {
return new Promise(() => { }); //forever promise...
}
if (event.indexOf('onCommand:') === 0) {
return new Promise(resolve => {
setTimeout(() => {
let reg = CommandsRegistry.registerCommand(event.substr('onCommand:'.length), () => {
callCounter += 1;
});
dispoables.push(reg);
resolve();
}, 0);
});
}
return Promise.resolve();
}
}, new NullLogService());
return service.executeCommand('farboo').then(() => {
assert.equal(callCounter, 1);
assert.deepEqual(events.sort(), ['*', 'onCommand:farboo'].sort());
dispose(dispoables);
});
});
});