X Tutup
Skip to content

Hoisting switch fix#1125

Merged
Perryvw merged 7 commits intoTypeScriptToLua:masterfrom
tomblind:hoisting-switch-fix
Sep 11, 2021
Merged

Hoisting switch fix#1125
Perryvw merged 7 commits intoTypeScriptToLua:masterfrom
tomblind:hoisting-switch-fix

Conversation

@tomblind
Copy link
Collaborator

@tomblind tomblind commented Sep 6, 2021

fixes #1099

To fix hoisting in switch statements, I've added separateHoistedStatements as an intermediate step to performHoisting. This keeps the results separate, which transformSwitchStatement uses directly so it can properly order statements after all clauses are transformed.

Previously, switch cases had some custom code to handle hoisting all locals to the top. I've refactored this to use the standard hoisting code path and just force-hoist everything that is immediately in a switch's scope.

Additionally, there was some very hard to follow 'magic' which handled function hoisting so that it could be output as local function foo() in some cases and local foo; function foo() in others when needed. This was incredibly hard to follow in the codebase, so I've changed it to always use the later form which works in all cases and keeps the implementation a bit more straightforward.

@tomblind tomblind requested review from Perryvw and lolleko September 6, 2021 14:48
Copy link
Contributor

@thejustinwalsh thejustinwalsh left a comment

Choose a reason for hiding this comment

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

I think this is covered by other tests, but passes with expected results. LGTM!

let x = 1;
let y = 2;
let result = [];
switch (x) {
    case 1: {
        let y = 100;
        result.push(y); 
    }
    case 2: {
        let y = 500;
        result.push(y);
    }
    case 3: {
        y = y + 50;
        result.push(y);
    } 
}
return result

scope: Scope,
statements: lua.Statement[]
): lua.Statement[] {
function hoistVariableDeclarations(context: TransformationContext, scope: Scope, statements: lua.Statement[]) {
Copy link
Member

Choose a reason for hiding this comment

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

Think I would prefer if you explicitly declared the return type of these hoist* functions for clarity - I guess it's just HoistingResult?

// Otherwise, we need to generate a set of if statements to emulate the switch.
let statements: lua.Statement[] = [];
const statements: lua.Statement[] = [];
const prefixStatements: lua.Statement[] = [];
Copy link
Member

Choose a reason for hiding this comment

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

Think it might be clearer if you just named this hoistedStatements? I think to avoid naming conflicts with your destructuring assignments is to just not destructure, I don't think that is really making things clearer when it's split over multiple lines like this anyway.

@tomblind tomblind requested a review from Perryvw September 11, 2021 13:13
@Perryvw Perryvw merged commit 73a4ed0 into TypeScriptToLua:master Sep 11, 2021
sanikoyes pushed a commit to sanikoyes/TypeScriptToLua that referenced this pull request Sep 24, 2021
* fixes and refactors for hoisting to fix switch statements and make logic more clear

* applied hoisting fix to new switch implementation
also refactored a few things for clarity and added tests

* fixed issues with hoisting from default clause

* added snapshots for a couple tests and a comment

* fixed edge case with hoisting in a solo default clause

* addressing review feedback

Co-authored-by: Tom <tomblind@users.noreply.github.com>
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.

Crash when hoisting inside a switch statement

3 participants

X Tutup