From 11fb2c1389fc82610bc4eeb24dbe8610603b2698 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 13 Dec 2018 10:28:26 +0100 Subject: [PATCH] remove winjs-promise - fixes #53526 --- .vscode/launch.json | 26 +- build/gulpfile.hygiene.js | 2 - src/tsconfig.strictNullChecks.json | 1 - src/vs/base/common/buildunit.json | 11 +- src/vs/base/common/winjs.base.d.ts | 53 - src/vs/base/common/winjs.base.js | 2096 ----------------- src/vs/base/test/common/async.test.ts | 55 - src/vs/base/test/common/winjs.promise.test.ts | 68 - .../node/extensionManagementService.ts | 3 +- test/all.js | 36 +- test/electron/renderer.js | 2 +- 11 files changed, 38 insertions(+), 2315 deletions(-) delete mode 100644 src/vs/base/common/winjs.base.d.ts delete mode 100644 src/vs/base/common/winjs.base.js delete mode 100644 src/vs/base/test/common/winjs.promise.test.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 851e4e43a38..1dafa8397ce 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -133,24 +133,22 @@ }, "urlFilter": "*workbench.html*", "runtimeArgs": [ - "--inspect=5875", "--no-cached-data" - ], - "skipFiles": [ - "**/winjs*.js" + "--inspect=5875", + "--no-cached-data" ], "webRoot": "${workspaceFolder}" }, { - "type": "node", - "request": "launch", - "name": "Launch VS Code (Main Process)", - "runtimeExecutable": "${workspaceFolder}/scripts/code.sh", - "runtimeArgs": [ - "--no-cached-data" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] + "type": "node", + "request": "launch", + "name": "Launch VS Code (Main Process)", + "runtimeExecutable": "${workspaceFolder}/scripts/code.sh", + "runtimeArgs": [ + "--no-cached-data" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ] }, { "type": "node", diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index a100157d96b..09b4b80b572 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -50,7 +50,6 @@ const indentationFilter = [ '!src/vs/css.build.js', '!src/vs/loader.js', '!src/vs/base/common/marked/marked.js', - '!src/vs/base/common/winjs.base.js', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', '!test/assert.js', @@ -128,7 +127,6 @@ const eslintFilter = [ '!src/vs/nls.js', '!src/vs/css.build.js', '!src/vs/nls.build.js', - '!src/**/winjs.base.js', '!src/**/marked.js', '!**/test/**' ]; diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index f3bd8c9df97..00c39f1328d 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -136,7 +136,6 @@ "./vs/base/test/common/types.test.ts", "./vs/base/test/common/utils.ts", "./vs/base/test/common/uuid.test.ts", - "./vs/base/test/common/winjs.promise.test.ts", "./vs/base/test/node/console.test.ts", "./vs/base/test/node/decoder.test.ts", "./vs/base/test/node/encoding/encoding.test.ts", diff --git a/src/vs/base/common/buildunit.json b/src/vs/base/common/buildunit.json index fecb5c6eac6..50e3d750676 100644 --- a/src/vs/base/common/buildunit.json +++ b/src/vs/base/common/buildunit.json @@ -1,7 +1,10 @@ { "name": "vs/base", "dependencies": [ - { "name": "vs", "internal": false } + { + "name": "vs", + "internal": false + } ], "libs": [ "lib.core.d.ts" @@ -9,7 +12,5 @@ "sources": [ "**/*.ts" ], - "declares": [ - "vs/base/winjs.base.d.ts" - ] -} \ No newline at end of file + "declares": [] +} diff --git a/src/vs/base/common/winjs.base.d.ts b/src/vs/base/common/winjs.base.d.ts deleted file mode 100644 index efac30a26b0..00000000000 --- a/src/vs/base/common/winjs.base.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -/// Interfaces for WinJS - -export type ErrorCallback = (error: any) => void; - -export class Promise { - constructor(executor: (resolve: (value: T | PromiseLike) => void, reject: (reason: any) => void) => void); - - public then( - onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | null): Promise; - - - public static as(value: null): Promise; - public static as(value: undefined): Promise; - public static as(value: PromiseLike): PromiseLike; - public static as>(value: SomePromise): SomePromise; - public static as(value: T): Promise; - - public static join(promises: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; - public static join(promises: (T | PromiseLike)[]): Promise; - - public static wrap(value: T | PromiseLike): Promise; - - public static wrapError(error: Error): Promise; - - /** - * @internal - */ - public static addEventListener(event: 'error', promiseErrorHandler: (e: IPromiseError) => void): void; -} - -export type TValueCallback = (value: T | PromiseLike) => void; - -export { - Promise as TPromise, - TValueCallback as ValueCallback -}; - -export interface IPromiseErrorDetail { - parent: Promise; - error: any; - id: number; - handler: Function; - exception: Error; -} - -export interface IPromiseError { - detail: IPromiseErrorDetail; -} diff --git a/src/vs/base/common/winjs.base.js b/src/vs/base/common/winjs.base.js deleted file mode 100644 index d8de83ddd3e..00000000000 --- a/src/vs/base/common/winjs.base.js +++ /dev/null @@ -1,2096 +0,0 @@ -/** - * Extracted from https://github.com/winjs/winjs - * Version: 4.4.0(ec3258a9f3a36805a187848984e3bb938044178d) - * Copyright (c) Microsoft Corporation. - * All Rights Reserved. - * Licensed under the MIT License. - */ -var __winjs_exports; - -(function() { - -var _modules = Object.create(null);//{}; -_modules["WinJS/Core/_WinJS"] = {}; - -var _winjs = function(moduleId, deps, factory) { - var exports = {}; - var exportsPassedIn = false; - - var depsValues = deps.map(function(dep) { - if (dep === 'exports') { - exportsPassedIn = true; - return exports; - } - return _modules[dep]; - }); - - var result = factory.apply({}, depsValues); - - _modules[moduleId] = exportsPassedIn ? exports : result; -}; - - -_winjs("WinJS/Core/_Global", [], function () { - "use strict"; - - // Appease jshint - /* global window, self, global */ - - var globalObject = - typeof window !== 'undefined' ? window : - typeof self !== 'undefined' ? self : - typeof global !== 'undefined' ? global : - {}; - return globalObject; -}); - -_winjs("WinJS/Core/_BaseCoreUtils", ["WinJS/Core/_Global"], function baseCoreUtilsInit(_Global) { - "use strict"; - - var hasWinRT = !!_Global.Windows; - - function markSupportedForProcessing(func) { - /// - /// - /// Marks a function as being compatible with declarative processing, such as WinJS.UI.processAll - /// or WinJS.Binding.processAll. - /// - /// - /// The function to be marked as compatible with declarative processing. - /// - /// - /// The input function. - /// - /// - func.supportedForProcessing = true; - return func; - } - - var actualSetImmediate = null; - - return { - hasWinRT: hasWinRT, - markSupportedForProcessing: markSupportedForProcessing, - _setImmediate: function (callback) { - // BEGIN monaco change - if (actualSetImmediate === null) { - if (_Global.setImmediate) { - actualSetImmediate = _Global.setImmediate.bind(_Global); - } else if (typeof process !== 'undefined' && typeof process.nextTick === 'function') { - actualSetImmediate = process.nextTick.bind(process); - } else { - actualSetImmediate = _Global.setTimeout.bind(_Global); - } - } - actualSetImmediate(callback); - // END monaco change - } - }; -}); -_winjs("WinJS/Core/_WriteProfilerMark", ["WinJS/Core/_Global"], function profilerInit(_Global) { - "use strict"; - - return _Global.msWriteProfilerMark || function () { }; -}); -_winjs("WinJS/Core/_Base", ["WinJS/Core/_WinJS","WinJS/Core/_Global","WinJS/Core/_BaseCoreUtils","WinJS/Core/_WriteProfilerMark"], function baseInit(_WinJS, _Global, _BaseCoreUtils, _WriteProfilerMark) { - "use strict"; - - function initializeProperties(target, members, prefix) { - var keys = Object.keys(members); - var isArray = Array.isArray(target); - var properties; - var i, len; - for (i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - var enumerable = key.charCodeAt(0) !== /*_*/95; - var member = members[key]; - if (member && typeof member === 'object') { - if (member.value !== undefined || typeof member.get === 'function' || typeof member.set === 'function') { - if (member.enumerable === undefined) { - member.enumerable = enumerable; - } - if (prefix && member.setName && typeof member.setName === 'function') { - member.setName(prefix + "." + key); - } - properties = properties || {}; - properties[key] = member; - continue; - } - } - if (!enumerable) { - properties = properties || {}; - properties[key] = { value: member, enumerable: enumerable, configurable: true, writable: true }; - continue; - } - if (isArray) { - target.forEach(function (target) { - target[key] = member; - }); - } else { - target[key] = member; - } - } - if (properties) { - if (isArray) { - target.forEach(function (target) { - Object.defineProperties(target, properties); - }); - } else { - Object.defineProperties(target, properties); - } - } - } - - (function () { - - var _rootNamespace = _WinJS; - if (!_rootNamespace.Namespace) { - _rootNamespace.Namespace = Object.create(Object.prototype); - } - - function createNamespace(parentNamespace, name) { - var currentNamespace = parentNamespace || {}; - if (name) { - var namespaceFragments = name.split("."); - if (currentNamespace === _Global && namespaceFragments[0] === "WinJS") { - currentNamespace = _WinJS; - namespaceFragments.splice(0, 1); - } - for (var i = 0, len = namespaceFragments.length; i < len; i++) { - var namespaceName = namespaceFragments[i]; - if (!currentNamespace[namespaceName]) { - Object.defineProperty(currentNamespace, namespaceName, - { value: {}, writable: false, enumerable: true, configurable: true } - ); - } - currentNamespace = currentNamespace[namespaceName]; - } - } - return currentNamespace; - } - - function defineWithParent(parentNamespace, name, members) { - /// - /// - /// Defines a new namespace with the specified name under the specified parent namespace. - /// - /// - /// The parent namespace. - /// - /// - /// The name of the new namespace. - /// - /// - /// The members of the new namespace. - /// - /// - /// The newly-defined namespace. - /// - /// - var currentNamespace = createNamespace(parentNamespace, name); - - if (members) { - initializeProperties(currentNamespace, members, name || ""); - } - - return currentNamespace; - } - - function define(name, members) { - /// - /// - /// Defines a new namespace with the specified name. - /// - /// - /// The name of the namespace. This could be a dot-separated name for nested namespaces. - /// - /// - /// The members of the new namespace. - /// - /// - /// The newly-defined namespace. - /// - /// - return defineWithParent(_Global, name, members); - } - - var LazyStates = { - uninitialized: 1, - working: 2, - initialized: 3, - }; - - function lazy(f) { - var name; - var state = LazyStates.uninitialized; - var result; - return { - setName: function (value) { - name = value; - }, - get: function () { - switch (state) { - case LazyStates.initialized: - return result; - - case LazyStates.uninitialized: - state = LazyStates.working; - try { - _WriteProfilerMark("WinJS.Namespace._lazy:" + name + ",StartTM"); - result = f(); - } finally { - _WriteProfilerMark("WinJS.Namespace._lazy:" + name + ",StopTM"); - state = LazyStates.uninitialized; - } - f = null; - state = LazyStates.initialized; - return result; - - case LazyStates.working: - throw "Illegal: reentrancy on initialization"; - - default: - throw "Illegal"; - } - }, - set: function (value) { - switch (state) { - case LazyStates.working: - throw "Illegal: reentrancy on initialization"; - - default: - state = LazyStates.initialized; - result = value; - break; - } - }, - enumerable: true, - configurable: true, - }; - } - - // helper for defining AMD module members - function moduleDefine(exports, name, members) { - var target = [exports]; - var publicNS = null; - if (name) { - publicNS = createNamespace(_Global, name); - target.push(publicNS); - } - initializeProperties(target, members, name || ""); - return publicNS; - } - - // Establish members of the "WinJS.Namespace" namespace - Object.defineProperties(_rootNamespace.Namespace, { - - defineWithParent: { value: defineWithParent, writable: true, enumerable: true, configurable: true }, - - define: { value: define, writable: true, enumerable: true, configurable: true }, - - _lazy: { value: lazy, writable: true, enumerable: true, configurable: true }, - - _moduleDefine: { value: moduleDefine, writable: true, enumerable: true, configurable: true } - - }); - - })(); - - (function () { - - function define(constructor, instanceMembers, staticMembers) { - /// - /// - /// Defines a class using the given constructor and the specified instance members. - /// - /// - /// A constructor function that is used to instantiate this class. - /// - /// - /// The set of instance fields, properties, and methods made available on the class. - /// - /// - /// The set of static fields, properties, and methods made available on the class. - /// - /// - /// The newly-defined class. - /// - /// - constructor = constructor || function () { }; - _BaseCoreUtils.markSupportedForProcessing(constructor); - if (instanceMembers) { - initializeProperties(constructor.prototype, instanceMembers); - } - if (staticMembers) { - initializeProperties(constructor, staticMembers); - } - return constructor; - } - - function derive(baseClass, constructor, instanceMembers, staticMembers) { - /// - /// - /// Creates a sub-class based on the supplied baseClass parameter, using prototypal inheritance. - /// - /// - /// The class to inherit from. - /// - /// - /// A constructor function that is used to instantiate this class. - /// - /// - /// The set of instance fields, properties, and methods to be made available on the class. - /// - /// - /// The set of static fields, properties, and methods to be made available on the class. - /// - /// - /// The newly-defined class. - /// - /// - if (baseClass) { - constructor = constructor || function () { }; - var basePrototype = baseClass.prototype; - constructor.prototype = Object.create(basePrototype); - _BaseCoreUtils.markSupportedForProcessing(constructor); - Object.defineProperty(constructor.prototype, "constructor", { value: constructor, writable: true, configurable: true, enumerable: true }); - if (instanceMembers) { - initializeProperties(constructor.prototype, instanceMembers); - } - if (staticMembers) { - initializeProperties(constructor, staticMembers); - } - return constructor; - } else { - return define(constructor, instanceMembers, staticMembers); - } - } - - function mix(constructor) { - /// - /// - /// Defines a class using the given constructor and the union of the set of instance members - /// specified by all the mixin objects. The mixin parameter list is of variable length. - /// - /// - /// A constructor function that is used to instantiate this class. - /// - /// - /// The newly-defined class. - /// - /// - constructor = constructor || function () { }; - var i, len; - for (i = 1, len = arguments.length; i < len; i++) { - initializeProperties(constructor.prototype, arguments[i]); - } - return constructor; - } - - // Establish members of "WinJS.Class" namespace - _WinJS.Namespace.define("WinJS.Class", { - define: define, - derive: derive, - mix: mix - }); - - })(); - - return { - Namespace: _WinJS.Namespace, - Class: _WinJS.Class - }; - -}); -_winjs("WinJS/Core/_ErrorFromName", ["WinJS/Core/_Base"], function errorsInit(_Base) { - "use strict"; - - var ErrorFromName = _Base.Class.derive(Error, function (name, message) { - /// - /// - /// Creates an Error object with the specified name and message properties. - /// - /// The name of this error. The name is meant to be consumed programmatically and should not be localized. - /// The message for this error. The message is meant to be consumed by humans and should be localized. - /// Error instance with .name and .message properties populated - /// - this.name = name; - this.message = message || name; - }, { - /* empty */ - }, { - supportedForProcessing: false, - }); - - _Base.Namespace.define("WinJS", { - // ErrorFromName establishes a simple pattern for returning error codes. - // - ErrorFromName: ErrorFromName - }); - - return ErrorFromName; - -}); - - -_winjs("WinJS/Core/_Events", ["exports","WinJS/Core/_Base"], function eventsInit(exports, _Base) { - "use strict"; - - - function createEventProperty(name) { - var eventPropStateName = "_on" + name + "state"; - - return { - get: function () { - var state = this[eventPropStateName]; - return state && state.userHandler; - }, - set: function (handler) { - var state = this[eventPropStateName]; - if (handler) { - if (!state) { - state = { wrapper: function (evt) { return state.userHandler(evt); }, userHandler: handler }; - Object.defineProperty(this, eventPropStateName, { value: state, enumerable: false, writable:true, configurable: true }); - this.addEventListener(name, state.wrapper, false); - } - state.userHandler = handler; - } else if (state) { - this.removeEventListener(name, state.wrapper, false); - this[eventPropStateName] = null; - } - }, - enumerable: true - }; - } - - function createEventProperties() { - /// - /// - /// Creates an object that has one property for each name passed to the function. - /// - /// - /// A variable list of property names. - /// - /// - /// The object with the specified properties. The names of the properties are prefixed with 'on'. - /// - /// - var props = {}; - for (var i = 0, len = arguments.length; i < len; i++) { - var name = arguments[i]; - props["on" + name] = createEventProperty(name); - } - return props; - } - - var EventMixinEvent = _Base.Class.define( - function EventMixinEvent_ctor(type, detail, target) { - this.detail = detail; - this.target = target; - this.timeStamp = Date.now(); - this.type = type; - }, - { - bubbles: { value: false, writable: false }, - cancelable: { value: false, writable: false }, - currentTarget: { - get: function () { return this.target; } - }, - defaultPrevented: { - get: function () { return this._preventDefaultCalled; } - }, - trusted: { value: false, writable: false }, - eventPhase: { value: 0, writable: false }, - target: null, - timeStamp: null, - type: null, - - preventDefault: function () { - this._preventDefaultCalled = true; - }, - stopImmediatePropagation: function () { - this._stopImmediatePropagationCalled = true; - }, - stopPropagation: function () { - } - }, { - supportedForProcessing: false, - } - ); - - var eventMixin = { - _listeners: null, - - addEventListener: function (type, listener, useCapture) { - /// - /// - /// Adds an event listener to the control. - /// - /// - /// The type (name) of the event. - /// - /// - /// The listener to invoke when the event is raised. - /// - /// - /// if true initiates capture, otherwise false. - /// - /// - useCapture = useCapture || false; - this._listeners = this._listeners || {}; - var eventListeners = (this._listeners[type] = this._listeners[type] || []); - for (var i = 0, len = eventListeners.length; i < len; i++) { - var l = eventListeners[i]; - if (l.useCapture === useCapture && l.listener === listener) { - return; - } - } - eventListeners.push({ listener: listener, useCapture: useCapture }); - }, - dispatchEvent: function (type, details) { - /// - /// - /// Raises an event of the specified type and with the specified additional properties. - /// - /// - /// The type (name) of the event. - /// - /// - /// The set of additional properties to be attached to the event object when the event is raised. - /// - /// - /// true if preventDefault was called on the event. - /// - /// - var listeners = this._listeners && this._listeners[type]; - if (listeners) { - var eventValue = new EventMixinEvent(type, details, this); - // Need to copy the array to protect against people unregistering while we are dispatching - listeners = listeners.slice(0, listeners.length); - for (var i = 0, len = listeners.length; i < len && !eventValue._stopImmediatePropagationCalled; i++) { - listeners[i].listener(eventValue); - } - return eventValue.defaultPrevented || false; - } - return false; - }, - removeEventListener: function (type, listener, useCapture) { - /// - /// - /// Removes an event listener from the control. - /// - /// - /// The type (name) of the event. - /// - /// - /// The listener to remove. - /// - /// - /// Specifies whether to initiate capture. - /// - /// - useCapture = useCapture || false; - var listeners = this._listeners && this._listeners[type]; - if (listeners) { - for (var i = 0, len = listeners.length; i < len; i++) { - var l = listeners[i]; - if (l.listener === listener && l.useCapture === useCapture) { - listeners.splice(i, 1); - if (listeners.length === 0) { - delete this._listeners[type]; - } - // Only want to remove one element for each call to removeEventListener - break; - } - } - } - } - }; - - _Base.Namespace._moduleDefine(exports, "WinJS.Utilities", { - _createEventProperty: createEventProperty, - createEventProperties: createEventProperties, - eventMixin: eventMixin - }); - -}); - - -_winjs("WinJS/Core/_Trace", ["WinJS/Core/_Global"], function traceInit(_Global) { - "use strict"; - - function nop(v) { - return v; - } - - return { - _traceAsyncOperationStarting: (_Global.Debug && _Global.Debug.msTraceAsyncOperationStarting && _Global.Debug.msTraceAsyncOperationStarting.bind(_Global.Debug)) || nop, - _traceAsyncOperationCompleted: (_Global.Debug && _Global.Debug.msTraceAsyncOperationCompleted && _Global.Debug.msTraceAsyncOperationCompleted.bind(_Global.Debug)) || nop, - _traceAsyncCallbackStarting: (_Global.Debug && _Global.Debug.msTraceAsyncCallbackStarting && _Global.Debug.msTraceAsyncCallbackStarting.bind(_Global.Debug)) || nop, - _traceAsyncCallbackCompleted: (_Global.Debug && _Global.Debug.msTraceAsyncCallbackCompleted && _Global.Debug.msTraceAsyncCallbackCompleted.bind(_Global.Debug)) || nop - }; -}); -_winjs("WinJS/Promise/_StateMachine", ["WinJS/Core/_Global","WinJS/Core/_BaseCoreUtils","WinJS/Core/_Base","WinJS/Core/_ErrorFromName","WinJS/Core/_Events","WinJS/Core/_Trace"], function promiseStateMachineInit(_Global, _BaseCoreUtils, _Base, _ErrorFromName, _Events, _Trace) { - "use strict"; - - _Global.Debug && (_Global.Debug.setNonUserCodeExceptions = true); - - var ListenerType = _Base.Class.mix(_Base.Class.define(null, { /*empty*/ }, { supportedForProcessing: false }), _Events.eventMixin); - var promiseEventListeners = new ListenerType(); - // make sure there is a listeners collection so that we can do a more trivial check below - promiseEventListeners._listeners = {}; - var errorET = "error"; - var canceledName = "Canceled"; - var tagWithStack = false; - var tag = { - promise: 0x01, - thenPromise: 0x02, - errorPromise: 0x04, - exceptionPromise: 0x08, - completePromise: 0x10, - }; - tag.all = tag.promise | tag.thenPromise | tag.errorPromise | tag.exceptionPromise | tag.completePromise; - - // - // Global error counter, for each error which enters the system we increment this once and then - // the error number travels with the error as it traverses the tree of potential handlers. - // - // When someone has registered to be told about errors (WinJS.Promise.callonerror) promises - // which are in error will get tagged with a ._errorId field. This tagged field is the - // contract by which nested promises with errors will be identified as chaining for the - // purposes of the callonerror semantics. If a nested promise in error is encountered without - // a ._errorId it will be assumed to be foreign and treated as an interop boundary and - // a new error id will be minted. - // - var error_number = 1; - - // - // The state machine has a interesting hiccup in it with regards to notification, in order - // to flatten out notification and avoid recursion for synchronous completion we have an - // explicit set of *_notify states which are responsible for notifying their entire tree - // of children. They can do this because they know that immediate children are always - // ThenPromise instances and we can therefore reach into their state to access the - // _listeners collection. - // - // So, what happens is that a Promise will be fulfilled through the _completed or _error - // messages at which point it will enter a *_notify state and be responsible for to move - // its children into an (as appropriate) success or error state and also notify that child's - // listeners of the state transition, until leaf notes are reached. - // - - var state_created, // -> working - state_working, // -> error | error_notify | success | success_notify | canceled | waiting - state_waiting, // -> error | error_notify | success | success_notify | waiting_canceled - state_waiting_canceled, // -> error | error_notify | success | success_notify | canceling - state_canceled, // -> error | error_notify | success | success_notify | canceling - state_canceling, // -> error_notify - state_success_notify, // -> success - state_success, // -> . - state_error_notify, // -> error - state_error; // -> . - - // Noop function, used in the various states to indicate that they don't support a given - // message. Named with the somewhat cute name '_' because it reads really well in the states. - - function _() { } - - // Initial state - // - state_created = { - name: "created", - enter: function (promise) { - promise._setState(state_working); - }, - cancel: _, - done: _, - then: _, - _completed: _, - _error: _, - _notify: _, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // Ready state, waiting for a message (completed/error/progress), able to be canceled - // - state_working = { - name: "working", - enter: _, - cancel: function (promise) { - promise._setState(state_canceled); - }, - done: done, - then: then, - _completed: completed, - _error: error, - _notify: _, - _progress: progress, - _setCompleteValue: setCompleteValue, - _setErrorValue: setErrorValue - }; - - // Waiting state, if a promise is completed with a value which is itself a promise - // (has a then() method) it signs up to be informed when that child promise is - // fulfilled at which point it will be fulfilled with that value. - // - state_waiting = { - name: "waiting", - enter: function (promise) { - var waitedUpon = promise._value; - // We can special case our own intermediate promises which are not in a - // terminal state by just pushing this promise as a listener without - // having to create new indirection functions - if (waitedUpon instanceof ThenPromise && - waitedUpon._state !== state_error && - waitedUpon._state !== state_success) { - pushListener(waitedUpon, { promise: promise }); - } else { - var error = function (value) { - if (waitedUpon._errorId) { - promise._chainedError(value, waitedUpon); - } else { - // Because this is an interop boundary we want to indicate that this - // error has been handled by the promise infrastructure before we - // begin a new handling chain. - // - callonerror(promise, value, detailsForHandledError, waitedUpon, error); - promise._error(value); - } - }; - error.handlesOnError = true; - waitedUpon.then( - promise._completed.bind(promise), - error, - promise._progress.bind(promise) - ); - } - }, - cancel: function (promise) { - promise._setState(state_waiting_canceled); - }, - done: done, - then: then, - _completed: completed, - _error: error, - _notify: _, - _progress: progress, - _setCompleteValue: setCompleteValue, - _setErrorValue: setErrorValue - }; - - // Waiting canceled state, when a promise has been in a waiting state and receives a - // request to cancel its pending work it will forward that request to the child promise - // and then waits to be informed of the result. This promise moves itself into the - // canceling state but understands that the child promise may instead push it to a - // different state. - // - state_waiting_canceled = { - name: "waiting_canceled", - enter: function (promise) { - // Initiate a transition to canceling. Triggering a cancel on the promise - // that we are waiting upon may result in a different state transition - // before the state machine pump runs again. - promise._setState(state_canceling); - var waitedUpon = promise._value; - if (waitedUpon.cancel) { - waitedUpon.cancel(); - } - }, - cancel: _, - done: done, - then: then, - _completed: completed, - _error: error, - _notify: _, - _progress: progress, - _setCompleteValue: setCompleteValue, - _setErrorValue: setErrorValue - }; - - // Canceled state, moves to the canceling state and then tells the promise to do - // whatever it might need to do on cancelation. - // - state_canceled = { - name: "canceled", - enter: function (promise) { - // Initiate a transition to canceling. The _cancelAction may change the state - // before the state machine pump runs again. - promise._setState(state_canceling); - promise._cancelAction(); - }, - cancel: _, - done: done, - then: then, - _completed: completed, - _error: error, - _notify: _, - _progress: progress, - _setCompleteValue: setCompleteValue, - _setErrorValue: setErrorValue - }; - - // Canceling state, commits to the promise moving to an error state with an error - // object whose 'name' and 'message' properties contain the string "Canceled" - // - state_canceling = { - name: "canceling", - enter: function (promise) { - var error = new Error(canceledName); - error.name = error.message; - promise._value = error; - promise._setState(state_error_notify); - }, - cancel: _, - done: _, - then: _, - _completed: _, - _error: _, - _notify: _, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // Success notify state, moves a promise to the success state and notifies all children - // - state_success_notify = { - name: "complete_notify", - enter: function (promise) { - promise.done = CompletePromise.prototype.done; - promise.then = CompletePromise.prototype.then; - if (promise._listeners) { - var queue = [promise]; - var p; - while (queue.length) { - p = queue.shift(); - p._state._notify(p, queue); - } - } - promise._setState(state_success); - }, - cancel: _, - done: null, /*error to get here */ - then: null, /*error to get here */ - _completed: _, - _error: _, - _notify: notifySuccess, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // Success state, moves a promise to the success state and does NOT notify any children. - // Some upstream promise is owning the notification pass. - // - state_success = { - name: "success", - enter: function (promise) { - promise.done = CompletePromise.prototype.done; - promise.then = CompletePromise.prototype.then; - promise._cleanupAction(); - }, - cancel: _, - done: null, /*error to get here */ - then: null, /*error to get here */ - _completed: _, - _error: _, - _notify: notifySuccess, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // Error notify state, moves a promise to the error state and notifies all children - // - state_error_notify = { - name: "error_notify", - enter: function (promise) { - promise.done = ErrorPromise.prototype.done; - promise.then = ErrorPromise.prototype.then; - if (promise._listeners) { - var queue = [promise]; - var p; - while (queue.length) { - p = queue.shift(); - p._state._notify(p, queue); - } - } - promise._setState(state_error); - }, - cancel: _, - done: null, /*error to get here*/ - then: null, /*error to get here*/ - _completed: _, - _error: _, - _notify: notifyError, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // Error state, moves a promise to the error state and does NOT notify any children. - // Some upstream promise is owning the notification pass. - // - state_error = { - name: "error", - enter: function (promise) { - promise.done = ErrorPromise.prototype.done; - promise.then = ErrorPromise.prototype.then; - promise._cleanupAction(); - }, - cancel: _, - done: null, /*error to get here*/ - then: null, /*error to get here*/ - _completed: _, - _error: _, - _notify: notifyError, - _progress: _, - _setCompleteValue: _, - _setErrorValue: _ - }; - - // - // The statemachine implementation follows a very particular pattern, the states are specified - // as static stateless bags of functions which are then indirected through the state machine - // instance (a Promise). As such all of the functions on each state have the promise instance - // passed to them explicitly as a parameter and the Promise instance members do a little - // dance where they indirect through the state and insert themselves in the argument list. - // - // We could instead call directly through the promise states however then every caller - // would have to remember to do things like pumping the state machine to catch state transitions. - // - - var PromiseStateMachine = _Base.Class.define(null, { - _listeners: null, - _nextState: null, - _state: null, - _value: null, - - cancel: function () { - /// - /// - /// Attempts to cancel the fulfillment of a promised value. If the promise hasn't - /// already been fulfilled and cancellation is supported, the promise enters - /// the error state with a value of Error("Canceled"). - /// - /// - this._state.cancel(this); - this._run(); - }, - done: function Promise_done(onComplete, onError, onProgress) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// After the handlers have finished executing, this function throws any error that would have been returned - /// from then() as a promise in the error state. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The fulfilled value is passed as the single argument. If the value is null, - /// the fulfilled value is returned. The value returned - /// from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while executing the function, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function is the fulfilled value of the promise returned by then(). - /// - /// - /// the function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - this._state.done(this, onComplete, onError, onProgress); - }, - then: function Promise_then(onComplete, onError, onProgress) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The value is passed as the single argument. If the value is null, the value is returned. - /// The value returned from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while this function is being executed, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function becomes the fulfilled value of the promise returned by then(). - /// - /// - /// The function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - /// The promise whose value is the result of executing the complete or - /// error function. - /// - /// - // BEGIN monaco change - if (this.then !== Promise_then) { - this.then(onComplete, onError, onProgress); - return; - } - // END monaco change - return this._state.then(this, onComplete, onError, onProgress); - }, - - _chainedError: function (value, context) { - var result = this._state._error(this, value, detailsForChainedError, context); - this._run(); - return result; - }, - _completed: function (value) { - var result = this._state._completed(this, value); - this._run(); - return result; - }, - _error: function (value) { - var result = this._state._error(this, value, detailsForError); - this._run(); - return result; - }, - _progress: function (value) { - this._state._progress(this, value); - }, - _setState: function (state) { - this._nextState = state; - }, - _setCompleteValue: function (value) { - this._state._setCompleteValue(this, value); - this._run(); - }, - _setChainedErrorValue: function (value, context) { - var result = this._state._setErrorValue(this, value, detailsForChainedError, context); - this._run(); - return result; - }, - _setExceptionValue: function (value) { - var result = this._state._setErrorValue(this, value, detailsForException); - this._run(); - return result; - }, - _run: function () { - while (this._nextState) { - this._state = this._nextState; - this._nextState = null; - this._state.enter(this); - } - } - }, { - supportedForProcessing: false - }); - - // - // Implementations of shared state machine code. - // - - function completed(promise, value) { - var targetState; - if (value && typeof value === "object" && typeof value.then === "function") { - targetState = state_waiting; - } else { - targetState = state_success_notify; - } - promise._value = value; - promise._setState(targetState); - } - function createErrorDetails(exception, error, promise, id, parent, handler) { - return { - exception: exception, - error: error, - promise: promise, - handler: handler, - id: id, - parent: parent - }; - } - function detailsForHandledError(promise, errorValue, context, handler) { - var exception = context._isException; - var errorId = context._errorId; - return createErrorDetails( - exception ? errorValue : null, - exception ? null : errorValue, - promise, - errorId, - context, - handler - ); - } - function detailsForChainedError(promise, errorValue, context) { - var exception = context._isException; - var errorId = context._errorId; - setErrorInfo(promise, errorId, exception); - return createErrorDetails( - exception ? errorValue : null, - exception ? null : errorValue, - promise, - errorId, - context - ); - } - function detailsForError(promise, errorValue) { - var errorId = ++error_number; - setErrorInfo(promise, errorId); - return createErrorDetails( - null, - errorValue, - promise, - errorId - ); - } - function detailsForException(promise, exceptionValue) { - var errorId = ++error_number; - setErrorInfo(promise, errorId, true); - return createErrorDetails( - exceptionValue, - null, - promise, - errorId - ); - } - function done(promise, onComplete, onError, onProgress) { - var asyncOpID = _Trace._traceAsyncOperationStarting("WinJS.Promise.done"); - pushListener(promise, { c: onComplete, e: onError, p: onProgress, asyncOpID: asyncOpID }); - } - function error(promise, value, onerrorDetails, context) { - promise._value = value; - callonerror(promise, value, onerrorDetails, context); - promise._setState(state_error_notify); - } - function notifySuccess(promise, queue) { - var value = promise._value; - var listeners = promise._listeners; - if (!listeners) { - return; - } - promise._listeners = null; - var i, len; - for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { - var listener = len === 1 ? listeners : listeners[i]; - var onComplete = listener.c; - var target = listener.promise; - - _Trace._traceAsyncOperationCompleted(listener.asyncOpID, _Global.Debug && _Global.Debug.MS_ASYNC_OP_STATUS_SUCCESS); - - if (target) { - _Trace._traceAsyncCallbackStarting(listener.asyncOpID); - try { - target._setCompleteValue(onComplete ? onComplete(value) : value); - } catch (ex) { - target._setExceptionValue(ex); - } finally { - _Trace._traceAsyncCallbackCompleted(); - } - if (target._state !== state_waiting && target._listeners) { - queue.push(target); - } - } else { - CompletePromise.prototype.done.call(promise, onComplete); - } - } - } - function notifyError(promise, queue) { - var value = promise._value; - var listeners = promise._listeners; - if (!listeners) { - return; - } - promise._listeners = null; - var i, len; - for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { - var listener = len === 1 ? listeners : listeners[i]; - var onError = listener.e; - var target = listener.promise; - - var errorID = _Global.Debug && (value && value.name === canceledName ? _Global.Debug.MS_ASYNC_OP_STATUS_CANCELED : _Global.Debug.MS_ASYNC_OP_STATUS_ERROR); - _Trace._traceAsyncOperationCompleted(listener.asyncOpID, errorID); - - if (target) { - var asyncCallbackStarted = false; - try { - if (onError) { - _Trace._traceAsyncCallbackStarting(listener.asyncOpID); - asyncCallbackStarted = true; - if (!onError.handlesOnError) { - callonerror(target, value, detailsForHandledError, promise, onError); - } - target._setCompleteValue(onError(value)); - } else { - target._setChainedErrorValue(value, promise); - } - } catch (ex) { - target._setExceptionValue(ex); - } finally { - if (asyncCallbackStarted) { - _Trace._traceAsyncCallbackCompleted(); - } - } - if (target._state !== state_waiting && target._listeners) { - queue.push(target); - } - } else { - ErrorPromise.prototype.done.call(promise, null, onError); - } - } - } - function callonerror(promise, value, onerrorDetailsGenerator, context, handler) { - if (promiseEventListeners._listeners[errorET]) { - if (value instanceof Error && value.message === canceledName) { - return; - } - promiseEventListeners.dispatchEvent(errorET, onerrorDetailsGenerator(promise, value, context, handler)); - } - } - function progress(promise, value) { - var listeners = promise._listeners; - if (listeners) { - var i, len; - for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { - var listener = len === 1 ? listeners : listeners[i]; - var onProgress = listener.p; - if (onProgress) { - try { onProgress(value); } catch (ex) { } - } - if (!(listener.c || listener.e) && listener.promise) { - listener.promise._progress(value); - } - } - } - } - function pushListener(promise, listener) { - var listeners = promise._listeners; - if (listeners) { - // We may have either a single listener (which will never be wrapped in an array) - // or 2+ listeners (which will be wrapped). Since we are now adding one more listener - // we may have to wrap the single listener before adding the second. - listeners = Array.isArray(listeners) ? listeners : [listeners]; - listeners.push(listener); - } else { - listeners = listener; - } - promise._listeners = listeners; - } - // The difference beween setCompleteValue()/setErrorValue() and complete()/error() is that setXXXValue() moves - // a promise directly to the success/error state without starting another notification pass (because one - // is already ongoing). - function setErrorInfo(promise, errorId, isException) { - promise._isException = isException || false; - promise._errorId = errorId; - } - function setErrorValue(promise, value, onerrorDetails, context) { - promise._value = value; - callonerror(promise, value, onerrorDetails, context); - promise._setState(state_error); - } - function setCompleteValue(promise, value) { - var targetState; - if (value && typeof value === "object" && typeof value.then === "function") { - targetState = state_waiting; - } else { - targetState = state_success; - } - promise._value = value; - promise._setState(targetState); - } - function then(promise, onComplete, onError, onProgress) { - var result = new ThenPromise(promise); - var asyncOpID = _Trace._traceAsyncOperationStarting("WinJS.Promise.then"); - pushListener(promise, { promise: result, c: onComplete, e: onError, p: onProgress, asyncOpID: asyncOpID }); - return result; - } - - // - // Internal implementation detail promise, ThenPromise is created when a promise needs - // to be returned from a then() method. - // - var ThenPromise = _Base.Class.derive(PromiseStateMachine, - function (creator) { - - if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.thenPromise))) { - this._stack = Promise._getStack(); - } - - this._creator = creator; - this._setState(state_created); - this._run(); - }, { - _creator: null, - - _cancelAction: function () { if (this._creator) { this._creator.cancel(); } }, - _cleanupAction: function () { this._creator = null; } - }, { - supportedForProcessing: false - } - ); - - // - // Slim promise implementations for already completed promises, these are created - // under the hood on synchronous completion paths as well as by WinJS.Promise.wrap - // and WinJS.Promise.wrapError. - // - - var ErrorPromise = _Base.Class.define( - function ErrorPromise_ctor(value) { - - if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.errorPromise))) { - this._stack = Promise._getStack(); - } - - this._value = value; - callonerror(this, value, detailsForError); - }, { - cancel: function () { - /// - /// - /// Attempts to cancel the fulfillment of a promised value. If the promise hasn't - /// already been fulfilled and cancellation is supported, the promise enters - /// the error state with a value of Error("Canceled"). - /// - /// - }, - done: function ErrorPromise_done(unused, onError) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// After the handlers have finished executing, this function throws any error that would have been returned - /// from then() as a promise in the error state. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The fulfilled value is passed as the single argument. If the value is null, - /// the fulfilled value is returned. The value returned - /// from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while executing the function, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function is the fulfilled value of the promise returned by then(). - /// - /// - /// the function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - var value = this._value; - if (onError) { - try { - if (!onError.handlesOnError) { - callonerror(null, value, detailsForHandledError, this, onError); - } - var result = onError(value); - if (result && typeof result === "object" && typeof result.done === "function") { - // If a promise is returned we need to wait on it. - result.done(); - } - return; - } catch (ex) { - value = ex; - } - } - if (value instanceof Error && value.message === canceledName) { - // suppress cancel - return; - } - // force the exception to be thrown asyncronously to avoid any try/catch blocks - // - Promise._doneHandler(value); - }, - then: function ErrorPromise_then(unused, onError) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The value is passed as the single argument. If the value is null, the value is returned. - /// The value returned from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while this function is being executed, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function becomes the fulfilled value of the promise returned by then(). - /// - /// - /// The function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - /// The promise whose value is the result of executing the complete or - /// error function. - /// - /// - - // If the promise is already in a error state and no error handler is provided - // we optimize by simply returning the promise instead of creating a new one. - // - if (!onError) { return this; } - var result; - var value = this._value; - try { - if (!onError.handlesOnError) { - callonerror(null, value, detailsForHandledError, this, onError); - } - result = new CompletePromise(onError(value)); - } catch (ex) { - // If the value throw from the error handler is the same as the value - // provided to the error handler then there is no need for a new promise. - // - if (ex === value) { - result = this; - } else { - result = new ExceptionPromise(ex); - } - } - return result; - } - }, { - supportedForProcessing: false - } - ); - - var ExceptionPromise = _Base.Class.derive(ErrorPromise, - function ExceptionPromise_ctor(value) { - - if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.exceptionPromise))) { - this._stack = Promise._getStack(); - } - - this._value = value; - callonerror(this, value, detailsForException); - }, { - /* empty */ - }, { - supportedForProcessing: false - } - ); - - var CompletePromise = _Base.Class.define( - function CompletePromise_ctor(value) { - - if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.completePromise))) { - this._stack = Promise._getStack(); - } - - if (value && typeof value === "object" && typeof value.then === "function") { - var result = new ThenPromise(null); - result._setCompleteValue(value); - return result; - } - this._value = value; - }, { - cancel: function () { - /// - /// - /// Attempts to cancel the fulfillment of a promised value. If the promise hasn't - /// already been fulfilled and cancellation is supported, the promise enters - /// the error state with a value of Error("Canceled"). - /// - /// - }, - done: function CompletePromise_done(onComplete) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// After the handlers have finished executing, this function throws any error that would have been returned - /// from then() as a promise in the error state. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The fulfilled value is passed as the single argument. If the value is null, - /// the fulfilled value is returned. The value returned - /// from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while executing the function, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function is the fulfilled value of the promise returned by then(). - /// - /// - /// the function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - if (!onComplete) { return; } - try { - var result = onComplete(this._value); - if (result && typeof result === "object" && typeof result.done === "function") { - result.done(); - } - } catch (ex) { - // force the exception to be thrown asynchronously to avoid any try/catch blocks - Promise._doneHandler(ex); - } - }, - then: function CompletePromise_then(onComplete) { - /// - /// - /// Allows you to specify the work to be done on the fulfillment of the promised value, - /// the error handling to be performed if the promise fails to fulfill - /// a value, and the handling of progress notifications along the way. - /// - /// - /// The function to be called if the promise is fulfilled successfully with a value. - /// The value is passed as the single argument. If the value is null, the value is returned. - /// The value returned from the function becomes the fulfilled value of the promise returned by - /// then(). If an exception is thrown while this function is being executed, the promise returned - /// by then() moves into the error state. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. If it is null, the error is forwarded. - /// The value returned from the function becomes the fulfilled value of the promise returned by then(). - /// - /// - /// The function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - /// The promise whose value is the result of executing the complete or - /// error function. - /// - /// - try { - // If the value returned from the completion handler is the same as the value - // provided to the completion handler then there is no need for a new promise. - // - var newValue = onComplete ? onComplete(this._value) : this._value; - return newValue === this._value ? this : new CompletePromise(newValue); - } catch (ex) { - return new ExceptionPromise(ex); - } - } - }, { - supportedForProcessing: false - } - ); - - // - // Promise is the user-creatable WinJS.Promise object. - // - - function timeout(timeoutMS) { - var id; - return new Promise( - function (c) { - if (timeoutMS) { - id = _Global.setTimeout(c, timeoutMS); - } else { - _BaseCoreUtils._setImmediate(c); - } - }, - function () { - if (id) { - _Global.clearTimeout(id); - } - } - ); - } - - function timeoutWithPromise(timeout, promise) { - var cancelPromise = function () { promise.cancel(); }; - var cancelTimeout = function () { timeout.cancel(); }; - timeout.then(cancelPromise); - promise.then(cancelTimeout, cancelTimeout); - return promise; - } - - var staticCanceledPromise; - - var Promise = _Base.Class.derive(PromiseStateMachine, - function Promise_ctor(init, oncancel) { - /// - /// - /// A promise provides a mechanism to schedule work to be done on a value that - /// has not yet been computed. It is a convenient abstraction for managing - /// interactions with asynchronous APIs. - /// - /// - /// The function that is called during construction of the promise. The function - /// is given three arguments (complete, error, progress). Inside this function - /// you should add event listeners for the notifications supported by this value. - /// - /// - /// The function to call if a consumer of this promise wants - /// to cancel its undone work. Promises are not required to - /// support cancellation. - /// - /// - - if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.promise))) { - this._stack = Promise._getStack(); - } - - this._oncancel = oncancel; - this._setState(state_created); - this._run(); - - try { - var complete = this._completed.bind(this); - var error = this._error.bind(this); - var progress = this._progress.bind(this); - init(complete, error, progress); - } catch (ex) { - this._setExceptionValue(ex); - } - }, { - _oncancel: null, - - _cancelAction: function () { - // BEGIN monaco change - try { - if (this._oncancel) { - this._oncancel(); - } else { - throw new Error('Promise did not implement oncancel'); - } - } catch (ex) { - // Access fields to get them created - var msg = ex.message; - var stack = ex.stack; - promiseEventListeners.dispatchEvent('error', ex); - } - // END monaco change - }, - _cleanupAction: function () { this._oncancel = null; } - }, { - - addEventListener: function Promise_addEventListener(eventType, listener, capture) { - /// - /// - /// Adds an event listener to the control. - /// - /// - /// The type (name) of the event. - /// - /// - /// The listener to invoke when the event is raised. - /// - /// - /// Specifies whether or not to initiate capture. - /// - /// - promiseEventListeners.addEventListener(eventType, listener, capture); - }, - any: function Promise_any(values) { - /// - /// - /// Returns a promise that is fulfilled when one of the input promises - /// has been fulfilled. - /// - /// - /// An array that contains promise objects or objects whose property - /// values include promise objects. - /// - /// - /// A promise that on fulfillment yields the value of the input (complete or error). - /// - /// - return new Promise( - function (complete, error) { - var keys = Object.keys(values); - if (keys.length === 0) { - complete(); - } - var canceled = 0; - keys.forEach(function (key) { - Promise.as(values[key]).then( - function () { complete({ key: key, value: values[key] }); }, - function (e) { - if (e instanceof Error && e.name === canceledName) { - if ((++canceled) === keys.length) { - complete(Promise.cancel); - } - return; - } - error({ key: key, value: values[key] }); - } - ); - }); - }, - function () { - var keys = Object.keys(values); - keys.forEach(function (key) { - var promise = Promise.as(values[key]); - if (typeof promise.cancel === "function") { - promise.cancel(); - } - }); - } - ); - }, - as: function Promise_as(value) { - /// - /// - /// Returns a promise. If the object is already a promise it is returned; - /// otherwise the object is wrapped in a promise. - /// - /// - /// The value to be treated as a promise. - /// - /// - /// A promise. - /// - /// - if (value && typeof value === "object" && typeof value.then === "function") { - return value; - } - return new CompletePromise(value); - }, - /// - /// Canceled promise value, can be returned from a promise completion handler - /// to indicate cancelation of the promise chain. - /// - cancel: { - get: function () { - return (staticCanceledPromise = staticCanceledPromise || new ErrorPromise(new _ErrorFromName(canceledName))); - } - }, - dispatchEvent: function Promise_dispatchEvent(eventType, details) { - /// - /// - /// Raises an event of the specified type and properties. - /// - /// - /// The type (name) of the event. - /// - /// - /// The set of additional properties to be attached to the event object. - /// - /// - /// Specifies whether preventDefault was called on the event. - /// - /// - return promiseEventListeners.dispatchEvent(eventType, details); - }, - is: function Promise_is(value) { - /// - /// - /// Determines whether a value fulfills the promise contract. - /// - /// - /// A value that may be a promise. - /// - /// - /// true if the specified value is a promise, otherwise false. - /// - /// - return value && typeof value === "object" && typeof value.then === "function"; - }, - join: function Promise_join(values) { - /// - /// - /// Creates a promise that is fulfilled when all the values are fulfilled. - /// - /// - /// An object whose fields contain values, some of which may be promises. - /// - /// - /// A promise whose value is an object with the same field names as those of the object in the values parameter, where - /// each field value is the fulfilled value of a promise. - /// - /// - return new Promise( - function (complete, error, progress) { - var keys = Object.keys(values); - var errors = Array.isArray(values) ? [] : {}; - var results = Array.isArray(values) ? [] : {}; - var undefineds = 0; - var pending = keys.length; - var argDone = function (key) { - if ((--pending) === 0) { - var errorCount = Object.keys(errors).length; - if (errorCount === 0) { - complete(results); - } else { - var canceledCount = 0; - keys.forEach(function (key) { - var e = errors[key]; - if (e instanceof Error && e.name === canceledName) { - canceledCount++; - } - }); - if (canceledCount === errorCount) { - complete(Promise.cancel); - } else { - error(errors); - } - } - } else { - progress({ Key: key, Done: true }); - } - }; - keys.forEach(function (key) { - var value = values[key]; - if (value === undefined) { - undefineds++; - } else { - Promise.then(value, - function (value) { results[key] = value; argDone(key); }, - function (value) { errors[key] = value; argDone(key); } - ); - } - }); - pending -= undefineds; - if (pending === 0) { - complete(results); - return; - } - }, - function () { - Object.keys(values).forEach(function (key) { - var promise = Promise.as(values[key]); - if (typeof promise.cancel === "function") { - promise.cancel(); - } - }); - } - ); - }, - removeEventListener: function Promise_removeEventListener(eventType, listener, capture) { - /// - /// - /// Removes an event listener from the control. - /// - /// - /// The type (name) of the event. - /// - /// - /// The listener to remove. - /// - /// - /// Specifies whether or not to initiate capture. - /// - /// - promiseEventListeners.removeEventListener(eventType, listener, capture); - }, - supportedForProcessing: false, - then: function Promise_then(value, onComplete, onError, onProgress) { - /// - /// - /// A static version of the promise instance method then(). - /// - /// - /// the value to be treated as a promise. - /// - /// - /// The function to be called if the promise is fulfilled with a value. - /// If it is null, the promise simply - /// returns the value. The value is passed as the single argument. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. - /// - /// - /// The function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - /// A promise whose value is the result of executing the provided complete function. - /// - /// - return Promise.as(value).then(onComplete, onError, onProgress); - }, - thenEach: function Promise_thenEach(values, onComplete, onError, onProgress) { - /// - /// - /// Performs an operation on all the input promises and returns a promise - /// that has the shape of the input and contains the result of the operation - /// that has been performed on each input. - /// - /// - /// A set of values (which could be either an array or an object) of which some or all are promises. - /// - /// - /// The function to be called if the promise is fulfilled with a value. - /// If the value is null, the promise returns the value. - /// The value is passed as the single argument. - /// - /// - /// The function to be called if the promise is fulfilled with an error. The error - /// is passed as the single argument. - /// - /// - /// The function to be called if the promise reports progress. Data about the progress - /// is passed as the single argument. Promises are not required to support - /// progress. - /// - /// - /// A promise that is the result of calling Promise.join on the values parameter. - /// - /// - var result = Array.isArray(values) ? [] : {}; - Object.keys(values).forEach(function (key) { - result[key] = Promise.as(values[key]).then(onComplete, onError, onProgress); - }); - return Promise.join(result); - }, - timeout: function Promise_timeout(time, promise) { - /// - /// - /// Creates a promise that is fulfilled after a timeout. - /// - /// - /// The timeout period in milliseconds. If this value is zero or not specified - /// setImmediate is called, otherwise setTimeout is called. - /// - /// - /// A promise that will be canceled if it doesn't complete before the - /// timeout has expired. - /// - /// - /// A promise that is completed asynchronously after the specified timeout. - /// - /// - var to = timeout(time); - return promise ? timeoutWithPromise(to, promise) : to; - }, - wrap: function Promise_wrap(value) { - /// - /// - /// Wraps a non-promise value in a promise. You can use this function if you need - /// to pass a value to a function that requires a promise. - /// - /// - /// Some non-promise value to be wrapped in a promise. - /// - /// - /// A promise that is successfully fulfilled with the specified value - /// - /// - return new CompletePromise(value); - }, - wrapError: function Promise_wrapError(error) { - /// - /// - /// Wraps a non-promise error value in a promise. You can use this function if you need - /// to pass an error to a function that requires a promise. - /// - /// - /// A non-promise error value to be wrapped in a promise. - /// - /// - /// A promise that is in an error state with the specified value. - /// - /// - return new ErrorPromise(error); - }, - - _veryExpensiveTagWithStack: { - get: function () { return tagWithStack; }, - set: function (value) { tagWithStack = value; } - }, - _veryExpensiveTagWithStack_tag: tag, - _getStack: function () { - if (_Global.Debug && _Global.Debug.debuggerEnabled) { - try { throw new Error(); } catch (e) { return e.stack; } - } - }, - - _cancelBlocker: function Promise__cancelBlocker(input, oncancel) { - // - // Returns a promise which on cancelation will still result in downstream cancelation while - // protecting the promise 'input' from being canceled which has the effect of allowing - // 'input' to be shared amoung various consumers. - // - if (!Promise.is(input)) { - return Promise.wrap(input); - } - var complete; - var error; - var output = new Promise( - function (c, e) { - complete = c; - error = e; - }, - function () { - complete = null; - error = null; - oncancel && oncancel(); - } - ); - input.then( - function (v) { complete && complete(v); }, - function (e) { error && error(e); } - ); - return output; - }, - - } - ); - Object.defineProperties(Promise, _Events.createEventProperties(errorET)); - - Promise._doneHandler = function (value) { - _BaseCoreUtils._setImmediate(function Promise_done_rethrow() { - throw value; - }); - }; - - return { - PromiseStateMachine: PromiseStateMachine, - Promise: Promise, - state_created: state_created - }; -}); - -_winjs("WinJS/Promise", ["WinJS/Core/_Base","WinJS/Promise/_StateMachine"], function promiseInit( _Base, _StateMachine) { - "use strict"; - - _Base.Namespace.define("WinJS", { - Promise: _StateMachine.Promise - }); - - return _StateMachine.Promise; -}); - -__winjs_exports = _modules["WinJS/Core/_WinJS"]; -__winjs_exports.TPromise = __winjs_exports.Promise; -__winjs_exports.PPromise = __winjs_exports.Promise; - -// ESM-comment-begin -if (typeof exports === 'undefined' && typeof define === 'function' && define.amd) { - define([], __winjs_exports); -} else { - module.exports = __winjs_exports; -} -// ESM-comment-end - -})(); - -// ESM-uncomment-begin -// export var Promise = __winjs_exports.Promise; -// export var TPromise = __winjs_exports.TPromise; -// export var PPromise = __winjs_exports.PPromise; -// ESM-uncomment-end diff --git a/src/vs/base/test/common/async.test.ts b/src/vs/base/test/common/async.test.ts index 65c4d110930..a18872a82b7 100644 --- a/src/vs/base/test/common/async.test.ts +++ b/src/vs/base/test/common/async.test.ts @@ -39,17 +39,6 @@ suite('Async', () => { return result; }); - // test('Cancel callback behaviour', async function () { - // let withCancelCallback = new WinJsPromise(() => { }, () => { }); - // let withoutCancelCallback = new TPromise(() => { }); - - // withCancelCallback.cancel(); - // (withoutCancelCallback as WinJsPromise).cancel(); - - // await withCancelCallback.then(undefined, err => { assert.ok(isPromiseCanceledError(err)); }); - // await withoutCancelCallback.then(undefined, err => { assert.ok(isPromiseCanceledError(err)); }); - // }); - // Cancelling a sync cancelable promise will fire the cancelled token. // Also, every `then` callback runs in another execution frame. test('CancelablePromise execution order (sync)', function () { @@ -95,50 +84,6 @@ suite('Async', () => { return promise.then(() => assert.deepEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally'])); }); - // // Cancelling a sync tpromise will NOT cancel the promise, since it has resolved already. - // // Every `then` callback runs sync in the same execution frame, thus `finally` executes - // // before `afterCancel`. - // test('TPromise execution order (sync)', function () { - // const order = []; - // let promise = new WinJsPromise(resolve => { - // order.push('in executor'); - // resolve(1234); - // }, () => order.push('cancelled')); - - // order.push('afterCreate'); - - // promise = promise - // .then(void 0, err => null) - // .then(() => order.push('finally')); - - // promise.cancel(); - // order.push('afterCancel'); - - // return promise.then(() => assert.deepEqual(order, ['in executor', 'afterCreate', 'finally', 'afterCancel'])); - // }); - - // // Cancelling an async tpromise will cancel the promise. - // // Every `then` callback runs sync on the same execution frame as the `cancel` call, - // // so finally still executes before `afterCancel`. - // test('TPromise execution order (async)', function () { - // const order = []; - // let promise = new WinJsPromise(resolve => { - // order.push('in executor'); - // setTimeout(() => resolve(1234)); - // }, () => order.push('cancelled')); - - // order.push('afterCreate'); - - // promise = promise - // .then(void 0, err => null) - // .then(() => order.push('finally')); - - // promise.cancel(); - // order.push('afterCancel'); - - // return promise.then(() => assert.deepEqual(order, ['in executor', 'afterCreate', 'cancelled', 'finally', 'afterCancel'])); - // }); - test('cancelablePromise - get inner result', async function () { let promise = async.createCancelablePromise(token => { return async.timeout(12).then(_ => 1234); diff --git a/src/vs/base/test/common/winjs.promise.test.ts b/src/vs/base/test/common/winjs.promise.test.ts deleted file mode 100644 index 15c9aa68112..00000000000 --- a/src/vs/base/test/common/winjs.promise.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import * as assert from 'assert'; -import * as winjs from 'vs/base/common/winjs.base'; - -suite('WinJS and ES6 Promises', function () { - - test('Promise.resolve', () => { - let resolveTPromise; - const tPromise = new winjs.Promise((c, e) => { - resolveTPromise = c; - }); - - const es6Promise = Promise.resolve(tPromise); - - const done = es6Promise.then(function (result) { - assert.equal(result, 'passed'); - }); - - resolveTPromise('passed'); - - return done; - }); - - test('new Promise', function () { - let resolveTPromise; - const tPromise = new winjs.Promise((c, e) => { - resolveTPromise = c; - }); - - const es6Promise = new Promise(function (c, e) { - c(tPromise); - }); - - const done = es6Promise.then(function (result) { - assert.equal(result, 'passed'); - }); - - resolveTPromise('passed'); - - return done; - }); - - test('1. Uncaught TypeError: this._state.then is not a function', () => { - let p1 = winjs.Promise.wrap(new Promise(function (c, e) { c(1); })); - Promise.all([p1]); - }); - - test('2. Uncaught TypeError: this._state.then is not a function', () => { - let p1 = winjs.Promise.wrap(new Promise(function (c, e) { c(1); })); - let thenFunc = p1.then.bind(p1); - setTimeout(() => { - thenFunc(() => 0); - }, 0); - }); - - test('3. Uncaught TypeError: this._state.then is not a function', () => { - let c; - let p1 = new winjs.Promise(function (_c, e) { c = _c; }); - let thenFunc = p1.then.bind(p1); - setTimeout(() => { - c(1); - thenFunc(() => 0); - }, 0); - }); -}); diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 12da992ec0f..fafaab3c05b 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -10,7 +10,6 @@ import { assign } from 'vs/base/common/objects'; import { toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { flatten } from 'vs/base/common/arrays'; import { extract, ExtractError, zip, IFile } from 'vs/platform/node/zip'; -import { ValueCallback, ErrorCallback } from 'vs/base/common/winjs.base'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IExtensionManifest, IGalleryMetadata, @@ -292,7 +291,7 @@ export class ExtensionManagementService extends Disposable implements IExtension if (!cancellablePromise) { let operation: InstallOperation = InstallOperation.Install; - let cancellationToken: CancellationToken, successCallback: ValueCallback, errorCallback: ErrorCallback; + let cancellationToken: CancellationToken, successCallback: (a?: any) => void, errorCallback: (e?: any) => any; cancellablePromise = createCancelablePromise(token => { cancellationToken = token; return new Promise((c, e) => { successCallback = c; errorCallback = e; }); }); this.installingExtensions.set(key, cancellablePromise); diff --git a/test/all.js b/test/all.js index db8fee59cf8..350e8606800 100644 --- a/test/all.js +++ b/test/all.js @@ -50,9 +50,9 @@ function main() { baseUrl: path.join(path.dirname(__dirname), 'src'), paths: { 'vs/css': '../test/css.mock', - 'vs': `../${ out }/vs`, - 'lib': `../${ out }/lib`, - 'bootstrap-fork': `../${ out }/bootstrap-fork` + 'vs': `../${out}/vs`, + 'lib': `../${out}/lib`, + 'bootstrap-fork': `../${out}/bootstrap-fork` }, catchError: true }; @@ -79,10 +79,10 @@ function main() { if (argv.forceLoad) { var allFiles = glob.sync(out + '/vs/**/*.js'); - allFiles = allFiles.map(function(source) { + allFiles = allFiles.map(function (source) { return path.join(__dirname, '..', source); }); - allFiles = allFiles.filter(function(source) { + allFiles = allFiles.filter(function (source) { if (seenSources[source]) { return false; } @@ -94,7 +94,7 @@ function main() { } return true; }); - allFiles.forEach(function(source, index) { + allFiles.forEach(function (source, index) { var contents = fs.readFileSync(source).toString(); contents = instrumenter.instrumentSync(contents, source); var stopAt = contents.indexOf('}\n__cov'); @@ -106,18 +106,18 @@ function main() { }); } - let remapIgnores = /\b((winjs\.base)|(marked)|(raw\.marked)|(nls)|(css))\.js$/; + let remapIgnores = /\b((marked)|(raw\.marked)|(nls)|(css))\.js$/; var remappedCoverage = i_remap(global.__coverage__, { exclude: remapIgnores }).getFinalCoverage(); // The remapped coverage comes out with broken paths - var toUpperDriveLetter = function(str) { + var toUpperDriveLetter = function (str) { if (/^[a-z]:/.test(str)) { return str.charAt(0).toUpperCase() + str.substr(1); } return str; }; - var toLowerDriveLetter = function(str) { + var toLowerDriveLetter = function (str) { if (/^[A-Z]:/.test(str)) { return str.charAt(0).toLowerCase() + str.substr(1); } @@ -125,7 +125,7 @@ function main() { }; var REPO_PATH = toUpperDriveLetter(path.join(__dirname, '..')); - var fixPath = function(brokenPath) { + var fixPath = function (brokenPath) { var startIndex = brokenPath.indexOf(REPO_PATH); if (startIndex === -1) { return toLowerDriveLetter(brokenPath); @@ -154,7 +154,7 @@ function main() { } var reporter = new istanbul.Reporter(null, coveragePath); reporter.addAll(reportTypes); - reporter.write(collector, true, function () {}); + reporter.write(collector, true, function () { }); }); } @@ -196,7 +196,7 @@ function main() { }; } else if (argv.run) { var tests = (typeof argv.run === 'string') ? [argv.run] : argv.run; - var modulesToLoad = tests.map(function(test) { + var modulesToLoad = tests.map(function (test) { test = test.replace(/^src/, 'out'); test = test.replace(/\.ts$/, '.js'); return path.relative(src, path.resolve(test)).replace(/(\.js)|(\.js\.map)$/, '').replace(/\\/g, '/'); @@ -205,12 +205,12 @@ function main() { define(modulesToLoad, () => cb(null), cb); }; } else if (argv['only-monaco-editor']) { - loadFunc = function(cb) { + loadFunc = function (cb) { glob(TEST_GLOB, { cwd: src }, function (err, files) { var modulesToLoad = files.map(function (file) { return file.replace(/\.js$/, ''); }); - modulesToLoad = modulesToLoad.filter(function(module) { + modulesToLoad = modulesToLoad.filter(function (module) { if (/^vs\/workbench\//.test(module)) { return false; } @@ -227,7 +227,7 @@ function main() { }); }; } else { - loadFunc = function(cb) { + loadFunc = function (cb) { glob(TEST_GLOB, { cwd: src }, function (err, files) { var modulesToLoad = files.map(function (file) { return file.replace(/\.js$/, ''); @@ -237,7 +237,7 @@ function main() { }; } - loadFunc(function(err) { + loadFunc(function (err) { if (err) { console.error(err); return process.exit(1); @@ -270,7 +270,7 @@ function main() { }); // replace the default unexpected error handler to be useful during tests - loader(['vs/base/common/errors'], function(errors) { + loader(['vs/base/common/errors'], function (errors) { errors.setUnexpectedErrorHandler(function (err) { let stack = (err && err.stack) || (new Error().stack); unexpectedErrors.push((err && err.message ? err.message : err) + '\n' + stack); @@ -286,4 +286,4 @@ if (process.argv.some(function (a) { return /^--browser/.test(a); })) { require('./browser'); } else { main(); -} \ No newline at end of file +} diff --git a/test/electron/renderer.js b/test/electron/renderer.js index 0dca5a84b62..addb1f0b93c 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -63,7 +63,7 @@ function createCoverageReport(opts) { return resolve(undefined); } - const exclude = /\b((winjs\.base)|(marked)|(raw\.marked)|(nls)|(css))\.js$/; + const exclude = /\b((marked)|(raw\.marked)|(nls)|(css))\.js$/; const remappedCoverage = i_remap(global.__coverage__, { exclude: exclude }).getFinalCoverage(); // The remapped coverage comes out with broken paths