tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

build-debugger.js (3494B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 "use strict";
      6 
      7 // eslint-disable-next-line mozilla/reject-relative-requires
      8 const Babel = require("./babel");
      9 const _path = require("path");
     10 
     11 function isRequire(t, node) {
     12  return node && t.isCallExpression(node) && node.callee.name == "require";
     13 }
     14 
     15 function shouldLazyLoad(value) {
     16  return (
     17    !value.includes("codemirror/") &&
     18    !value.endsWith(".properties") &&
     19    !value.startsWith("devtools/") &&
     20    !value.startsWith("resource://devtools/") &&
     21    // XXX: the lazyRequire rewriter (in transformMC) fails for this module, it
     22    // evaluates `t.thisExpression()` as `void 0` instead of `this`. But the
     23    // rewriter still works for other call sites and seems mandatory for the
     24    // debugger to start successfully (lazy requires help to break circular
     25    // dependencies).
     26    value !== "resource://gre/modules/AppConstants.jsm"
     27  );
     28 }
     29 
     30 /**
     31 * This Babel plugin is used to transpile a single Debugger module into a module that
     32 * can be loaded in Firefox via the regular DevTools loader.
     33 */
     34 function transformMC({ types: t }) {
     35  return {
     36    visitor: {
     37      StringLiteral(path, state) {
     38        const { filePath } = state.opts;
     39        let value = path.node.value;
     40 
     41        if (!isRequire(t, path.parent)) {
     42          return;
     43        }
     44 
     45        if (shouldLazyLoad(value)) {
     46          const requireCall = path.parentPath;
     47          const declarator = requireCall.parentPath;
     48          const declaration = declarator.parentPath;
     49 
     50          // require()s that are not assigned to a variable cannot be safely lazily required
     51          // since we lack anything to initiate the require (= the getter for the variable)
     52          if (declarator.type !== "VariableDeclarator") {
     53            return;
     54          }
     55 
     56          // update relative paths to be "absolute" (starting with devtools/)
     57          // e.g. ./utils/source-queue
     58          if (value.startsWith(".")) {
     59            // Create full path
     60            // e.g. z:\build\build\src\devtools\client\debugger\src\utils\source-queue
     61            let newValue = _path.join(_path.dirname(filePath), value);
     62 
     63            // Select the devtools portion of the path
     64            // e.g. devtools\client\debugger\src\utils\source-queue
     65            if (!newValue.startsWith("devtools")) {
     66              newValue = newValue.match(/^(.*?)(devtools.*)/)[2];
     67            }
     68 
     69            // Replace forward slashes with back slashes
     70            // e.g devtools/client/debugger/src/utils/source-queue
     71            newValue = newValue.replace(/\\/g, "/");
     72 
     73            value = newValue;
     74          }
     75 
     76          // rewrite to: loader.lazyRequireGetter(this, "variableName", "pathToFile")
     77          const lazyRequire = t.callExpression(
     78            t.memberExpression(
     79              t.identifier("loader"),
     80              t.identifier("lazyRequireGetter")
     81            ),
     82            [
     83              t.thisExpression(),
     84              t.stringLiteral(declarator.node.id.name || ""),
     85              t.stringLiteral(value),
     86            ]
     87          );
     88 
     89          declaration.replaceWith(lazyRequire);
     90        }
     91      },
     92    },
     93  };
     94 }
     95 
     96 Babel.registerPlugin("transform-mc", transformMC);
     97 
     98 module.exports = function (filePath) {
     99  return [
    100    "proposal-class-properties",
    101    "transform-modules-commonjs",
    102    ["transform-mc", { filePath }],
    103  ];
    104 };