Skip to content

Handling return from try and catch#642

Merged
tomblind merged 3 commits intomasterfrom
bugfix/try-return
Jul 4, 2019
Merged

Handling return from try and catch#642
tomblind merged 3 commits intomasterfrom
bugfix/try-return

Conversation

@tomblind
Copy link
Copy Markdown
Collaborator

fixes #252

To support proper returning from try/catch (while still executing finally), a true literal is prepended to returned values. This is checked after finally is executed and the return value is forwarded on. Note that the catch block will always be wrapped in an IIFE in this case.

function foobar() {
    try {
        return mayThrow();
    } catch (err) {
        return "error thrown: " + err;
    } finally {
        console.log("finally");
    }
}

=>

function foobar(self)
    do
        local ____TS_try, err, ____TS_returnValue = pcall(function()
            return true, mayThrow()
        end)
        if not ____TS_try then
            err, ____TS_returnValue = (function()
                return true, "error thrown: " .. tostring(err)
            end)()
        end
        do
            print("finally")
        end
        if err then
            return ____TS_returnValue
        end
    end
end

In the case of @tupleReturn functions, the return value will be wrapped and later unpacked when forwarded.

/** @tupleReturn */
function foobar() {
    try {
        return [mayThrow(), mayThrow()];
    } catch (err) {
        return ["error thrown", err];
    } finally {
        console.log("finally");
    }
}

=>

function foobar(self)
    do
        local ____TS_try, err, ____TS_returnValue = pcall(function()
            return true, ({
                mayThrow(),
                mayThrow(),
            })
        end)
        if not ____TS_try then
            err, ____TS_returnValue = (function()
                return true, ({
                    "error thrown",
                    err,
                })
            end)()
        end
        do
            print("finally")
        end
        if err then
            return unpack(____TS_returnValue)
        end
    end
end

}
}

protected transformScopeBlock(block: ts.Block, scopeType: ScopeType): [tstl.Block, Scope] {
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.

since this functions is only used for try/catch it might be better to name it accordingly, transformScopeBlock sounds a bit generic. Unless there are plans to use this function in more places in the future.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It could be used for other purposes at well. It's really just an alternate form of transformBlock which returns the scope as well. I could just modify that function and use it everywhere.

`;
expect(util.transpileAndExecute(code)).toBe("finally evaluated");
});

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.

tuple return from finally?

@tomblind tomblind merged commit 85050fd into master Jul 4, 2019
@tomblind tomblind deleted the bugfix/try-return branch July 4, 2019 21:08
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.

Returning inside try block fails

3 participants