summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js')
-rw-r--r--devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js b/devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js
new file mode 100644
index 0000000000..7a22313aca
--- /dev/null
+++ b/devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js
@@ -0,0 +1,117 @@
+/* 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/>. */
+
+import { locColumn } from "./locColumn";
+import { positionCmp } from "./positionCmp";
+import { filterSortedArray } from "./filtering";
+
+// * match - Range contains a single identifier with matching start location
+// * contains - Range contains a single identifier with non-matching start
+// * multiple - Range contains multiple identifiers
+// * empty - Range contains no identifiers
+
+export async function loadRangeMetadata(
+ location,
+ originalAstScopes,
+ { sourceMapLoader }
+) {
+ const originalRanges = await sourceMapLoader.getOriginalRanges(
+ location.sourceId
+ );
+
+ const sortedOriginalAstBindings = [];
+ for (const item of originalAstScopes) {
+ for (const name of Object.keys(item.bindings)) {
+ for (const ref of item.bindings[name].refs) {
+ sortedOriginalAstBindings.push(ref);
+ }
+ }
+ }
+ sortedOriginalAstBindings.sort((a, b) => positionCmp(a.start, b.start));
+
+ let i = 0;
+
+ return originalRanges.map(range => {
+ const bindings = [];
+
+ while (
+ i < sortedOriginalAstBindings.length &&
+ (sortedOriginalAstBindings[i].start.line < range.line ||
+ (sortedOriginalAstBindings[i].start.line === range.line &&
+ locColumn(sortedOriginalAstBindings[i].start) < range.columnStart))
+ ) {
+ i++;
+ }
+
+ while (
+ i < sortedOriginalAstBindings.length &&
+ sortedOriginalAstBindings[i].start.line === range.line &&
+ locColumn(sortedOriginalAstBindings[i].start) >= range.columnStart &&
+ locColumn(sortedOriginalAstBindings[i].start) < range.columnEnd
+ ) {
+ const lastBinding = bindings[bindings.length - 1];
+ // Only add bindings when they're in new positions
+ if (
+ !lastBinding ||
+ positionCmp(lastBinding.start, sortedOriginalAstBindings[i].start) !== 0
+ ) {
+ bindings.push(sortedOriginalAstBindings[i]);
+ }
+ i++;
+ }
+
+ let type = "empty";
+ let singleDeclaration = true;
+ if (bindings.length === 1) {
+ const binding = bindings[0];
+ if (
+ binding.start.line === range.line &&
+ binding.start.column === range.columnStart
+ ) {
+ type = "match";
+ } else {
+ type = "contains";
+ }
+ } else if (bindings.length > 1) {
+ type = "multiple";
+ const binding = bindings[0];
+ const declStart =
+ binding.type !== "ref" ? binding.declaration.start : null;
+
+ singleDeclaration = bindings.every(b => {
+ return (
+ declStart &&
+ b.type !== "ref" &&
+ positionCmp(declStart, b.declaration.start) === 0
+ );
+ });
+ }
+
+ return {
+ type,
+ singleDeclaration,
+ ...range,
+ };
+ });
+}
+
+export function findMatchingRange(sortedOriginalRanges, bindingRange) {
+ return filterSortedArray(sortedOriginalRanges, range => {
+ if (range.line < bindingRange.start.line) {
+ return -1;
+ }
+ if (range.line > bindingRange.start.line) {
+ return 1;
+ }
+
+ if (range.columnEnd <= locColumn(bindingRange.start)) {
+ return -1;
+ }
+ if (range.columnStart > locColumn(bindingRange.start)) {
+ return 1;
+ }
+
+ return 0;
+ }).pop();
+}