提交 86380f91 编写于 作者: B Benjamin Pasero

Merge branch 'master' into ben/global-storage

......@@ -621,6 +621,7 @@
"./vs/workbench/parts/tasks/common/taskTemplates.ts",
"./vs/workbench/parts/tasks/common/tasks.ts",
"./vs/workbench/parts/tasks/electron-browser/jsonSchemaCommon.ts",
"./vs/workbench/parts/tasks/electron-browser/runAutomaticTasks.ts",
"./vs/workbench/parts/tasks/node/tasks.ts",
"./vs/workbench/parts/terminal/browser/terminalTab.ts",
"./vs/workbench/parts/terminal/browser/terminalWidgetManager.ts",
......
......@@ -14,6 +14,7 @@ import { fromNodeEventEmitter, anyEvent, mapEvent, debounceEvent } from 'vs/base
import * as objects from 'vs/base/common/objects';
import { Schemas } from 'vs/base/common/network';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { rimraf } from 'vs/base/node/pfs';
export class ExtensionsLifecycle extends Disposable {
......@@ -26,15 +27,15 @@ export class ExtensionsLifecycle extends Disposable {
super();
}
postUninstall(extension: ILocalExtension): Thenable<void> {
async postUninstall(extension: ILocalExtension): Promise<void> {
const script = this.parseScript(extension, 'uninstall');
if (script) {
this.logService.info(extension.identifier.id, `Running post uninstall script`);
return this.processesLimiter.queue(() =>
await this.processesLimiter.queue(() =>
this.runLifecycleHook(script.script, 'uninstall', script.args, true, extension)
.then(() => this.logService.info(extension.identifier.id, `Finished running post uninstall script`), err => this.logService.error(extension.identifier.id, `Failed to run post uninstall script: ${err}`)));
}
return Promise.resolve();
return rimraf(this.getExtensionStoragePath(extension)).then(null, e => this.logService.error('Error while removing extension storage path', e));
}
postInstall(extension: ILocalExtension): Thenable<void> {
......@@ -66,10 +67,9 @@ export class ExtensionsLifecycle extends Disposable {
}
private runLifecycleHook(lifecycleHook: string, lifecycleType: string, args: string[], timeout: boolean, extension: ILocalExtension): Thenable<void> {
const extensionStoragePath = posix.join(this.environmentService.globalStorageHome, extension.identifier.id.toLocaleLowerCase());
return new Promise<void>((c, e) => {
const extensionLifecycleProcess = this.start(lifecycleHook, lifecycleType, args, extension, extensionStoragePath);
const extensionLifecycleProcess = this.start(lifecycleHook, lifecycleType, args, extension);
let timeoutHandler;
const onexit = (error?: string) => {
......@@ -105,12 +105,12 @@ export class ExtensionsLifecycle extends Disposable {
});
}
private start(uninstallHook: string, lifecycleType: string, args: string[], extension: ILocalExtension, extensionStoragePath: string): ChildProcess {
private start(uninstallHook: string, lifecycleType: string, args: string[], extension: ILocalExtension): ChildProcess {
const opts = {
silent: true,
execArgv: undefined,
env: objects.mixin(objects.deepClone(process.env), {
VSCODE_EXTENSION_STORAGE_LOCATION: extensionStoragePath
VSCODE_EXTENSION_STORAGE_LOCATION: this.getExtensionStoragePath(extension)
})
};
const extensionUninstallProcess = fork(uninstallHook, [`--type=extension-post-${lifecycleType}`, ...args], opts);
......@@ -147,4 +147,8 @@ export class ExtensionsLifecycle extends Disposable {
return extensionUninstallProcess;
}
private getExtensionStoragePath(extension: ILocalExtension): string {
return posix.join(this.environmentService.globalStorageHome, extension.identifier.id.toLocaleLowerCase());
}
}
......@@ -18,7 +18,7 @@ export const ILifecycleService = createDecorator<ILifecycleService>('lifecycleSe
* Note: It is absolutely important to avoid long running promises if possible. Please try hard
* to return a boolean directly. Returning a promise has quite an impact on the shutdown sequence!
*/
export interface WillShutdownEvent {
export interface BeforeShutdownEvent {
/**
* Allows to veto the shutdown. The veto can be a long running operation but it
......@@ -27,7 +27,7 @@ export interface WillShutdownEvent {
veto(value: boolean | Thenable<boolean>): void;
/**
* The reason why Code will be shutting down.
* The reason why the application will be shutting down.
*/
reason: ShutdownReason;
}
......@@ -40,7 +40,7 @@ export interface WillShutdownEvent {
* Note: It is absolutely important to avoid long running promises if possible. Please try hard
* to return a boolean directly. Returning a promise has quite an impact on the shutdown sequence!
*/
export interface ShutdownEvent {
export interface WillShutdownEvent {
/**
* Allows to join the shutdown. The promise can be a long running operation but it
......@@ -49,7 +49,7 @@ export interface ShutdownEvent {
join(promise: Thenable<void>): void;
/**
* The reason why Code is shutting down.
* The reason why the application is shutting down.
*/
reason: ShutdownReason;
}
......@@ -137,17 +137,26 @@ export interface ILifecycleService {
/**
* Fired before shutdown happens. Allows listeners to veto against the
* shutdown.
* shutdown to prevent it from happening.
*
* The event carries a shutdown reason that indicates how the shutdown was triggered.
*/
readonly onWillShutdown: Event<WillShutdownEvent>;
readonly onBeforeShutdown: Event<BeforeShutdownEvent>;
/**
* Fired when no client is preventing the shutdown from happening. Can be used to dispose heavy resources
* like running processes. Can also be used to save UI state to storage.
* Fired when no client is preventing the shutdown from happening (from onBeforeShutdown).
* Can be used to save UI state even if that is long running through the WillShutdownEvent#join()
* method.
*
* The event carries a shutdown reason that indicates how the shutdown was triggered.
*/
readonly onShutdown: Event<ShutdownEvent>;
readonly onWillShutdown: Event<WillShutdownEvent>;
/**
* Fired when the shutdown is about to happen after long running shutdown operations
* have finished (from onWillShutdown). This is the right place to dispose resources.
*/
readonly onShutdown: Event<void>;
/**
* Returns a promise that resolves when a certain lifecycle phase
......@@ -158,6 +167,7 @@ export interface ILifecycleService {
export const NullLifecycleService: ILifecycleService = {
_serviceBrand: null,
onBeforeShutdown: Event.None,
onWillShutdown: Event.None,
onShutdown: Event.None,
phase: LifecyclePhase.Restored,
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ILifecycleService, WillShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, handleVetos, LifecyclePhaseToString, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, handleVetos, LifecyclePhaseToString, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ipcRenderer as ipc } from 'electron';
import { Event, Emitter } from 'vs/base/common/event';
......@@ -22,11 +22,14 @@ export class LifecycleService extends Disposable implements ILifecycleService {
_serviceBrand: any;
private readonly _onBeforeShutdown = this._register(new Emitter<BeforeShutdownEvent>());
get onBeforeShutdown(): Event<BeforeShutdownEvent> { return this._onBeforeShutdown.event; }
private readonly _onWillShutdown = this._register(new Emitter<WillShutdownEvent>());
get onWillShutdown(): Event<WillShutdownEvent> { return this._onWillShutdown.event; }
private readonly _onShutdown = this._register(new Emitter<ShutdownEvent>());
get onShutdown(): Event<ShutdownEvent> { return this._onShutdown.event; }
private readonly _onShutdown = this._register(new Emitter<void>());
get onShutdown(): Event<void> { return this._onShutdown.event; }
private readonly _startupKind: StartupKind;
get startupKind(): StartupKind { return this._startupKind; }
......@@ -77,8 +80,8 @@ export class LifecycleService extends Disposable implements ILifecycleService {
// store shutdown reason to retrieve next startup
this.storageService.store(LifecycleService.LAST_SHUTDOWN_REASON_KEY, JSON.stringify(reply.reason), StorageScope.WORKSPACE);
// trigger onWillShutdown events and veto collecting
this.handleWillShutdown(reply.reason).then(veto => {
// trigger onBeforeShutdown events and veto collecting
this.handleBeforeShutdown(reply.reason).then(veto => {
if (veto) {
this.logService.trace('lifecycle: onBeforeUnload prevented via veto');
this.storageService.remove(LifecycleService.LAST_SHUTDOWN_REASON_KEY, StorageScope.WORKSPACE);
......@@ -94,17 +97,22 @@ export class LifecycleService extends Disposable implements ILifecycleService {
ipc.on('vscode:onWillUnload', (event, reply: { replyChannel: string, reason: ShutdownReason }) => {
this.logService.trace(`lifecycle: onWillUnload (reason: ${reply.reason})`);
// trigger onShutdown events and joining
return this.handleShutdown(reply.reason).then(() => {
// trigger onWillShutdown events and joining
return this.handleWillShutdown(reply.reason).then(() => {
// trigger onShutdown event now that we know we will quit
this._onShutdown.fire();
// acknowledge to main side
ipc.send(reply.replyChannel, windowId);
});
});
}
private handleWillShutdown(reason: ShutdownReason): Promise<boolean> {
private handleBeforeShutdown(reason: ShutdownReason): Promise<boolean> {
const vetos: (boolean | Thenable<boolean>)[] = [];
this._onWillShutdown.fire({
this._onBeforeShutdown.fire({
veto(value) {
vetos.push(value);
},
......@@ -117,10 +125,10 @@ export class LifecycleService extends Disposable implements ILifecycleService {
});
}
private handleShutdown(reason: ShutdownReason): Thenable<void> {
private handleWillShutdown(reason: ShutdownReason): Thenable<void> {
const joiners: Thenable<void>[] = [];
this._onShutdown.fire({
this._onWillShutdown.fire({
join(promise) {
if (promise) {
joiners.push(promise);
......
......@@ -53,8 +53,8 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
this._toDispose.push(_webviewService.registerReviver(MainThreadWebviews.viewType, this));
lifecycleService.onWillShutdown(e => {
e.veto(this._onWillShutdown());
lifecycleService.onBeforeShutdown(e => {
e.veto(this._onBeforeShutdown());
}, this, this._toDispose);
}
......@@ -183,7 +183,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
return this._revivers.has(webview.state.viewType) || !!webview.reviver;
}
private _onWillShutdown(): boolean {
private _onBeforeShutdown(): boolean {
this._webviews.forEach((view) => {
if (this.canRevive(view)) {
view.state.state = view.webviewState;
......
......@@ -44,6 +44,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer';
import { ILabelService } from 'vs/platform/label/common/label';
import { dirname } from 'vs/base/common/resources';
import { escape } from 'vs/base/common/strings';
export class CustomTreeViewPanel extends ViewletPanel {
......@@ -406,7 +407,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.resetMessageElement();
this._messageValue = message;
if (isString(this._messageValue)) {
this.messageElement.innerText = this._messageValue;
this.messageElement.innerText = escape(this._messageValue);
} else {
this.markdownResult = this.markdownRenderer.render(this._messageValue);
DOM.append(this.messageElement, this.markdownResult.element);
......@@ -626,12 +627,12 @@ class TreeRenderer implements IRenderer {
renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void {
const resource = node.resourceUri ? URI.revive(node.resourceUri) : null;
const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource.path) } : void 0;
const description = isString(node.description) ? node.description : resource && node.description === true ? this.labelService.getUriLabel(dirname(resource), { relative: true }) : void 0;
const label = treeItemLabel ? treeItemLabel.label : void 0;
const description = isString(node.description) ? escape(node.description) : resource && node.description === true ? this.labelService.getUriLabel(dirname(resource), { relative: true }) : void 0;
const label = treeItemLabel ? escape(treeItemLabel.label) : void 0;
const matches = treeItemLabel && treeItemLabel.highlights ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : void 0;
const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark;
const iconUrl = icon ? URI.revive(icon) : null;
const title = node.tooltip ? node.tooltip : resource ? void 0 : label;
const title = node.tooltip ? node.tooltip : resource ? void 0 : treeItemLabel ? treeItemLabel.label : void 0;
// reset
templateData.resourceLabel.clear();
......
......@@ -138,7 +138,7 @@ function openWorkbench(configuration: IWindowConfiguration): Promise<void> {
}, mainServices, mainProcessClient, configuration);
// Gracefully Shutdown Storage
shell.onShutdown(event => {
shell.onWillShutdown(event => {
event.join(storageService.close());
});
......
......@@ -42,7 +42,7 @@ import { ExtensionService } from 'vs/workbench/services/extensions/electron-brow
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/node/instantiationService';
import { ILifecycleService, LifecyclePhase, ShutdownReason, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ISearchService, ISearchHistoryService } from 'vs/platform/search/common/search';
......@@ -122,8 +122,8 @@ export interface ICoreServices {
*/
export class WorkbenchShell extends Disposable {
private readonly _onShutdown = this._register(new Emitter<ShutdownEvent>());
get onShutdown(): Event<ShutdownEvent> { return this._onShutdown.event; }
private readonly _onWillShutdown = this._register(new Emitter<WillShutdownEvent>());
get onWillShutdown(): Event<WillShutdownEvent> { return this._onWillShutdown.event; }
private storageService: DelegatingStorageService;
private environmentService: IEnvironmentService;
......@@ -428,11 +428,8 @@ export class WorkbenchShell extends Disposable {
serviceCollection.set(IDialogService, instantiationService.createInstance(DialogService));
const lifecycleService = instantiationService.createInstance(LifecycleService);
this._register(lifecycleService.onShutdown(event => {
this._onShutdown.fire(event);
this.dispose(event.reason);
}));
this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event)));
this._register(lifecycleService.onShutdown(() => this.dispose()));
serviceCollection.set(ILifecycleService, lifecycleService);
this.lifecycleService = lifecycleService;
......@@ -585,12 +582,12 @@ export class WorkbenchShell extends Disposable {
this.workbench.layout();
}
dispose(reason = ShutdownReason.QUIT): void {
dispose(): void {
super.dispose();
// Dispose Workbench
if (this.workbench) {
this.workbench.dispose(reason);
this.workbench.dispose();
}
this.mainProcessClient.dispose();
......
......@@ -477,7 +477,7 @@ export class Workbench extends Disposable implements IPartService {
private registerListeners(): void {
// Lifecycle
this._register(this.lifecycleService.onWillShutdown(e => this.saveState(e.reason)));
this._register(this.lifecycleService.onBeforeShutdown(e => this.saveState(e.reason)));
// Listen to visible editor changes
this._register(this.editorService.onDidVisibleEditorsChange(() => this.onDidVisibleEditorsChange()));
......@@ -1142,7 +1142,7 @@ export class Workbench extends Disposable implements IPartService {
}
}
dispose(reason = ShutdownReason.QUIT): void {
dispose(): void {
super.dispose();
this.workbenchShutdown = true;
......
......@@ -49,12 +49,9 @@ function createProxyAgent(
let cacheRolls = 0;
let oldCache = new Map<string, string>();
let cache = new Map<string, string>();
function getCacheKey(url: string) {
function getCacheKey(url: nodeurl.UrlWithStringQuery) {
// Expecting proxies to usually be the same per scheme://host:port. Assuming that for performance.
const parsed = nodeurl.parse(url); // Coming from Node's URL, sticking with that.
delete parsed.pathname;
delete parsed.search;
return nodeurl.format(parsed);
return nodeurl.format({ ...url, ...{ pathname: undefined, search: undefined, hash: undefined } });
}
function getCachedProxy(key: string) {
let proxy = cache.get(key);
......@@ -85,6 +82,7 @@ function createProxyAgent(
let cacheCount = 0;
let envCount = 0;
let settingsCount = 0;
let localhostCount = 0;
function logEvent() {
timeout = undefined;
/* __GDPR__
......@@ -96,11 +94,12 @@ function createProxyAgent(
"cacheSize": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"cacheRolls": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"envCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"settingsCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
"settingsCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"localhostCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount });
count = duration = errorCount = cacheCount = envCount = settingsCount = 0;
mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount });
count = duration = errorCount = cacheCount = envCount = settingsCount = localhostCount = 0;
}
function resolveProxy(url: string, callback: (proxy?: string) => void) {
......@@ -108,6 +107,16 @@ function createProxyAgent(
timeout = setTimeout(logEvent, 10 * 60 * 1000);
}
const parsedUrl = nodeurl.parse(url); // Coming from Node's URL, sticking with that.
const hostname = parsedUrl.hostname;
if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '::ffff:127.0.0.1') {
localhostCount++;
callback('DIRECT');
extHostLogService.trace('ProxyResolver#resolveProxy localhost', url, 'DIRECT');
return;
}
if (settingsProxy) {
settingsCount++;
callback(settingsProxy);
......@@ -122,7 +131,7 @@ function createProxyAgent(
return;
}
const key = getCacheKey(url);
const key = getCacheKey(parsedUrl);
const proxy = getCachedProxy(key);
if (proxy) {
cacheCount++;
......
......@@ -17,11 +17,13 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
taskService.getWorkspaceTasks().then(workspaceTaskResult => {
if (workspaceTaskResult) {
workspaceTaskResult.forEach(resultElement => {
resultElement.set.tasks.forEach(task => {
if (task.runOptions.runOn === RunOnOptions.folderOpen) {
taskService.run(task);
}
});
if (resultElement.set) {
resultElement.set.tasks.forEach(task => {
if (task.runOptions.runOn === RunOnOptions.folderOpen) {
taskService.run(task);
}
});
}
if (resultElement.configurations) {
forEach(resultElement.configurations.byIdentifier, (configedTask) => {
if (configedTask.value.runOptions.runOn === RunOnOptions.folderOpen) {
......
......@@ -529,7 +529,7 @@ class TaskService extends Disposable implements ITaskService {
this.updateWorkspaceTasks();
}));
this._taskRunningState = TASK_RUNNING_STATE.bindTo(contextKeyService);
this._register(lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown())));
this._register(lifecycleService.onBeforeShutdown(event => event.veto(this.beforeShutdown())));
this._register(storageService.onWillSaveState(() => this.saveState()));
this._onDidStateChange = this._register(new Emitter());
this.registerCommands();
......
......@@ -63,7 +63,7 @@ export abstract class TerminalService implements ITerminalService {
this._activeTabIndex = 0;
this._isShuttingDown = false;
this._findState = new FindReplaceState();
lifecycleService.onWillShutdown(event => event.veto(this._onWillShutdown()));
lifecycleService.onBeforeShutdown(event => event.veto(this._onBeforeShutdown()));
lifecycleService.onShutdown(() => this._onShutdown());
this._terminalFocusContextKey = KEYBINDING_CONTEXT_TERMINAL_FOCUS.bindTo(this._contextKeyService);
this._findWidgetVisible = KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE.bindTo(this._contextKeyService);
......@@ -92,7 +92,7 @@ export abstract class TerminalService implements ITerminalService {
public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void;
public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void;
private _onWillShutdown(): boolean | PromiseLike<boolean> {
private _onBeforeShutdown(): boolean | PromiseLike<boolean> {
if (this.terminalInstances.length === 0) {
// No terminal instances, don't veto
return false;
......
......@@ -124,7 +124,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
this._toDispose = [];
this._toDispose.push(this._onCrashed);
this._toDispose.push(this._lifecycleService.onWillShutdown((e) => this._onWillShutdown(e)));
this._toDispose.push(this._lifecycleService.onWillShutdown(e => this._onWillShutdown(e)));
this._toDispose.push(this._lifecycleService.onShutdown(reason => this.terminate()));
this._toDispose.push(this._broadcastService.onBroadcast(b => this._onBroadcast(b)));
......@@ -563,7 +563,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
}
});
event.veto(timeout(100 /* wait a bit for IPC to get delivered */).then(() => false));
event.join(timeout(100 /* wait a bit for IPC to get delivered */));
}
}
}
......
......@@ -106,7 +106,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
private registerListeners(): void {
// Lifecycle
this.lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown(event.reason)));
this.lifecycleService.onBeforeShutdown(event => event.veto(this.beforeShutdown(event.reason)));
this.lifecycleService.onShutdown(this.dispose, this);
// Files configuration changes
......
......@@ -7,7 +7,7 @@ import * as sinon from 'sinon';
import * as platform from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { ILifecycleService, WillShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { workbenchInstantiationService, TestLifecycleService, TestTextFileService, TestWindowsService, TestContextService, TestFileService } from 'vs/workbench/test/workbenchTestServices';
import { toResource } from 'vs/base/test/common/utils';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -37,7 +37,7 @@ class ServiceAccessor {
}
}
class ShutdownEventImpl implements WillShutdownEvent {
class BeforeShutdownEventImpl implements BeforeShutdownEvent {
public value: boolean | TPromise<boolean>;
public reason = ShutdownReason.CLOSE;
......@@ -69,7 +69,7 @@ suite('Files - TextFileService', () => {
model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);
const event = new ShutdownEventImpl();
const event = new BeforeShutdownEventImpl();
accessor.lifecycleService.fireWillShutdown(event);
const veto = event.value;
......@@ -94,7 +94,7 @@ suite('Files - TextFileService', () => {
assert.equal(service.getDirty().length, 1);
const event = new ShutdownEventImpl();
const event = new BeforeShutdownEventImpl();
accessor.lifecycleService.fireWillShutdown(event);
assert.ok(event.value);
......@@ -114,7 +114,7 @@ suite('Files - TextFileService', () => {
assert.equal(service.getDirty().length, 1);
const event = new ShutdownEventImpl();
const event = new BeforeShutdownEventImpl();
accessor.lifecycleService.fireWillShutdown(event);
const veto = event.value;
......@@ -145,7 +145,7 @@ suite('Files - TextFileService', () => {
assert.equal(service.getDirty().length, 1);
const event = new ShutdownEventImpl();
const event = new BeforeShutdownEventImpl();
accessor.lifecycleService.fireWillShutdown(event);
return (<TPromise<boolean>>event.value).then(veto => {
......@@ -450,7 +450,7 @@ suite('Files - TextFileService', () => {
assert.equal(service.getDirty().length, 1);
const event = new ShutdownEventImpl();
const event = new BeforeShutdownEventImpl();
event.reason = shutdownReason;
accessor.lifecycleService.fireWillShutdown(event);
......
......@@ -24,7 +24,7 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { IEditorOptions, IResourceInput } from 'vs/platform/editor/common/editor';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace } from 'vs/platform/workspace/common/workspace';
import { ILifecycleService, WillShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService';
import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent, ICreateFileOptions, ITextSnapshot, IResourceEncodings } from 'vs/platform/files/common/files';
......@@ -1144,29 +1144,34 @@ export class TestLifecycleService implements ILifecycleService {
public phase: LifecyclePhase;
public startupKind: StartupKind;
private _onBeforeShutdown = new Emitter<BeforeShutdownEvent>();
private _onWillShutdown = new Emitter<WillShutdownEvent>();
private _onShutdown = new Emitter<ShutdownEvent>();
private _onShutdown = new Emitter<void>();
when(): TPromise<void> {
return TPromise.as(void 0);
}
public fireShutdown(reason = ShutdownReason.QUIT): void {
this._onShutdown.fire({
this._onWillShutdown.fire({
join: () => { },
reason
});
}
public fireWillShutdown(event: WillShutdownEvent): void {
this._onWillShutdown.fire(event);
public fireWillShutdown(event: BeforeShutdownEvent): void {
this._onBeforeShutdown.fire(event);
}
public get onBeforeShutdown(): Event<BeforeShutdownEvent> {
return this._onBeforeShutdown.event;
}
public get onWillShutdown(): Event<WillShutdownEvent> {
return this._onWillShutdown.event;
}
public get onShutdown(): Event<ShutdownEvent> {
public get onShutdown(): Event<void> {
return this._onShutdown.event;
}
}
......
......@@ -9405,10 +9405,10 @@ vscode-proxy-agent@0.1.1:
https-proxy-agent "2.2.1"
socks-proxy-agent "4.0.1"
vscode-ripgrep@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.2.4.tgz#b3cfbe08ed13f6cf6b134147ea4d982970ab4f70"
integrity sha512-TysaK20aCSfsFIQGd0DfMshjkHof0fG6zx7DoO0tdWNAZgsvoqLtOWdqHcocICRZ3RSpdiMiEJRaMK+iOzx16w==
vscode-ripgrep@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.2.5.tgz#2093c8f36d52bd2dab9eb45b003dd02533c5499c"
integrity sha512-n5XBm9od5hahpljw9T8wbkuMnAY7LlAG1OyEEtcCZEX9aCHFuBKSP0IcvciGRTbtWRovNuT83A2iRjt6PL3bLg==
vscode-sqlite3@4.0.5:
version "4.0.5"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册