代码之家  ›  专栏  ›  技术社区  ›  jantimon

用SWC Rust插件中的CallExpression替换TaggedTemplateExpression

  •  0
  • jantimon  · 技术社区  · 2 年前

    我正在开发一个SWC Rust WASM插件来转换JavaScript。

    整体SWC及其API设计良好。然而,目前我很难转换 TaggedTemplateExpression CallExpression 就像在这个例子中一样:

    console.log`Hello, ${name}!`;
    

    console.log("Hello, ", name, "!");
    

    在巴贝尔,这种转变将相对简单。以下是它的外观示例:

    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
                )
              );
            }
          },
        },
      };
    }
    

    我发现的“更改AST类型”部分 SWC CheatSheet 但我仍然不知道如何正确转换:

    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?
        }
    }
    
    1 回复  |  直到 2 年前
        1
  •  1
  •   kdy    2 年前

    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
                    });
                }
    
                _ => {}
            }
        }
    }