我正在开发一个 SWC Rust WASM 插件来转换 JavaScript。
总体SWC及其API设计良好。然而,目前我很难将
TaggedTemplateExpression
转换为 CallExpression
,如下例所示:
console.log`Hello, ${name}!`;
至:
console.log("Hello, ", name, "!");
在 Babel 中,这种转变相对简单。下面是它的外观示例:
const babel = require("@babel/core");
function transform({ types: t }) {
return {
visitor: {
TaggedTemplateExpression(path) {
const { tag, quasi } = path.node;
if (
t.isMemberExpression(tag) &&
t.isIdentifier(tag.object, { name: "console" }) &&
t.isIdentifier(tag.property, { name: "log" })
) {
let args = [];
quasi.quasis.forEach((element, index) => {
args.push(t.stringLiteral(element.value.raw));
if (index < quasi.expressions.length) {
args.push(quasi.expressions[index]);
}
});
path.replaceWith(
t.callExpression(
t.memberExpression(
t.identifier("console"),
t.identifier("log")
),
args
)
);
}
},
},
};
}
我找到了 SWC CheatSheet 的更改 AST 类型部分,但我仍然不知道如何正确转换它:
use swc_core::ecma::{
ast::*,
visit::{VisitMut, VisitMutWith},
};
struct TemplateToCallTransform;
impl VisitMut for TemplateToCallTransform {
fn visit_mut_tagged_tpl(&mut self, n: &mut TaggedTpl) {=
// How do I replace the current node with the new CallExpr?
}
}
SWC 作者在这里(再次)。
您需要从
fn visit_mut_expr(&mut self, e: &mut Expr)
处处理它。
TaggedTpl
和CallExpr
都属于ECMAScript中的表达式,因此您可以从那里处理它。
use swc_core::ecma::{
ast::*,
visit::{VisitMut, VisitMutWith},
};
struct TemplateToCallTransform;
impl VisitMut for TemplateToCallTransform {
fn visit_mut_expr(&mut self, e: &mut Expr) {
// You may skip this, depending on the requirements.
e.visit_mut_children_with(self);
match e {
Expr::TaggedTpl(n) => {
*e = Expr::Call(CallExpr {
// ...fields
});
}
_ => {}
}
}
}