|
| 1 | +// TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to |
| 2 | +// get some metadata about transpilation. |
| 3 | + |
| 4 | +import { __TS__Match } from "./Match"; |
| 5 | + |
| 6 | +interface SourceMap { |
| 7 | + [line: number]: number | { line: number; file: string }; |
| 8 | +} |
| 9 | + |
| 10 | +declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); |
| 11 | + |
| 12 | +export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { |
| 13 | + globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; |
| 14 | + globalThis.__TS__sourcemap[fileName] = sourceMap; |
| 15 | + |
| 16 | + if (globalThis.__TS__originalTraceback === undefined) { |
| 17 | + const originalTraceback = debug.traceback; |
| 18 | + globalThis.__TS__originalTraceback = originalTraceback; |
| 19 | + debug.traceback = ((thread, message, level) => { |
| 20 | + let trace: string; |
| 21 | + if (thread === undefined && message === undefined && level === undefined) { |
| 22 | + trace = originalTraceback(); |
| 23 | + } else { |
| 24 | + trace = originalTraceback(`[Level ${level}] ${message}`); |
| 25 | + } |
| 26 | + |
| 27 | + if (typeof trace !== "string") { |
| 28 | + return trace; |
| 29 | + } |
| 30 | + |
| 31 | + const replacer = (file: string, srcFile: string, line: string) => { |
| 32 | + const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; |
| 33 | + if (fileSourceMap && fileSourceMap[line]) { |
| 34 | + const data = fileSourceMap[line]; |
| 35 | + if (typeof data === "number") { |
| 36 | + return `${srcFile}:${data}`; |
| 37 | + } |
| 38 | + |
| 39 | + return `${data.file}:${data.line}`; |
| 40 | + } |
| 41 | + |
| 42 | + return `${file}:${line}`; |
| 43 | + }; |
| 44 | + |
| 45 | + let [result] = string.gsub(trace, "(%S+)%.lua:(%d+)", (file, line) => |
| 46 | + replacer(`${file}.lua`, `${file}.ts`, line) |
| 47 | + ); |
| 48 | + |
| 49 | + const stringReplacer = (file: string, line: string) => { |
| 50 | + const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; |
| 51 | + if (fileSourceMap && fileSourceMap[line]) { |
| 52 | + const chunkName = __TS__Match(file, '%[string "([^"]+)"%]')[0]; |
| 53 | + const [sourceName] = string.gsub(chunkName, ".lua$", ".ts"); |
| 54 | + const data = fileSourceMap[line]; |
| 55 | + if (typeof data === "number") { |
| 56 | + return `${sourceName}:${data}`; |
| 57 | + } |
| 58 | + |
| 59 | + return `${data.file}:${data.line}`; |
| 60 | + } |
| 61 | + |
| 62 | + return `${file}:${line}`; |
| 63 | + }; |
| 64 | + [result] = string.gsub(result, '(%[string "[^"]+"%]):(%d+)', (file, line) => stringReplacer(file, line)); |
| 65 | + |
| 66 | + return result; |
| 67 | + }) as typeof debug.traceback; |
| 68 | + } |
| 69 | +} |
0 commit comments