diff --git a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts index 8a391e3d96d..7bd8bd07c8c 100644 --- a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts @@ -13,6 +13,7 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {ExtHostDocuments} from 'vs/workbench/api/node/extHostDocuments'; export interface TextDocumentWillSaveEvent { + document: vscode.TextDocument; waitUntil(t: Thenable): void; } @@ -52,16 +53,23 @@ export class ExtHostDocumentSaveParticipant { } private _deliverEventAsync(listener: Function, thisArg: any, document: vscode.TextDocument): TPromise { + const promises: TPromise[] = []; - const event = { + + const event: TextDocumentWillSaveEvent = Object.freeze({ + document, waitUntil(p: Thenable) { + if (Object.isFrozen(promises)) { + throw illegalState('waitUntil can not be called async'); + } promises.push(TPromise.wrap(p)); } - }; + }); + try { listener.apply(thisArg, [event]); } finally { - event.waitUntil = () => { throw illegalState(); }; + Object.freeze(promises); return TPromise.join(promises).then(() => void 0, err => void 0 /* ignore */); } } diff --git a/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts index 4934f66e034..19863f67735 100644 --- a/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts @@ -61,7 +61,23 @@ suite('ExtHostDocumentSaveParticipant', () => { }); }); - test('event delivery in subscribe order', () => { + test('event delivery, immutable', () => { + const participant = new ExtHostDocumentSaveParticipant(documents); + + let event: TextDocumentWillSaveEvent; + let sub = participant.onWillSaveTextDocumentEvent(function (e) { + event = e; + }); + + return participant.$participateInSave(resource).then(() => { + sub.dispose(); + + assert.ok(event); + assert.throws(() => event.document = null); + }); + }); + + test('event delivery, in subscriber order', () => { const participant = new ExtHostDocumentSaveParticipant(documents); let counter = 0;