Last active
September 16, 2019 13:19
-
-
Save FND/70f7df09b498ebc450d59f1c4b33f9bd to your computer and use it in GitHub Desktop.
JavaScript AST manipulation
This file contains 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
#!/usr/bin/env node | |
let { generate } = require("escodegen"); | |
let jsx = require("acorn-jsx"); | |
let acorn = require("acorn"); | |
let { strictEqual: assertSame } = require("assert"); | |
let JSXParser = acorn.Parser.extend(jsx()); | |
let ast = JSXParser.parse(`<Card title={123}> | |
lorem ipsum | |
{9.87} | |
</Card>`); | |
let root = ast.body[0].expression; | |
validateNode(root, "JSXElement"); // sanity check | |
console.error(root); | |
console.error("\n----\n"); | |
// rewrite node in place -- FIXME: discards `start`, `end` | |
Object.keys(root).forEach(key => { | |
delete root[key]; // XXX: crude? | |
}); | |
Object.assign(root, $array( | |
$invocation("Card", $object({ title: $literal(123) }), | |
$literal("lorem ipsum"), $literal(9.87)), | |
$literal(false), | |
$literal(null) | |
)); | |
let code = generate(ast); | |
console.error(`<pre>\n${code}\n</pre>`); | |
function $invocation(functionName, ...args) { | |
return { | |
type: "CallExpression", | |
callee: { | |
type: "Identifier", | |
name: functionName | |
}, | |
arguments: args | |
}; | |
} | |
function $array(...elements) { | |
return { | |
type: "ArrayExpression", | |
elements | |
}; | |
} | |
function $object(obj) { | |
return { | |
type: "ObjectExpression", | |
properties: Object.entries(obj).map(([key, value]) => ({ | |
type: "Property", | |
kind: "init", // XXX: ? | |
method: false, | |
shorthand: false, | |
computed: false, | |
key: { | |
type: "Identifier", | |
name: key | |
}, | |
value | |
})) | |
}; | |
} | |
function $literal(value) { | |
return { | |
type: "Literal", | |
value, | |
raw: JSON.stringify(value) // XXX: unnecessary? | |
}; | |
} | |
function validateNode({ type }, expected) { | |
assertSame(type, expected, `expected \`${expected}\`, got \`${type}\``); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment