tor-browser

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

helpers.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 import * as t from "@babel/types";
      6 
      7 export function isFunction(node) {
      8  return (
      9    t.isFunction(node) ||
     10    t.isArrowFunctionExpression(node) ||
     11    t.isObjectMethod(node) ||
     12    t.isClassMethod(node)
     13  );
     14 }
     15 
     16 export function isAwaitExpression(path) {
     17  const { node, parent } = path;
     18  return (
     19    t.isAwaitExpression(node) ||
     20    t.isAwaitExpression(parent.init) ||
     21    t.isAwaitExpression(parent)
     22  );
     23 }
     24 
     25 export function isYieldExpression(path) {
     26  const { node, parent } = path;
     27  return (
     28    t.isYieldExpression(node) ||
     29    t.isYieldExpression(parent.init) ||
     30    t.isYieldExpression(parent)
     31  );
     32 }
     33 
     34 export function getMemberExpression(root) {
     35  function _getMemberExpression(node, expr) {
     36    if (t.isMemberExpression(node)) {
     37      expr = [node.property.name].concat(expr);
     38      return _getMemberExpression(node.object, expr);
     39    }
     40 
     41    if (t.isCallExpression(node)) {
     42      return [];
     43    }
     44 
     45    if (t.isThisExpression(node)) {
     46      return ["this"].concat(expr);
     47    }
     48 
     49    return [node.name].concat(expr);
     50  }
     51 
     52  const expr = _getMemberExpression(root, []);
     53  return expr.join(".");
     54 }
     55 
     56 export function getVariables(dec) {
     57  if (!dec.id) {
     58    return [];
     59  }
     60 
     61  if (t.isArrayPattern(dec.id)) {
     62    if (!dec.id.elements) {
     63      return [];
     64    }
     65 
     66    // NOTE: it's possible that an element is empty or has several variables
     67    // e.g. const [, a] = arr
     68    // e.g. const [{a, b }] = 2
     69    return dec.id.elements
     70      .filter(Boolean)
     71      .map(element => ({
     72        name: t.isAssignmentPattern(element)
     73          ? element.left.name
     74          : element.name || element.argument?.name,
     75        location: element.loc,
     76      }))
     77      .filter(({ name }) => name);
     78  }
     79 
     80  return [
     81    {
     82      name: dec.id.name,
     83      location: dec.loc,
     84    },
     85  ];
     86 }
     87 
     88 /**
     89 * Add the identifiers for a given object pattern.
     90 *
     91 * @param {Array.<object>} identifiers
     92 *        the current list of identifiers where to push the new identifiers
     93 *        related to this path.
     94 * @param {Set<string>} identifiersKeys
     95 *        List of currently registered identifier location key.
     96 * @param {object} pattern
     97 */
     98 export function addPatternIdentifiers(identifiers, identifiersKeys, pattern) {
     99  let items;
    100  if (t.isObjectPattern(pattern)) {
    101    items = pattern.properties.map(({ value }) => value);
    102  }
    103 
    104  if (t.isArrayPattern(pattern)) {
    105    items = pattern.elements;
    106  }
    107 
    108  if (items) {
    109    addIdentifiers(identifiers, identifiersKeys, items);
    110  }
    111 }
    112 
    113 function addIdentifiers(identifiers, identifiersKeys, items) {
    114  for (const item of items) {
    115    if (t.isObjectPattern(item) || t.isArrayPattern(item)) {
    116      addPatternIdentifiers(identifiers, identifiersKeys, item);
    117    } else if (t.isIdentifier(item)) {
    118      if (!identifiersKeys.has(nodeLocationKey(item.loc))) {
    119        identifiers.push({
    120          name: item.name,
    121          expression: item.name,
    122          location: item.loc,
    123        });
    124      }
    125    }
    126  }
    127 }
    128 
    129 // Top Level checks the number of "body" nodes in the ancestor chain
    130 // if the node is top-level, then it shoul only have one body.
    131 export function isTopLevel(ancestors) {
    132  return ancestors.filter(ancestor => ancestor.key == "body").length == 1;
    133 }
    134 
    135 export function nodeLocationKey({ start, end }) {
    136  return `${start.line}:${start.column}:${end.line}:${end.column}`;
    137 }