137 lines
16 KiB
JavaScript
137 lines
16 KiB
JavaScript
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
const compare_1 = require("./compare");
|
||
|
function emitForest(trees) {
|
||
|
return emitForestLines(trees).join("\n");
|
||
|
}
|
||
|
exports.emitForest = emitForest;
|
||
|
function emitForestLines(trees) {
|
||
|
const colMap = getColMap(trees);
|
||
|
const header = emitOffsets(colMap);
|
||
|
return [header, ...trees.map(tree => emitTree(tree, colMap).join("\n"))];
|
||
|
}
|
||
|
exports.emitForestLines = emitForestLines;
|
||
|
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(compare_1.compareRangeCovs);
|
||
|
return result;
|
||
|
}
|
||
|
exports.parseFunctionRanges = parseFunctionRanges;
|
||
|
/**
|
||
|
*
|
||
|
* @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;
|
||
|
}
|
||
|
exports.parseOffsets = parseOffsets;
|
||
|
|
||
|
//# sourceMappingURL=data:application/json;charset=utf8;base64,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
|