Use '@' to separate form@line references.
[ustaxlib.git] / src / core / Trace.ts
1 // Copyright 2020 Blue Static <https://www.bluestatic.org>
2 // This program is free software licensed under the GNU General Public License,
3 // version 3.0. The full text of the license can be found in LICENSE.txt.
4 // SPDX-License-Identifier: GPL-3.0-only
5
6 import { Line } from './Line';
7
8 export type Edge = [string, string];
9
10 type Trace = { [key: string]: Edge };
11
12 var stack: string[] = [];
13
14 var current: Trace = null;
15 var previous: Trace = null;
16
17 export function begin(line: Line<any>) {
18 const name = formatLine(line);
19
20 if (current === null)
21 current = {} as Trace;
22
23 if (stack.length != 0)
24 addEdge([ previousEdge(), name ]);
25
26 stack.push(name);
27 }
28
29 export function mark(id: string) {
30 if (current === null)
31 return;
32 addEdge([ previousEdge(), id ]);
33 }
34
35 export function end() {
36 stack.pop();
37 if (stack.length == 0) {
38 reset();
39 }
40 }
41
42 export function reset() {
43 previous = current;
44 current = null;
45 stack = [];
46 }
47
48 export function getLastTraceList(): readonly Edge[] {
49 if (previous === null)
50 return null;
51 return Object.values(previous);
52 }
53
54 function addEdge(e: Edge) {
55 current[`${e[0]}|${e[1]}`] = e;
56 }
57
58 function previousEdge(): string {
59 return stack[stack.length - 1];
60 }
61
62 function formatLine(line: Line<any>): string {
63 const description = line.description ? ` (${line.description})` : '';
64 if (line.form === undefined)
65 return `${line.constructor.name}${description}`;
66 return `${line.form.name}@${line.id}${description}`;
67 }