Conversation
|
This is looking pretty solid. I have got something picky that is kinda 🤷 Thought about it after LuaTables When declaring things like this an identifier is revealed to TypeScript that doesn't actually exist. This identifier can be used almost everywhere. console.log(luaForRange);
luaForRange.call(null, 0, 0, 0);
let array = [0, luaForRange, 1];
const call = cb => cb();
call(luaForRange);If this is something that is considered a problem I'm thinking a functional solution could be to iterate over all identifiers in each source file. Each identifier in a source file would have their parents' kinds and directives checked to make sure identifiers revealing forRange functions are being used in call expressions on the right hand side of for..of statements. I am not entirely sure how to iterate through every node, but it might look something like the below code: // TSHelper
validateNode(checker: ts.Checker, node: Node) {
if (node.kind === ts.SyntaxKind.Identifier) {
const type = checker.getTypeAtLocation(node);
if (this.getCustomDecorators(type).has(DecoratorKind.ForRange)) {
// further checks for a valid ForRange use
}
}
ts.forEachChild(node, this.validateNode);
}
// LuaTransformer
transformSourceFile(node: ts.SourceFile) {
...
ts.forEachChild(node, tsHelper.validateNode.bind(tsHelper, this.checker));
} |
|
While all directives have situations where they can be broken (they fall into the "use at your own risk" category), you're right that these cases can be caught easily enough. We actively try to avoid "scanning" the AST, but I was able to add a general check in |
This new directive is used to create lua numeric for loops by using an ambient function declaration which can be used in TS for...of loops.
=>
An error will be thrown if the function: