tor-browser

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

rangeMetadata.js (3343B)


      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 { locColumn } from "./locColumn";
      6 import { positionCmp } from "./positionCmp";
      7 import { filterSortedArray } from "./filtering";
      8 
      9 // * match - Range contains a single identifier with matching start location
     10 // * contains - Range contains a single identifier with non-matching start
     11 // * multiple - Range contains multiple identifiers
     12 // * empty - Range contains no identifiers
     13 
     14 export async function loadRangeMetadata(
     15  location,
     16  originalAstScopes,
     17  { sourceMapLoader }
     18 ) {
     19  const originalRanges = await sourceMapLoader.getOriginalRanges(
     20    location.source.id
     21  );
     22 
     23  const sortedOriginalAstBindings = [];
     24  for (const item of originalAstScopes) {
     25    for (const name of Object.keys(item.bindings)) {
     26      for (const ref of item.bindings[name].refs) {
     27        sortedOriginalAstBindings.push(ref);
     28      }
     29    }
     30  }
     31  sortedOriginalAstBindings.sort((a, b) => positionCmp(a.start, b.start));
     32 
     33  let i = 0;
     34 
     35  return originalRanges.map(range => {
     36    const bindings = [];
     37 
     38    while (
     39      i < sortedOriginalAstBindings.length &&
     40      (sortedOriginalAstBindings[i].start.line < range.line ||
     41        (sortedOriginalAstBindings[i].start.line === range.line &&
     42          locColumn(sortedOriginalAstBindings[i].start) < range.columnStart))
     43    ) {
     44      i++;
     45    }
     46 
     47    while (
     48      i < sortedOriginalAstBindings.length &&
     49      sortedOriginalAstBindings[i].start.line === range.line &&
     50      locColumn(sortedOriginalAstBindings[i].start) >= range.columnStart &&
     51      locColumn(sortedOriginalAstBindings[i].start) < range.columnEnd
     52    ) {
     53      const lastBinding = bindings[bindings.length - 1];
     54      // Only add bindings when they're in new positions
     55      if (
     56        !lastBinding ||
     57        positionCmp(lastBinding.start, sortedOriginalAstBindings[i].start) !== 0
     58      ) {
     59        bindings.push(sortedOriginalAstBindings[i]);
     60      }
     61      i++;
     62    }
     63 
     64    let type = "empty";
     65    let singleDeclaration = true;
     66    if (bindings.length === 1) {
     67      const binding = bindings[0];
     68      if (
     69        binding.start.line === range.line &&
     70        binding.start.column === range.columnStart
     71      ) {
     72        type = "match";
     73      } else {
     74        type = "contains";
     75      }
     76    } else if (bindings.length > 1) {
     77      type = "multiple";
     78      const binding = bindings[0];
     79      const declStart =
     80        binding.type !== "ref" ? binding.declaration.start : null;
     81 
     82      singleDeclaration = bindings.every(b => {
     83        return (
     84          declStart &&
     85          b.type !== "ref" &&
     86          positionCmp(declStart, b.declaration.start) === 0
     87        );
     88      });
     89    }
     90 
     91    return {
     92      type,
     93      singleDeclaration,
     94      ...range,
     95    };
     96  });
     97 }
     98 
     99 export function findMatchingRange(sortedOriginalRanges, bindingRange) {
    100  return filterSortedArray(sortedOriginalRanges, range => {
    101    if (range.line < bindingRange.start.line) {
    102      return -1;
    103    }
    104    if (range.line > bindingRange.start.line) {
    105      return 1;
    106    }
    107 
    108    if (range.columnEnd <= locColumn(bindingRange.start)) {
    109      return -1;
    110    }
    111    if (range.columnStart > locColumn(bindingRange.start)) {
    112      return 1;
    113    }
    114 
    115    return 0;
    116  }).pop();
    117 }