Bug 1381853 - Make defineLazyScriptGetter support lazy loading scripts exposing several symbols to the global scope, r=mconley,Mossop.
authorFlorian Quèze <florian@queze.net>
Sun, 23 Jul 2017 00:17:56 +0200
changeset 419139 2e738363519ef41c7a1e1ca08f436d3f8aa585af
parent 419138 f6d831fc2b2bea1fd6b82cd3c92ab34829832ce1
child 419140 527d222ce02b1237c0f7b4b197e955857fdd4b0a
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, Mossop
bugs1381853
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1381853 - Make defineLazyScriptGetter support lazy loading scripts exposing several symbols to the global scope, r=mconley,Mossop.
js/xpconnect/loader/XPCOMUtils.jsm
tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js
--- a/js/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/xpconnect/loader/XPCOMUtils.jsm
@@ -211,33 +211,43 @@ this.XPCOMUtils = {
   },
 
   /**
    * Defines a getter on a specified object for a script.  The script will not
    * be loaded until first use.
    *
    * @param aObject
    *        The object to define the lazy getter on.
-   * @param aName
+   * @param aNames
    *        The name of the getter to define on aObject for the script.
+   *        This can be a string if the script exports only one symbol,
+   *        or an array of strings if the script can be first accessed
+   *        from several different symbols.
    * @param aResource
    *        The URL used to obtain the script.
    */
-  defineLazyScriptGetter: function XPCU_defineLazyScriptGetter(aObject, aName,
+  defineLazyScriptGetter: function XPCU_defineLazyScriptGetter(aObject, aNames,
                                                                aResource)
   {
-    Object.defineProperty(aObject, aName, {
-      get: function () {
-        delete aObject[aName];
-        Services.scriptloader.loadSubScript(aResource, aObject);
-        return aObject[aName];
-      },
-      configurable: true,
-      enumerable: true
-    });
+    if (!Array.isArray(aNames)) {
+      aNames = [aNames];
+    }
+    for (let name of aNames) {
+      Object.defineProperty(aObject, name, {
+        get: function() {
+          for (let n of aNames) {
+            delete aObject[n];
+          }
+          Services.scriptloader.loadSubScript(aResource, aObject);
+          return aObject[name];
+        },
+        configurable: true,
+        enumerable: true
+      });
+    }
   },
 
   /**
    * Defines a getter on a specified object for a service.  The service will not
    * be obtained until first use.
    *
    * @param aObject
    *        The object to define the lazy getter on.
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js
@@ -99,16 +99,18 @@ module.exports = {
         var args = node.arguments.map(a => this.getASTSource(a)).join(", ");
         return this.getASTSource(node.callee) + "(" + args + ")";
       case "ObjectExpression":
         return "{}";
       case "ExpressionStatement":
         return this.getASTSource(node.expression) + ";";
       case "FunctionExpression":
         return "function() {}";
+      case "ArrayExpression":
+        return "[" + node.elements.map(this.getASTSource, this).join(",") + "]";
       case "ArrowFunctionExpression":
         return "() => {}";
       case "AssignmentExpression":
         return this.getASTSource(node.left) + " = " +
           this.getASTSource(node.right);
       default:
         throw new Error("getASTSource unsupported node type: " + node.type);
     }
@@ -274,16 +276,24 @@ module.exports = {
 
     for (let reg of callExpressionDefinitions) {
       let match = source.match(reg);
       if (match) {
         return [{ name: match[1], writable: true }];
       }
     }
 
+    if (node.expression.callee.type == "MemberExpression" &&
+        node.expression.callee.property.type == "Identifier" &&
+        node.expression.callee.property.name == "defineLazyScriptGetter") {
+      // The case where we have a single symbol as a string has already been
+      // handled by the regexp, so we have an array of symbols here.
+      return node.expression.arguments[1].elements.map(n => ({ name: n.value, writable: true }));
+    }
+
     return [];
   },
 
   /**
    * Add a variable to the current scope.
    * HACK: This relies on eslint internals so it could break at any time.
    *
    * @param {String} name