Refine Trace to be able to output graphviz-compatible data.
[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 var current: Trace = null;
9
10 var traces: Trace[] = [];
11
12 export type Edge = [string, string];
13
14 export default class Trace {
15 private _edges: { [key: string]: Edge } = {};
16 private _stack: string[] = [];
17 private _name: string;
18
19 constructor(line: Line<any>) {
20 this._name = this._formatLine(line);
21
22 if (current === null)
23 current = this;
24
25 if (current._stack.length != 0) {
26 current._addEdge([ current._previousEdge(), this._name ]);
27 }
28
29 current._stack.push(this._name);
30 }
31
32 static add(id: string) {
33 if (current === null)
34 return;
35 current._addEdge([ current._previousEdge(), id ]);
36 }
37
38 end() {
39 current._stack.pop();
40 if (current === this) {
41 current = null;
42 traces.push(this);
43 }
44 }
45
46 get traceList(): readonly Edge[] {
47 return Object.values(this._edges);
48 }
49
50 private _addEdge(e: Edge) {
51 this._edges[`${e[0]}|${e[1]}`] = e;
52 }
53
54 private _previousEdge(): string {
55 return this._stack[this._stack.length - 1];
56 }
57
58 private _formatLine(line: Line<any>): string {
59 const description = line.description ? ` (${line.description})` : '';
60 if (line.form === undefined)
61 return `${line.constructor.name}${description}`;
62 return `${line.form.name}-${line.id}${description}`;
63 }
64 };
65
66 export function getLastTraceList(): readonly Edge[] {
67 if (traces.length == 0)
68 return null;
69 return traces[traces.length - 1].traceList;
70 }