Skip to content

Fix variable destructuring compatibility issue with lua 5.1#158

Merged
Perryvw merged 7 commits intoTypeScriptToLua:masterfrom
Janne252:master
Jul 28, 2018
Merged

Fix variable destructuring compatibility issue with lua 5.1#158
Perryvw merged 7 commits intoTypeScriptToLua:masterfrom
Janne252:master

Conversation

@Janne252
Copy link
Copy Markdown
Contributor

@Janne252 Janne252 commented Jul 27, 2018

Fixes:

Replaces:

I added tests for luaTarget 5.1, 5.2, 5.3, and JIT. Technically only the tests for 5.1 and 5.2 matter as Transpilers 5.3 and JIT don't override transpileVariableDestructuring, so they might be a bit excessive.

Edit: There seems to be an issue reported by continuous-integration/appveyor/p, that error didn't occur while running npm run test-threaded, only with npm run test. Investigating...

@Janne252
Copy link
Copy Markdown
Contributor Author

Looks like Fengari only implements lua 5.3, which causes an issue when testing 5.1 specific features that have been deprecated in 5.3.

I added with51Backport to executeLua which includes the necessary backport

-- Lua 5.1 unpack was moved to table.unpack in Lua 5.3, make it available as a backport
unpack = table.unpack

However this pollutes the API of executeLua with a new boolean param. Thoughts?

Copy link
Copy Markdown
Member

@lolleko lolleko left a comment

Choose a reason for hiding this comment

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

Looks good to me, I'm fine with having this bool for now.
In the future we might want to use bit flags in executeLua if we encounter more version specific problems.

And about the tests for 5.3 and JIT it might be better to remove them. If we for some reason decide to change the destructuring we only will need to update 2 tests not 4.

@Janne252
Copy link
Copy Markdown
Contributor Author

Implemented the requested changes (removed duplicate tests).

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 good, I left a couple of style- and convention-related comemnts. Once those are resolved this can be merged.

return `bit32.arshift(${lhs},${rhs})`;
}
}
/** @override */
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.

Add a whiteline between methods.

}

// Implemented in 5.1 and overridden in 5.2 (and onwards)
public abstract transpileVariableDestructuring(value: string): string;
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.

By convention we throw a TranspileError here, see transpileContinue in Transpiler.ts.

export class AssignmentDestructuringTests {

private readonly assignmentDestruturingTs = `
declare function myFunc(): [number, string];
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.

Indent line 8 and 9 please.

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.

Almost all test files have issues reported by tslint. I'm using VS Code and the extension seems to also apply the lint to the test files. I think ./tests/**/*.ts should be ignored by tslint?

tslint.json

{
/// ...
    "linterOptions": {
        "exclude": [
            "./test/**/*.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.

Eventually they should adhere to tslint I think, but for now I am treating tslint as "suggestions" for test files (which is why it doesn't fail builds).

Copy link
Copy Markdown
Contributor Author

@Janne252 Janne252 Jul 28, 2018

Choose a reason for hiding this comment

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

Is it okay to disable tslint for ./test for now (as demonstrated above)? I'm using VS Code and it's rather obtrusive to have the test files full of errors. Unless a path's severity can be forced to "suggestion" in tslint.json? I couldn't find a feature like that after a quick search.

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.

As long as you don't push it you can change it however you want :D

test/src/util.ts Outdated
luaStr = minimalTestLib + luaStr;
}

if (with51Backport) {
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.

Can this backport stuff be removed since no 5.1 lua is executed?

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.

When luaTarget is 5.1 and a variable destructuring is performed, e.g.

declare function myFunc(): [number, string];
let [a, b] = myFunc();

It has to rersult in

local a,b=unpack(myFunc())

Because Lua 5.1 doesn't have table.unpack, which is generated by 5.2 and onwards.

The tests that run Lua code rely on Fengari which only implements Lua 5.3 runtime. unpack (that was generated by luaTarget 5.1) is not defined in Lua 5.3 and thus has to be backported in order to be able to test Lua 5.1 code in Lua 5.3 VM.

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.

Which tests are executed in Fengari that are compiled with target 5.1?

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.

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.

Those are only transpiled, not executed.

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.

Hmm those are not transpiled as 5.1 either... Sounds like something is off here, I will investigate.

Copy link
Copy Markdown
Contributor Author

@Janne252 Janne252 Jul 28, 2018

Choose a reason for hiding this comment

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

It's caused by build_lualib.ts, the lualib is transpiled as 5.1. For example the generated map.lua uses unpack call:

function Map.constructor(self,other)
    self.items = {}
    self.size = 0
    if __TS__InstanceOf(other, Map) then
        self.size = other.size
        for _, __forOfValue0 in ipairs(other:entries()) do
        local key,value=unpack(__forOfValue0)
            do
                self.items[key] = value
            end
        end
    else
        if other~=nil then
            self.size = #other
            for _, __forOfValue1 in ipairs(other) do
            local key,value=unpack(__forOfValue1)
                do
                    self.items[key] = value
                end
            end
        end
    end
end

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.

Does changing the lua version to 5.3 in build_lualib.ts fix that? I am fine with you changing that for now so we can get rid of this backport stuff, since that is just treating symptoms instead of the actual cause.

We will have to come up with a better fix later, probably changing the map implementation so it does not use unpack (or any version-sensitive stuff) would be the best answer, but we can do that in a different PR.

Copy link
Copy Markdown
Contributor Author

@Janne252 Janne252 Jul 28, 2018

Choose a reason for hiding this comment

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

If the luaTarget for build_lualib.ts is changed to 5.3, then lualib would not work with Lua 5.1, as it would use table.unpack (at the moment). If we don't want to use backports, the other option is to add a polyfill so that transpiled 5.1 code supports table.unpack, e.g.

if not table.unpack then
    function table.unpack(...)
        return unpack(...)
    end
end

This polyfill should probably be included in the lualib, but ideally it would only be emitted when the project luatarget is set to 5.1, e.g. tstl --luaTarget 5.1

Copy link
Copy Markdown
Member

@Perryvw Perryvw Jul 28, 2018

Choose a reason for hiding this comment

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

I actually just hotfixed unpack out of the map implementation, if you merge master into your branch that should hopefully fix the failing tests.

@Janne252
Copy link
Copy Markdown
Contributor Author

Yep, tests passed without the backport (removed it). Also applied all the requested changes.

@Perryvw Perryvw merged commit bc073bb into TypeScriptToLua:master Jul 28, 2018
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.

3 participants