-
-
Notifications
You must be signed in to change notification settings - Fork 185
Expand file tree
/
Copy pathSourceMapTraceBack.ts
More file actions
80 lines (66 loc) · 3.47 KB
/
SourceMapTraceBack.ts
File metadata and controls
80 lines (66 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to
// get some metadata about transpilation.
import { __TS__Match } from "./Match";
interface SourceMap {
[line: string]: number | { line: number; file: string };
}
declare global {
function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number): void;
var __TS__sourcemap: Record<string, SourceMap>;
}
export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void {
globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {};
globalThis.__TS__sourcemap[fileName] = sourceMap;
if (globalThis.__TS__originalTraceback === undefined) {
const originalTraceback = debug.traceback;
globalThis.__TS__originalTraceback = originalTraceback as typeof __TS__originalTraceback;
debug.traceback = ((thread?: LuaThread, message?: string, level?: number) => {
let trace: string;
if (thread === undefined && message === undefined && level === undefined) {
trace = originalTraceback();
} else if (_VERSION.includes("Lua 5.0")) {
trace = originalTraceback(`[Level ${level}] ${message}`);
} else {
// @ts-ignore Fails when compiled with Lua 5.0 types
trace = originalTraceback(thread, message, level);
}
if (typeof trace !== "string") {
return trace;
}
const replacer = (file: string, srcFile: string, line: string) => {
const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file];
if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) {
const data = fileSourceMap[line];
if (typeof data === "number") {
return `${srcFile}:${data}`;
}
return `${data.file}:${data.line}`;
}
return `${file}:${line}`;
};
// Rewrite stack trace frames from "{PATH}.lua:{LINE}" to "{PATH}.ts:{ORIGINAL_LINE}".
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1665
// Avoid matching anonymous function stack entries like `in function <...>`
// by excluding `<` before the file path.
// TODO: This will still fail for paths containing spaces.
let [result] = string.gsub(trace, "([^%s<]+)%.lua:(%d+)", (file, line) =>
replacer(`${file}.lua`, `${file}.ts`, line)
);
const stringReplacer = (file: string, line: string) => {
const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file];
if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) {
const chunkName = __TS__Match(file, '%[string "([^"]+)"%]')[0];
const [sourceName] = string.gsub(chunkName, ".lua$", ".ts");
const data = fileSourceMap[line];
if (typeof data === "number") {
return `${sourceName}:${data}`;
}
return `${data.file}:${data.line}`;
}
return `${file}:${line}`;
};
[result] = string.gsub(result, '(%[string "[^"]+"%]):(%d+)', (file, line) => stringReplacer(file, line));
return result;
}) as typeof debug.traceback;
}
}