Skip to content

Commit

Permalink
Visualize ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Sep 5, 2023
1 parent 9606dd1 commit 2d29f7c
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 46 deletions.
@@ -1,41 +1,41 @@
(1:0) var t <-- (1:0) var t
^ ^
(1:0-4) var t = <-- (1:0-4) var t =
^^^^ ^^^^

(1:4) var t = x <-- (1:4) var t = f
^ ^
(1:4-5) var t = x <-- (1:4-5) var t = f
^ ^

(1:5) ar t = x <-- (1:5) ar t = fu
^ ^
(1:5-8) ar t = x => <-- (1:5-8) ar t = func
^^^ ^^^

(1:8) t = x => <-- (1:8) t = funct
^ ^
(1:8-8) t = x => <-- (1:8-17) t = function t(x)
>< ^^^^^^^^^

(1:4) var t = x <-- (1:17) ion t(x)
^ ^
(1:4-5) var t = x <-- (1:17-18) ion t(x)
^ ^

(1:5) ar t = x <-- (1:18) on t(x) {
^ ^
(1:5-8) ar t = x => <-- (1:18-19) on t(x) {
^^^ ^

(1:8) t = x => <-- (1:19) n t(x) {
^ ^
(1:8-9) t = x => <-- (1:19-20) n t(x) {
^ ^

(1:9) = x => x <-- (1:20) t(x) {
^ ^
(1:9-13) = x => x * <-- (1:20-23) t(x) {
^^^^ ^^^

(1:9) = x => x <-- (2:2) retur
^ ^
(1:9-13) = x => x * <-- (2:2-9) return x *
^^^^ ^^^^^^^

(1:13) => x * x <-- (2:9) urn x * x
^ ^
(1:13-14) => x * x <-- (2:9-10) urn x * x
^ ^

(1:14) => x * x; <-- (2:10) rn x * x;
^ ^
(1:14-17) => x * x; <-- (2:10-13) rn x * x;
^^^ ^^^

(1:17) x * x; <-- (2:13) x * x;
^ ^
(1:17-18) x * x; <-- (2:13-14) x * x;
^ ^

(1:18) * x; <-- (2:14) * x;
^ ^
(1:18-19) * x; <-- (2:14-15) * x;
^ ^

(1:18) * x; <-- (3:0) };
^ ^
(1:18-19) * x; <-- (3:0-2) };
^ ^^
@@ -1,15 +1,31 @@
import { TraceMap, eachMapping } from "@jridgewell/trace-mapping";
import {
TraceMap,
eachMapping,
type EachMapping,
} from "@jridgewell/trace-mapping";

const CONTEXT_SIZE = 4;
const MAX_LOC_SIZE = 10;
const LOC_SIZE = 10;
const CONTENT_SIZE = 15;

function simpleCodeFrameRange(
lines: string[],
line: number,
colStart: number,
colEnd: number,
) {
colEnd = Math.min(colEnd, lines[line - 1].length);

const start = Math.max(colStart - CONTEXT_SIZE, 0);
const end = Math.min(colEnd + CONTEXT_SIZE, lines[line - 1].length);

const markerSize = colEnd - colStart;
const marker = markerSize === 0 ? "><" : " " + "^".repeat(markerSize);
const markerPadding = colStart - start - 1;

function simpleCodeFrame(lines: string[], line: number, col: number) {
const start = Math.max(col - CONTEXT_SIZE, 0);
const end = Math.min(col + CONTEXT_SIZE + 1, lines[line - 1].length);
const marker = col - start;
const code = lines[line - 1].slice(start, end);
const loc = `(${line}:${col}) `.padStart(MAX_LOC_SIZE, " ");
return loc + code + "\n" + " ".repeat(marker + loc.length) + "^";
const loc = `(${line}:${colStart}-${colEnd}) `.padStart(LOC_SIZE, " ");
return loc + code + "\n" + " ".repeat(markerPadding + loc.length) + marker;
}

function joinMultiline(left: string, right: string, leftLen?: number) {
Expand All @@ -33,24 +49,89 @@ export default function visualize(input: string, output: string, map: any) {
const inputLines = input.split("\n");
const outputLines = output.split("\n");

const res: string[] = [];
type Pos = { line: number; column: number };
type Range = { from: Pos; to: Pos };
const ranges: Array<{
original: Range;
generated: Range;
name: string | null;
}> = [];
let prev: EachMapping = null;
eachMapping(new TraceMap(map), mapping => {
const input = simpleCodeFrame(
if (prev === null) {
prev = mapping;
return;
}
const original = {
from: { line: prev.originalLine, column: prev.originalColumn },
to: { line: mapping.originalLine, column: mapping.originalColumn },
};
const generated = {
from: { line: prev.generatedLine, column: prev.generatedColumn },
to: { line: mapping.generatedLine, column: mapping.generatedColumn },
};
if (original.from.line !== original.to.line) {
original.to.line = original.from.line;
original.to.column = Infinity;
} else if (original.to.column < original.from.column) {
original.to.column = original.from.column;
}
if (generated.from.line !== generated.to.line) {
generated.to.line = generated.from.line;
generated.to.column = Infinity;
} else if (generated.to.column < generated.from.column) {
generated.to.column = generated.from.column;
}
ranges.push({ original, generated, name: prev.name });
prev = mapping;
});
ranges.push({
original: {
from: { line: prev.originalLine, column: prev.originalColumn },
to: { line: prev.originalLine, column: Infinity },
},
generated: {
from: { line: prev.generatedLine, column: prev.generatedColumn },
to: { line: prev.generatedLine, column: Infinity },
},
name: prev.name,
});

// Multiple generated ranges can map to the same original range. The previous
// loop would generate a 0-length original range, so replace its end with the
// end of the following range if possible.
for (let i = ranges.length - 1; i >= 0; i--) {
const { original } = ranges[i];
if (
original.from.column === original.to.column &&
original.to.column < ranges[i + 1].original.to.column &&
ranges[i].name === ranges[i + 1].name
) {
original.to.column = ranges[i + 1].original.to.column;
}
}

const res = ranges.map(({ original, generated }) => {
const input = simpleCodeFrameRange(
inputLines,
mapping.originalLine,
mapping.originalColumn,
original.from.line,
original.from.column,
original.to.column,
);
const output = simpleCodeFrame(
const output = simpleCodeFrameRange(
outputLines,
mapping.generatedLine,
mapping.generatedColumn,
generated.from.line,
generated.from.column,
generated.to.column,
);

res.push(
return joinMultiline(
joinMultiline(
joinMultiline(input, " <-- ", MAX_LOC_SIZE + CONTEXT_SIZE * 2 + 5),
output,
input,
" <-- ",
LOC_SIZE + CONTEXT_SIZE * 2 + CONTENT_SIZE,
),
output,
);
});

Expand Down

0 comments on commit 2d29f7c

Please sign in to comment.