Skip to content

fix: debug.traceback of loadstring get unknown file #1259#1260

Merged
Perryvw merged 4 commits intoTypeScriptToLua:masterfrom
pilaoda:master
Apr 24, 2022
Merged

fix: debug.traceback of loadstring get unknown file #1259#1260
Perryvw merged 4 commits intoTypeScriptToLua:masterfrom
pilaoda:master

Conversation

@pilaoda
Copy link
Copy Markdown
Contributor

@pilaoda pilaoda commented Apr 17, 2022

Assume the chunkname is the lua path, and replace the traceback substring [string "xx/xx.lua"]:22 to xx/xx.ts:10

Copy link
Copy Markdown
Member

@Perryvw Perryvw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks alright, could you see if you can add a test that fails without your fix and fix the linter errors by running npm run fix:prettier ?

@pilaoda pilaoda requested a review from Perryvw April 19, 2022 09:50
@Perryvw
Copy link
Copy Markdown
Member

Perryvw commented Apr 20, 2022

Can you add a test that would fail without your changes, but passes on your branch? Maybe something throwing an error in loadstring like your issue mentions. Add it here: https://github.com/TypeScriptToLua/TypeScriptToLua/blob/master/test/unit/printer/sourcemaps.spec.ts#L286

@pilaoda
Copy link
Copy Markdown
Contributor Author

pilaoda commented Apr 22, 2022

Can you add a test that would fail without your changes, but passes on your branch? Maybe something throwing an error in loadstring like your issue mentions. Add it here: https://github.com/TypeScriptToLua/TypeScriptToLua/blob/master/test/unit/printer/sourcemaps.spec.ts#L286

This test is really complicated. I tried my best.

Comment on lines +331 to +354
test("loadstring sourceMapTraceback gives traceback", () => {
const strCodeBuilder = util.testModule`
function bar() {
const trace = (debug.traceback as (this: void)=>string)();
return trace;
}
return bar();
`.setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 });

const strCode = strCodeBuilder.getMainLuaCodeChunk();
const file = `
const luaCode: string = \`${strCode}\`;
return (loadstring as (this: void, string: string, chunkname?: string) => LuaMultiReturn<[() => any] | [undefined, string]>)
(luaCode, "foo.lua")()
`;
const builder = util.testModule`
return (require as (this: void, modname: string) => any)("foo");
`
.addExtraFile("foo.ts", file)
.setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 });

const traceback = builder.getLuaExecutionResult();
expect(traceback).toContain("foo.ts");
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks way too complicated, couldn't you just do something like:

    const builder = util.testFunction`
        return loadstring(
            "return debug.traceback();",
            "foo.lua"
        )();
    `
        .setTsHeader("declare function loadstring(this: void, str: string, chunkName: string): () => unknown;")
        .setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 });

    const traceback = builder.getLuaExecutionResult();
    expect(traceback).toContain("foo.ts");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks way too complicated, couldn't you just do something like:

    const builder = util.testFunction`
        return loadstring(
            "return debug.traceback();",
            "foo.lua"
        )();
    `
        .setTsHeader("declare function loadstring(this: void, str: string, chunkName: string): () => unknown;")
        .setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 });

    const traceback = builder.getLuaExecutionResult();
    expect(traceback).toContain("foo.ts");

This is intentional.
The compiled lua code and sourcemap info should be passed into the loadstring together , otherelse the foo.lua could not be mapped back to foo.ts .

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I played around with it a bit, a much nicer test seems to be:

const loadStrCode = transpileString(
        `function bar() {
            const trace = (debug.traceback as (this: void)=>string)();
            return trace;
        }
        return bar();`,
        { sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 }
    ).file?.lua;

    const builder = util.testModule`
        const luaCode = \`${loadStrCode}\`;
        return loadstring(luaCode, "foo.lua")();
    `
        .setTsHeader("declare function loadstring(this: void, string: string, chunkname: string): () => unknown")
        .setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 });

    const traceback = builder.getLuaExecutionResult();
    expect(traceback).toContain("foo.ts");

Seems to work and is much neater.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. I will commit with your nicer test.

@Perryvw Perryvw merged commit 080163a into TypeScriptToLua:master Apr 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants