LuaTransformer class now has a number of issues:
- Ability to extend it isn't a plugin system - you can do it only once, you can override things you aren't meant to, we are limited with public/protected/private when designing visitor API
- If you want to extend it, you always have to use it with API, so you also have to re-implement
tstl even when you don't want to change anything there
- 5500 lines is too much
The idea is to make whole transformation be composed of plugins. A plugin is a function that receives context: TranspilerContext and returns an object. Context is an object with some state that may be passed to utility functions.
Project structure:
- src/transformers
- utils
- index.ts
- type-checks.ts
- lua-ast-utils.ts
- ...
- class.ts
- call.ts
- try.ts
- ...
Example transformer:
import { escapeString, isTupleReturnCall, isArrayType, createUnpackCall, transformLuaLibFunction } from "./utils";
export const someTransformer = (context: TranspilerContext): TranspilerPlugin => ({
visitors: {
[ts.SyntaxKind.StringLiteral]: node => escapeString(node.text),
[ts.SyntaxKind.SpreadElement](node) {
const innerExpression = context.transformExpression(node.expression);
if (isTupleReturnCall(context, node.expression)) {
return innerExpression;
}
const type = context.checker.getTypeAtLocation(node.expression);
if (isArrayType(context, type)) {
return createUnpackCall(innerExpression, node);
}
return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression);
},
},
});
LuaTransformerclass now has a number of issues:tstleven when you don't want to change anything thereThe idea is to make whole transformation be composed of plugins. A plugin is a function that receives
context: TranspilerContextand returns an object. Context is an object with some state that may be passed to utility functions.Project structure:
Example transformer: