Conversation
tomblind
left a comment
There was a problem hiding this comment.
- Need to make sure other classes don't extend LuaTables
- Need to make sure non-declared classes don't use this as it results in unexpected behavior
Also made the |
|
One more issue I see is explicit constructors. I can declare a constructor for the class, but it's basically ignored. We should throw an error or do something with the arguments. Also, it would be good to have tests for the directive when used on an interface instead of a class. As for assigning length, we now support that for array types with a lib function |
|
Now if a LuaTable is constructed with arguments the transpiler will throw an error saying no parameters are allowed. I chose not to use |
tomblind
left a comment
There was a problem hiding this comment.
This is looking good - but I thought of one more edge-case 😄 We should probably dis-allow using instanceof on @luaTable objects since it will give incorrect results.
Perryvw
left a comment
There was a problem hiding this comment.
Missing functional test(s) for table get/set.
src/LuaTransformer.ts
Outdated
| "One parameter is required for get() on a '@LuaTable' object." | ||
| ); | ||
| } | ||
| if (isWithinExpressionStatement) { |
There was a problem hiding this comment.
I don't think I understand the reasoning here. If you have a table.get(abc) statement it is transformed to ____ = table.get(abc)? That sounds like asking for all kinds of strange bugs.
There was a problem hiding this comment.
Since table.get(abc) transforms to table[abc] it becomes an invalid expression in Lua. In this case I chose to then assign this to an anonymous variable the same way x; is transformed to local ____ = x;
There was a problem hiding this comment.
This sounds like a more fundamental issue. Table.get(abc) is an expression but you are returning a statement. This is related to my other comment on the function signature, I think it might automatically be resolved if you separate the assignment and expression functions.
There was a problem hiding this comment.
I've separated this logic into three functions atm to keep this logic more consistent. I've grouped the error checking in validateLuaTableCall which takes isWithinExpressionStatement for validation purposes, transformLuaTableExpressionStatement and transformLuaTableExpression.
Would this be something more appropriate?
There was a problem hiding this comment.
Seems okay, these methods should probably be private instead of public though.
src/LuaTransformer.ts
Outdated
| } | ||
|
|
||
| // LuaTable classes must be declared | ||
| if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isDeclared(statement)) { |
There was a problem hiding this comment.
Class may considered declared because of it's context
| if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isDeclared(statement)) { | |
| if (decorators.has(DecoratorKind.LuaTable) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Ambient) === 0) { |
There was a problem hiding this comment.
Not sure how to test this but good pickup
|
|
||
| switch (methodName) { | ||
| case "get": | ||
| if (expression.arguments.length !== 1) { |
There was a problem hiding this comment.
It also should check that it's argument isn't a SpreadElement
src/LuaTransformer.ts
Outdated
| if (expression.arguments.length !== 1) { | ||
| throw TSTLErrors.ForbiddenLuaTableUseException( | ||
| expression, | ||
| "One parameter is required for get() on a '@LuaTable' object." |
There was a problem hiding this comment.
| "One parameter is required for get() on a '@LuaTable' object." | |
| "One parameter is required for get() on a '@luaTable' object." |
src/LuaTransformer.ts
Outdated
| if (params.length !== 2) { | ||
| throw TSTLErrors.ForbiddenLuaTableUseException( | ||
| expression, | ||
| "Two parameters are required for set() on a '@LuaTable' object." |
There was a problem hiding this comment.
| "Two parameters are required for set() on a '@LuaTable' object." | |
| "Two parameters are required for set() on a '@luaTable' object." |
src/TSTLErrors.ts
Outdated
| new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); | ||
|
|
||
| public static ForbiddenLuaTableSetExpression = (node: ts.Node) => new TranspileError( | ||
| `A '@LuaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, |
There was a problem hiding this comment.
| `A '@LuaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, | |
| `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, |
For #346
@LuaTablecan be used to mark a Map-like object to transpile down to a simple Lua table.get,setandlengthare the only properties the transpiler pays special attention to. Other properties are treated the same as any other property.I did make a decision to disallow
tbl.set(...)to be used in place of an expression since it never returns a value and transpiles to an ExpressionStatement, not an Expression.This could help with reducing the amount of Lua outputted through its use in LuaLibs and other source code.