Conversation
src/LuaTransformer.ts
Outdated
| ); | ||
| } | ||
| if (!isWithinExpressionStatement) { | ||
| if (expression.parent.kind !== ts.SyntaxKind.ExpressionStatement) { |
There was a problem hiding this comment.
That won't work if it's gone through transformExpressionStatement as an expression
There was a problem hiding this comment.
Seems like that would cause a bug but I can't seem to create some code to break this. What kind of code would do you think would break this?
There was a problem hiding this comment.
Just like above, anything that calls transformExpressionStatement directly with an expression
There was a problem hiding this comment.
It looks it is working as expected. It doesn't break when it goes through transformExpressionStatement as an Expression and will throw the Exception appropriately
/** @LuaTable */
declare class LuaTable<K extends {} = {}, V = any> {
readonly length: number;
set(key: K, value: V): number;
get(key: K): V;
}
let y;
let t = new LuaTable();
for (let x = 0; x < 10; t.set("x", 4)) {} // ❌
for (let x = 0; x < 10; x = t.set("x", 4)) {} // ❌
let x = 4 + (y = t.set('', 2)); // ❌
let xx = 4 + t.set('', 2); // ❌
let xxx = t.set('', 2); // ❌
let y = 4 + (y = t.get('')); // ✔
let yy = 4 + t.get(''); // ✔
let yyy = t.get(''); // ✔transformExpressionStatement is only called with an ExpressionStatement from transformStatement and this would be the only case where luaTable.set would be allowed
There was a problem hiding this comment.
It shouldn't throw in these cases. The whole point of passing an expression to transformExpressionStatement is to assume that this expression is used in statement context, even if it's not a part of ExpressionStatement.
src/LuaTransformer.ts
Outdated
| protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.Expression { | ||
| switch (node.name.text) { | ||
| case "set": | ||
| return this.transformExpression(node.expression); |
There was a problem hiding this comment.
Okay, took me some time to understand how it works and I don't like how transformation flows there. In general, property access isn't equivalent to it's root node, so returning it there isn't correct.
Maybe something like const [luaTable, methodName] = this.parseLuaTableExpression(expression.expression);?
src/LuaTransformer.ts
Outdated
|
|
||
| if (decorators.has(DecoratorKind.LuaTable)) { | ||
| return this.transformLuaTableProperty(expression); | ||
| const [luaTable] = this.parseLuaTableExpression(expression); |
There was a problem hiding this comment.
That's not what I meant. table.get shouldn't be transformed just to table, because these aren't interchangeable in isolation. transformLuaTableProperty should allow only length property.
What I meant is that getLuaTablePropertyName can be renamed to parseLuaTableExpression and would split lua table reference and it's method name.
There was a problem hiding this comment.
Thanks for the clarification, looks like it neatened up nicely
This reverts commit cd5324c.
Closes #699
Also added a rule preventing LuaTables from being accessed via ElementAccessExpressions.
/** @LuaTable */ declare class LuaTable<K extends {} = {}, V = any> { readonly length: number; set(key: K, value: V): void; get(key: K): V; } const k = "k" const t = { data: new LuaTable() } + const v = t.data.get(k) // --> local v = t.data[k] + t.data.set(k,v) // --> t.data[k] = v + const v2 = t.data.get(k).x; // --> local v2 = t.data[k].x - const v3 = t.data["get"](k) - t.data["set"](k, v)Removed a lot of casting to track down the bug.