fune/toolkit/components/asyncshutdown/nsAsyncShutdown.js
Andrew McCreight 5dec0e0beb Bug 1432992, part 1 - Remove definitions of Ci, Cr, Cc, and Cu. r=florian
This patch was autogenerated by my decomponents.py

It covers almost every file with the extension js, jsm, html, py,
xhtml, or xul.

It removes blank lines after removed lines, when the removed lines are
preceded by either blank lines or the start of a new block. The "start
of a new block" is defined fairly hackily: either the line starts with
//, ends with */, ends with {, <![CDATA[, """ or '''. The first two
cover comments, the third one covers JS, the fourth covers JS embedded
in XUL, and the final two cover JS embedded in Python. This also
applies if the removed line was the first line of the file.

It covers the pattern matching cases like "var {classes: Cc,
interfaces: Ci, utils: Cu, results: Cr} = Components;". It'll remove
the entire thing if they are all either Ci, Cr, Cc or Cu, or it will
remove the appropriate ones and leave the residue behind. If there's
only one behind, then it will turn it into a normal, non-pattern
matching variable definition. (For instance, "const { classes: Cc,
Constructor: CC, interfaces: Ci, utils: Cu } = Components" becomes
"const CC = Components.Constructor".)

MozReview-Commit-ID: DeSHcClQ7cG

--HG--
extra : rebase_source : d9c41878036c1ef7766ef5e91a7005025bc1d72b
2018-02-06 09:36:57 -08:00

268 lines
7.6 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* An implementation of nsIAsyncShutdown* based on AsyncShutdown.jsm
*/
"use strict";
var XPCOMUtils = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {}).XPCOMUtils;
ChromeUtils.defineModuleGetter(this, "AsyncShutdown",
"resource://gre/modules/AsyncShutdown.jsm");
/**
* Conversion between nsIPropertyBag and JS object
*/
var PropertyBagConverter = {
// From nsIPropertyBag to JS
toObject(bag) {
if (!(bag instanceof Ci.nsIPropertyBag)) {
throw new TypeError("Not a property bag");
}
let result = {};
let enumerator = bag.enumerator;
while (enumerator.hasMoreElements()) {
let {name, value: property} = enumerator.getNext().QueryInterface(Ci.nsIProperty);
let value = this.toValue(property);
result[name] = value;
}
return result;
},
toValue(property) {
if (typeof property != "object") {
return property;
}
if (Array.isArray(property)) {
return property.map(this.toValue, this);
}
if (property && property instanceof Ci.nsIPropertyBag) {
return this.toObject(property);
}
return property;
},
// From JS to nsIPropertyBag
fromObject(obj) {
if (obj == null || typeof obj != "object") {
throw new TypeError("Invalid object: " + obj);
}
let bag = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag);
for (let k of Object.keys(obj)) {
let value = this.fromValue(obj[k]);
bag.setProperty(k, value);
}
return bag;
},
fromValue(value) {
if (typeof value == "function") {
return null; // Emulating the behavior of JSON.stringify with functions
}
if (Array.isArray(value)) {
return value.map(this.fromValue, this);
}
if (value == null || typeof value != "object") {
// Auto-converted to nsIVariant
return value;
}
return this.fromObject(value);
},
};
/**
* Construct an instance of nsIAsyncShutdownClient from a
* AsyncShutdown.Barrier client.
*
* @param {object} moduleClient A client, as returned from the `client`
* property of an instance of `AsyncShutdown.Barrier`. This client will
* serve as back-end for methods `addBlocker` and `removeBlocker`.
* @constructor
*/
function nsAsyncShutdownClient(moduleClient) {
if (!moduleClient) {
throw new TypeError("nsAsyncShutdownClient expects one argument");
}
this._moduleClient = moduleClient;
this._byName = new Map();
}
nsAsyncShutdownClient.prototype = {
_getPromisified(xpcomBlocker) {
let candidate = this._byName.get(xpcomBlocker.name);
if (!candidate) {
return null;
}
if (candidate.xpcom === xpcomBlocker) {
return candidate.jsm;
}
return null;
},
_setPromisified(xpcomBlocker, moduleBlocker) {
let candidate = this._byName.get(xpcomBlocker.name);
if (!candidate) {
this._byName.set(xpcomBlocker.name, {xpcom: xpcomBlocker,
jsm: moduleBlocker});
return;
}
if (candidate.xpcom === xpcomBlocker) {
return;
}
throw new Error("We have already registered a distinct blocker with the same name: " + xpcomBlocker.name);
},
_deletePromisified(xpcomBlocker) {
let candidate = this._byName.get(xpcomBlocker.name);
if (!candidate || candidate.xpcom !== xpcomBlocker) {
return false;
}
this._byName.delete(xpcomBlocker.name);
return true;
},
get jsclient() {
return this._moduleClient;
},
get name() {
return this._moduleClient.name;
},
addBlocker(/* nsIAsyncShutdownBlocker*/ xpcomBlocker,
fileName, lineNumber, stack) {
// We need a Promise-based function with the same behavior as
// `xpcomBlocker`. Furthermore, to support `removeBlocker`, we
// need to ensure that we always get the same Promise-based
// function if we call several `addBlocker`/`removeBlocker` several
// times with the same `xpcomBlocker`.
//
// Ideally, this should be done with a WeakMap() with xpcomBlocker
// as a key, but XPConnect NativeWrapped objects cannot serve as
// WeakMap keys.
//
let moduleBlocker = this._getPromisified(xpcomBlocker);
if (!moduleBlocker) {
moduleBlocker = () => new Promise(
// This promise is never resolved. By opposition to AsyncShutdown
// blockers, `nsIAsyncShutdownBlocker`s are always lifted by calling
// `removeBlocker`.
() => xpcomBlocker.blockShutdown(this)
);
this._setPromisified(xpcomBlocker, moduleBlocker);
}
this._moduleClient.addBlocker(xpcomBlocker.name,
moduleBlocker,
{
fetchState: () => {
let state = xpcomBlocker.state;
if (state) {
return PropertyBagConverter.toValue(state);
}
return null;
},
filename: fileName,
lineNumber,
stack,
});
},
removeBlocker(xpcomBlocker) {
let moduleBlocker = this._getPromisified(xpcomBlocker);
if (!moduleBlocker) {
return false;
}
this._deletePromisified(xpcomBlocker);
return this._moduleClient.removeBlocker(moduleBlocker);
},
/* ........ QueryInterface .............. */
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAsyncShutdownBarrier]),
classID: Components.ID("{314e9e96-cc37-4d5c-843b-54709ce11426}"),
};
/**
* Construct an instance of nsIAsyncShutdownBarrier from an instance
* of AsyncShutdown.Barrier.
*
* @param {object} moduleBarrier an instance if
* `AsyncShutdown.Barrier`. This instance will serve as back-end for
* all methods.
* @constructor
*/
function nsAsyncShutdownBarrier(moduleBarrier) {
this._client = new nsAsyncShutdownClient(moduleBarrier.client);
this._moduleBarrier = moduleBarrier;
}
nsAsyncShutdownBarrier.prototype = {
get state() {
return PropertyBagConverter.fromValue(this._moduleBarrier.state);
},
get client() {
return this._client;
},
wait(onReady) {
this._moduleBarrier.wait().then(() => {
onReady.done();
});
// By specification, _moduleBarrier.wait() cannot reject.
},
/* ........ QueryInterface .............. */
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAsyncShutdownBarrier]),
classID: Components.ID("{29a0e8b5-9111-4c09-a0eb-76cd02bf20fa}"),
};
function nsAsyncShutdownService() {
// Cache for the getters
for (let _k of
[// Parent process
"profileBeforeChange",
"profileChangeTeardown",
"quitApplicationGranted",
"sendTelemetry",
// Child processes
"contentChildShutdown",
// All processes
"webWorkersShutdown",
"xpcomWillShutdown",
]) {
let k = _k;
Object.defineProperty(this, k, {
configurable: true,
get() {
delete this[k];
let wrapped = AsyncShutdown[k]; // May be undefined, if we're on the wrong process.
let result = wrapped ? new nsAsyncShutdownClient(wrapped) : undefined;
Object.defineProperty(this, k, {
value: result
});
return result;
}
});
}
// Hooks for testing purpose
this.wrappedJSObject = {
_propertyBagConverter: PropertyBagConverter
};
}
nsAsyncShutdownService.prototype = {
makeBarrier(name) {
return new nsAsyncShutdownBarrier(new AsyncShutdown.Barrier(name));
},
/* ........ QueryInterface .............. */
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAsyncShutdownService]),
classID: Components.ID("{35c496de-a115-475d-93b5-ffa3f3ae6fe3}"),
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
nsAsyncShutdownService,
nsAsyncShutdownBarrier,
nsAsyncShutdownClient,
]);