aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js
diff options
context:
space:
mode:
Diffstat (limited to 'vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js')
-rw-r--r--vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js b/vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js
new file mode 100644
index 0000000..f0700ca
--- /dev/null
+++ b/vanilla/node_modules/@bcoe/v8-coverage/src/lib/ascii.js
@@ -0,0 +1,145 @@
+const { compareRangeCovs } = require("./compare");
+
+function emitForest(trees) {
+ return emitForestLines(trees).join("\n");
+}
+
+function emitForestLines(trees) {
+ const colMap = getColMap(trees);
+ const header = emitOffsets(colMap);
+ return [header, ...trees.map((tree) => emitTree(tree, colMap).join("\n"))];
+}
+
+function getColMap(trees) {
+ const eventSet = new Set();
+ for (const tree of trees) {
+ const stack = [tree];
+ while (stack.length > 0) {
+ const cur = stack.pop();
+ eventSet.add(cur.start);
+ eventSet.add(cur.end);
+ for (const child of cur.children) {
+ stack.push(child);
+ }
+ }
+ }
+ const events = [...eventSet];
+ events.sort((a, b) => a - b);
+ let maxDigits = 1;
+ for (const event of events) {
+ maxDigits = Math.max(maxDigits, event.toString(10).length);
+ }
+ const colWidth = maxDigits + 3;
+ const colMap = new Map();
+ for (const [i, event] of events.entries()) {
+ colMap.set(event, i * colWidth);
+ }
+ return colMap;
+}
+
+function emitTree(tree, colMap) {
+ const layers = [];
+ let nextLayer = [tree];
+ while (nextLayer.length > 0) {
+ const layer = nextLayer;
+ layers.push(layer);
+ nextLayer = [];
+ for (const node of layer) {
+ for (const child of node.children) {
+ nextLayer.push(child);
+ }
+ }
+ }
+ return layers.map((layer) => emitTreeLayer(layer, colMap));
+}
+
+function parseFunctionRanges(text, offsetMap) {
+ const result = [];
+ for (const line of text.split("\n")) {
+ for (const range of parseTreeLayer(line, offsetMap)) {
+ result.push(range);
+ }
+ }
+ result.sort(compareRangeCovs);
+ return result;
+}
+
+/**
+ *
+ * @param layer Sorted list of disjoint trees.
+ * @param colMap
+ */
+function emitTreeLayer(layer, colMap) {
+ const line = [];
+ let curIdx = 0;
+ for (const { start, end, count } of layer) {
+ const startIdx = colMap.get(start);
+ const endIdx = colMap.get(end);
+ if (startIdx > curIdx) {
+ line.push(" ".repeat(startIdx - curIdx));
+ }
+ line.push(emitRange(count, endIdx - startIdx));
+ curIdx = endIdx;
+ }
+ return line.join("");
+}
+
+function parseTreeLayer(text, offsetMap) {
+ const result = [];
+ const regex = /\[(\d+)-*\)/gs;
+ while (true) {
+ const match = regex.exec(text);
+ if (match === null) {
+ break;
+ }
+ const startIdx = match.index;
+ const endIdx = startIdx + match[0].length;
+ const count = parseInt(match[1], 10);
+ const startOffset = offsetMap.get(startIdx);
+ const endOffset = offsetMap.get(endIdx);
+ if (startOffset === undefined || endOffset === undefined) {
+ throw new Error(`Invalid offsets for: ${JSON.stringify(text)}`);
+ }
+ result.push({ startOffset, endOffset, count });
+ }
+ return result;
+}
+
+function emitRange(count, len) {
+ const rangeStart = `[${count.toString(10)}`;
+ const rangeEnd = ")";
+ const hyphensLen = len - (rangeStart.length + rangeEnd.length);
+ const hyphens = "-".repeat(Math.max(0, hyphensLen));
+ return `${rangeStart}${hyphens}${rangeEnd}`;
+}
+
+function emitOffsets(colMap) {
+ let line = "";
+ for (const [event, col] of colMap) {
+ if (line.length < col) {
+ line += " ".repeat(col - line.length);
+ }
+ line += event.toString(10);
+ }
+ return line;
+}
+
+function parseOffsets(text) {
+ const result = new Map();
+ const regex = /\d+/gs;
+ while (true) {
+ const match = regex.exec(text);
+ if (match === null) {
+ break;
+ }
+ result.set(match.index, parseInt(match[0], 10));
+ }
+ return result;
+}
+
+module.exports = {
+ emitForest,
+ emitForestLines,
+ parseFunctionRanges,
+ parseOffsets,
+};