如何将 TemplateLiteral AST 节点转换回模板字符串源代码?

How to convert a TemplateLiteral AST node back into template string source code?

所以我正在研究 "normalizing" a JS AST in certain ways to make transpilation easier into a particular target language. So I am having to learn the inner details of the AST. Then for testing, I am converting it back into JS source code, using print functions。到目前为止,我几乎处理了所有案例,但 TemplateLiteral 似乎是一个奇怪的结构。

例如,您有这个模板字符串:

const str = 'const b83 = `foo${a100} bar ${b82}`'

str 解析为 AST,你会得到这个结构:

{
  "type": "TemplateLiteral",
  "start": 2692,
  "end": 2715,
  "expressions": [
    {
      "type": "Identifier",
      "start": 2698,
      "end": 2702,
      "name": "a100"
    },
    {
      "type": "Identifier",
      "start": 2710,
      "end": 2713,
      "name": "b82"
    }
  ],
  "quasis": [
    {
      "type": "TemplateElement",
      "start": 2693,
      "end": 2696,
      "value": {
        "raw": "foo",
        "cooked": "foo"
      },
      "tail": false
    },
    {
      "type": "TemplateElement",
      "start": 2703,
      "end": 2708,
      "value": {
        "raw": " bar ",
        "cooked": " bar "
      },
      "tail": false
    },
    {
      "type": "TemplateElement",
      "start": 2714,
      "end": 2714,
      "value": {
        "raw": "",
        "cooked": ""
      },
      "tail": true
    }
  ]
}

注意,“expressions”和“quasis”不是交错排列的,它们是分开排列的。我如何返回并以正确的顺序正确放置它们以重新生成模板字符串源代码?假设这个 AST 节点可能是一个更大的 AST 的一部分,并且树可能被重写,所以您使用的关于开始和结束文本位置的任何信息仅从相对而非绝对的角度有用。我只是不太确定阅读开头和结尾以重新交错表达式和拟态的最佳方式。

您将永远拥有 quasis.length == expressions.length+1。你只要取第一个准,然后第一个表达式,然后下一个准,再下一个表达式,以此类推,直到最后一个准。