Skip to content

Instantly share code, notes, and snippets.

@phenomnomnominal
Created May 30, 2019 08:16
Show Gist options
  • Save phenomnomnominal/b720915d884429c09a3d7ee13edbb236 to your computer and use it in GitHub Desktop.
Save phenomnomnominal/b720915d884429c09a3d7ee13edbb236 to your computer and use it in GitHub Desktop.
Fifth version of our transform, which moves the casting calls from the decorator to the getter and setter
// Constants:
// ...
const CASTERS_QUERY = 'CallExpression[expression.name!="Value"], CallExpression[expression.name="Value"] > Identifier[name!="Value"], CallExpression[expression.name="Value"] > ArrayLiteralExpression > Identifier[name!="Value"]';
const CAST_RESULT_EXPRESSION_QUERY = 'ExpressionStatement';
const GETTER_CAST_QUERY = 'Identifier[name="isNotNull"]';
const CAST_CALL_TEMPLATE = tstemplate.compile(`
val = <%= name %>(val, <%= propertyName %>);
`);
export function transformer (source: SourceFile): TransformerFactory<Node> {
// ...
}
export function valueDecoratorToGetterAndSetterFactory (nodes: Array<Node>): TransformerFactory<Node> {
return function (context: TransformationContext): Transformer<Node> {
// ...
function visit (node: Node): Node | Array<Node> {
if (nodes.includes(node)) {
// Create the base structure of the new getter/setter:
// ...
// Re-attach any other decorators:
// ...
// Find caster function names:
const casterNodes = tsquery(node, CASTERS_QUERY);
// Create the CallExpressions for each cast call:
const castCalls = casterNodes.map(casterNode => {
const [call] = tsquery(CAST_CALL_TEMPLATE({
name: casterNode,
propertyName: createLiteral(propertyName),
}), CAST_RESULT_EXPRESSION_QUERY);
return call;
});
const getters = castCalls.filter(call => tsquery(call, GETTER_CAST_QUERY).length);
const setters = castCalls.filter(call => !getters.includes(call));
// Insert the cast calls into the getter and setter bodies:
getter.body.statements.splice(1, 0, ...getters);
setter.body.statements.splice(1, 0, ...setters);
// Return the new AST nodes to replace the old one:
// ...
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment