Created
October 26, 2024 19:41
-
-
Save Jordan-Hall/b0fdeaa5e2215b05e09096189faeb450 to your computer and use it in GitHub Desktop.
Make the functions return state correctly for ivy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as ts from "typescript"; | |
// Input function | |
const sourceCode = ` | |
function example() { | |
let test = 1; | |
let helloWorld; | |
const add = (by) => { | |
test += by; | |
}; | |
function remove(by) { | |
test -= by; | |
} | |
} | |
`; | |
// Transformer function | |
function transformFunctionToReturnGetSetAndMethods(sourceCode: string): string { | |
const sourceFile = ts.createSourceFile( | |
"example.ts", | |
sourceCode, | |
ts.ScriptTarget.Latest, | |
true, | |
ts.ScriptKind.TS | |
); | |
const printer = ts.createPrinter(); | |
const transformer: ts.TransformerFactory<ts.SourceFile> = (context) => { | |
const visit: ts.Visitor = (node) => { | |
// Identify top-level functions only | |
if (ts.isFunctionDeclaration(node) && node.body) { | |
const statements = node.body.statements; | |
const returnProperties: ts.ObjectLiteralElementLike[] = []; | |
statements.forEach((statement) => { | |
if (ts.isVariableStatement(statement)) { | |
statement.declarationList.declarations.forEach((declaration) => { | |
if (ts.isIdentifier(declaration.name)) { | |
const name = declaration.name.getText(); | |
if (declaration?.initializer && ts.isArrowFunction(declaration?.initializer)) { | |
returnProperties.push( | |
ts.factory.createShorthandPropertyAssignment(name) | |
); | |
return | |
} | |
// Create getter for variable | |
const getter = ts.factory.createGetAccessorDeclaration( | |
undefined, // No modifiers | |
name, // Name of the accessor | |
[], // No parameters for getter | |
undefined, // Return type is inferred | |
ts.factory.createBlock([ | |
ts.factory.createReturnStatement( | |
ts.factory.createIdentifier(name) | |
), | |
], true) | |
); | |
// Create setter for variable | |
const setter = ts.factory.createSetAccessorDeclaration( | |
undefined, // No modifiers | |
name, // Name of the accessor | |
[ | |
ts.factory.createParameterDeclaration( | |
undefined, undefined, ts.factory.createIdentifier("value"), undefined, undefined | |
) | |
], | |
ts.factory.createBlock([ | |
ts.factory.createExpressionStatement( | |
ts.factory.createBinaryExpression( | |
ts.factory.createIdentifier(name), | |
ts.SyntaxKind.EqualsToken, | |
ts.factory.createIdentifier("value") | |
) | |
), | |
], true) | |
); | |
returnProperties.push(getter, setter); | |
} | |
}); | |
} else if (ts.isFunctionDeclaration(statement)) { | |
const name = statement.name?.getText(); | |
if (name) { | |
returnProperties.push( | |
ts.factory.createShorthandPropertyAssignment(name) | |
); | |
} | |
} | |
}); | |
// Add return statement at the end of the function | |
const returnStatement = ts.factory.createReturnStatement( | |
ts.factory.createObjectLiteralExpression(returnProperties, true) | |
); | |
const updatedBody = ts.factory.updateBlock(node.body, [ | |
...node.body.statements, | |
returnStatement, | |
]); | |
node = ts.factory.updateFunctionDeclaration( | |
node, | |
node.modifiers, | |
node.asteriskToken, | |
node.name, | |
node.typeParameters, | |
node.parameters, | |
node.type, | |
updatedBody | |
); | |
} | |
return ts.visitEachChild(node, visit, context); | |
}; | |
return (node: ts.SourceFile) => ts.visitNode(node, visit) as ts.SourceFile; | |
}; | |
const result = ts.transform(sourceFile, [transformer]); | |
const transformedSourceFile = result.transformed[0] as ts.SourceFile; | |
const transformedSource = printer.printFile(transformedSourceFile); | |
result.dispose(); | |
return transformedSource; | |
} | |
// Transformed output | |
console.log(transformFunctionToReturnGetSetAndMethods(sourceCode)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment