UNPKG

2 kBJavaScriptView Raw
1import LinesAndColumns from "lines-and-columns";
2
3import {formatTokenType} from "../parser/tokenizer/types";
4
5export default function formatTokens(code, tokens) {
6 if (tokens.length === 0) {
7 return "";
8 }
9
10 const tokenKeys = Object.keys(tokens[0]).filter(
11 (k) => k !== "type" && k !== "value" && k !== "start" && k !== "end" && k !== "loc",
12 );
13 const typeKeys = Object.keys(tokens[0].type).filter((k) => k !== "label" && k !== "keyword");
14
15 const headings = ["Location", "Label", "Raw", ...tokenKeys, ...typeKeys];
16
17 const lines = new LinesAndColumns(code);
18 const rows = [headings, ...tokens.map(getTokenComponents)];
19 const padding = headings.map(() => 0);
20 for (const components of rows) {
21 for (let i = 0; i < components.length; i++) {
22 padding[i] = Math.max(padding[i], components[i].length);
23 }
24 }
25 return rows
26 .map((components) => components.map((component, i) => component.padEnd(padding[i])).join(" "))
27 .join("\n");
28
29 function getTokenComponents(token) {
30 const raw = code.slice(token.start, token.end);
31 return [
32 formatRange(token.start, token.end),
33 formatTokenType(token.type),
34 truncate(String(raw), 14),
35 ...tokenKeys.map((key) => formatValue(token[key], key)),
36 ...typeKeys.map((key) => formatValue(token.type[key], key)),
37 ];
38 }
39
40 // tslint:disable-next-line no-any
41 function formatValue(value, key) {
42 if (value === true) {
43 return key;
44 } else if (value === false || value === null) {
45 return "";
46 } else {
47 return String(value);
48 }
49 }
50
51 function formatRange(start, end) {
52 return `${formatPos(start)}-${formatPos(end)}`;
53 }
54
55 function formatPos(pos) {
56 const location = lines.locationForIndex(pos);
57 if (!location) {
58 return "Unknown";
59 } else {
60 return `${location.line + 1}:${location.column + 1}`;
61 }
62 }
63}
64
65function truncate(s, length) {
66 if (s.length > length) {
67 return `${s.slice(0, length - 3)}...`;
68 } else {
69 return s;
70 }
71}