创建 AST 节点写法示例

2020-04-02 12:01:09 浏览数 (1)

AST (Abstract Syntax Tree(抽象语法树)) 是源代码语法结构的一种抽象表示。不了解 AST 的,可以看这篇文章。

创建 AST 节点是转换AST节点时的常见操作。本文用 @babel/types 来创建 AST节点。@babel/types 是根据 babel 的 AST 规范来创建 AST。规范说明见这里。

下面,我们来具体看代码。代码中的 trequire('@babel/types')。完整代码见这里。

创建数字

代码语言:javascript复制
t.numericLiteral(1)

输出:

代码语言:javascript复制
1

创建字符串

代码语言:javascript复制
t.stringLiteral('a str')

输出:

代码语言:javascript复制
"a str"

创建布尔值

代码语言:javascript复制
t.booleanLiteral(true)
t.booleanLiteral(false)

输出:

代码语言:javascript复制
true
false

创建null

代码语言:javascript复制
t.nullLiteral()

输出:

代码语言:javascript复制
null

创建对象

代码语言:javascript复制
const nameKey = 
  t.objectProperty(
    t.identifier('name'), 
    t.stringLiteral('Joel')
  )
const agetKey = 
  t.objectProperty(
    t.identifier('age'),
    t.numericLiteral(18)
  )
t.objectExpression([nameKey, agetKey])

输出:

代码语言:javascript复制
{
  name: "Joel",
  age: 18
}

创建获取对象的属性

代码语言:javascript复制
t.memberExpression(
  t.identifier('obj'),
  t.identifier('name')
)

t.memberExpression(
  t.identifier('obj'),
  t.identifier('name'),
  true
)

输出:

代码语言:javascript复制
obj.name
obj[name]

创建数组

代码语言:javascript复制
const item1 = t.numericLiteral(1)
const item2 = t.numericLiteral(2)
t.arrayExpression([item1, item2])

输出:

代码语言:javascript复制
[1, 2]

创建获取数组的内容

代码语言:javascript复制
t.memberExpression(
  t.identifier('arr'),
  t.numericLiteral(1),
  true
)

输出:

代码语言:javascript复制
arr[1]

创建二元表达式

代码语言:javascript复制
t.binaryExpression(
  ' ', // 操作符。 还支持:==, ===, != 等
  item1, // 左操作数
  item2
)

输出:

代码语言:javascript复制
1   2

创建三元表达式

代码语言:javascript复制
t.conditionalExpression(
  t.binaryExpression(
    '>',
    t.numericLiteral(4),
    t.numericLiteral(3)
  ),
  t.numericLiteral(4),
  t.numericLiteral(3)
)

输出:

代码语言:javascript复制
4 > 3 ? 4 : 3

创建逻辑表达式

代码语言:javascript复制
t.logicalExpression(
  '||',
  t.identifier('num'),
  t.numericLiteral(0)
)

t.logicalExpression(
  '&&',
  t.identifier('obj'),
  t.memberExpression(
    t.identifier('obj'),
    t.identifier('name')
  )
)

输出:

代码语言:javascript复制
num || 0
obj && obj.name

创建条件语句if

代码语言:javascript复制
t.binaryExpression(
  '>',
  t.numericLiteral(4),
  t.numericLiteral(3)
),
t.blockStatement(
  [
    t.expressionStatement(
      t.callExpression(
        t.memberExpression(
          t.identifier('console'),
          t.identifier('log')
        ),
        [
          t.booleanLiteral(true)
        ]
      )
    )
  ]
)

输出:

代码语言:javascript复制
if (4 > 3) {
  console.log(true);
}

不知到怎么创建 else if 和 else。

创建for循环

代码语言:javascript复制
t.forStatement(
  t.variableDeclaration(
    'let',
    [
      t.variableDeclarator(
        t.identifier('i'),
        t.numericLiteral(0)
      )
    ]
 ),
 t.binaryExpression(
    '<',
    t.identifier('i'),
    t.numericLiteral(3)
 ),
 t.updateExpression(
   '  ',
   t.identifier('i')
 ),
 t.blockStatement([
   t.emptyStatement()
 ])
)

输出:

代码语言:javascript复制
for (let i = 0; i < 3; i  ) {
  ;
}

创建变量定义

代码语言:javascript复制
t.variableDeclaration(
  'let', // 还支持 const 和 var
  [
    t.variableDeclarator(
      t.identifier('b'), // 变量名
    )
  ]
)

t.variableDeclaration(
  'let', // 还支持 const 和 var
  [
    t.variableDeclarator(
      t.identifier('b'), // 变量名
    )
  ]
)
t.assignmentExpression(
  '=',
  t.identifier('b'),
  t.numericLiteral(1)
)

输出:

代码语言:javascript复制
let a = 1;
let b;
b = 1

创建定义函数

代码语言:javascript复制
t.functionDeclaration(
  t.identifier('add'), // 函数名
  [t.identifier('a'), t.identifier('b')], // 参数
  t.blockStatement([ // 函数体
    t.variableDeclaration(// const sum = a   b
      'const', 
      [
        t.variableDeclarator(
          t.identifier('sum'), // 变量名
          t.binaryExpression(' ', t.identifier('a'), t.identifier('b')) // a   b
        ),
      ]
    ),
    t.returnStatement(t.identifier('sum')) // return sum
  ])
)

输出:

代码语言:javascript复制
function add(a, b) {
  const sum = a   b;
  return sum;
}

创建箭头函数

代码语言:javascript复制
const declarationArrowFun = 
  t.arrowFunctionExpression(
    [t.identifier('a'), t.identifier('b')], // 参数
    t.blockStatement([ // 函数体
      t.variableDeclaration(// const sum = a   b
        'const', 
        [
          t.variableDeclarator(
            t.identifier('sum'), // 变量名
            t.binaryExpression(' ', t.identifier('a'), t.identifier('b')) // a   b
          ),
        ]
      ),
      t.returnStatement(t.identifier('sum')) // return sum
    ])
  )

t.variableDeclaration(
  'let', // 还支持 const 和 var
  [
    t.variableDeclarator(
      t.identifier('add2'), // 变量名
      declarationArrowFun
    )
  ]
 )

输出:

代码语言:javascript复制
function add(a, b) {
  const sum = a   b;
  return sum;
}

let add2 = (a, b) => {
  const sum = a   b;
  return sum;
};

创建函数调用

代码语言:javascript复制
t.callExpression(
  t.identifier('add'),
  [
    t.numericLiteral(1),
    t.numericLiteral(2)
  ]
)

输出:

代码语言:javascript复制
add(1, 2)

0 人点赞