Skip to content

Commit

Permalink
feat: ast解析箭头函数,暂未实现
Browse files Browse the repository at this point in the history
  • Loading branch information
okbug committed Nov 18, 2021
1 parent fc4edef commit fb7a6df
Show file tree
Hide file tree
Showing 4,292 changed files with 248,205 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
31 changes: 31 additions & 0 deletions learnWebpack/ast-demo/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
let esprima = require('esprima');
let estraverse = require('estraverse');
let escodegen = require('escodegen');

let code = `
function ast() {};
`

// 生成语法树
let res = esprima.parse(code);

// console.log(res)

// 遍历语法树 (DFS)

let indent = 0;
const padding = () => " ".repeat(indent);
estraverse.traverse(res, {
enter(node) {
console.log(padding() + '进入' + node.type);
indent += 2;
},
leave(node) {
indent -= 2;
console.log(padding() + '离开' + node.type);
}
})

// 生成语法树
let target = escodegen.generate(res);
console.log(target)
43 changes: 43 additions & 0 deletions learnWebpack/ast-demo/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const core = require('@babel/core');
const types = require('babel-types');
const plugin = require('babel-plugin-transform-es2015-arrow-functions');

const code = `
const sum = (a, b) => a + b;
`
// babel/core 本身只有 生成、遍历、生成 代码的功能,和上面的三个工具一样
// 它本身不会在代码遍历的时候做一个处理,除了用插件等方法
let target = core.transform(code, {
plugins: [plugin]
})
// console.log(target.code);

// babel插件其实就是一个对象,它有一个 visitor(访问器)

let myPlugin = {
visitor: {
/**
* 函数名称就是在遍历语法树时遇到的类型,意味着给这个类型做转换
* @param {*} path 节点的数据
*/
ArrowFunctionExpression(path) {
path.node.type = 'FunctionExpression';
// 只是添加这个的话 会转成 function (a, b) a + b 普通函数没有隐式返回
// 并且在箭头函数中的this没有办法取到

// 处理this指针
const thisBinding = hoistFunctionEnvironmen(path)
}
}
}
function hoistFunctionEnvironmen(fnPath) {
const thisEventFn = fnPath.findParent(p => {
return p.isFunction() && !p.isArrowFunctionExpression() || p.isProgram()
})
}

let target2 = core.transform(code, {
plugins: [myPlugin]
})

console.log(target2.code)
136 changes: 136 additions & 0 deletions learnWebpack/ast-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
> 相关网站
> https://www.astexplorer.net
> SpiderMonkey (MDN)



## 基本使用
安装依赖

`npm install esprima estraverse escodegen -S`
### 解析语法树

代码:

```js
let esprima = require('esprima');
let estraverse = require('estraverse');
let escodegen = require('escodegen');

let code = `
function ast() {};
`

let res = esprima.parse(code);

console.log(res)
```

运行后的结果:

```js
Script {
type: 'Program',
body: [
FunctionDeclaration {
type: 'FunctionDeclaration',
id: [Identifier],
params: [],
body: [BlockStatement],
generator: false,
expression: false,
async: false
},
EmptyStatement { type: 'EmptyStatement' }
],
sourceType: 'script'
}
```

### 遍历语法树
代码:
```js
// 遍历语法树 (DFS)

let indent = 0;
const padding = () => " ".repeat(indent);
estraverse.traverse(res, {
enter(node) {
console.log(padding() + '进入' + node.type);
indent += 2;
},
leave(node) {
indent -= 2;
console.log(padding() + 'leave' + node.type);
}
})
```

结果:
```txt
进入Program
进入FunctionDeclaration
进入Identifier
离开Identifier
进入BlockStatement
离开BlockStatement
离开FunctionDeclaration
进入EmptyStatement
离开EmptyStatement
离开Program
```

### 生成语法树

代码:
```js
let target = escodegen.generate(res);
console.log(target)
```

结果:
```js
function ast() {
}
```

我们可以在第二步生成的时候,对生成的代码做一些自己的转换。

## 使用babel解析箭头函数

安装依赖
`npm install @babel/core babel-types babel-plugin-transform-es2015-arrow-functions -D`


代码:
```js
const core = require('@babel/core');
const types = require('babel-types');
const plugin = require('babel-plugin-transform-es2015-arrow-functions');

const code = `
const sum = (a, b) => a + b;
`

// babel/core 本身只有 生成、遍历、生成 代码的功能,和上面的三个工具一样
// 它本身不会在代码遍历的时候做一个处理,除了用插件等方法
let target = core.transform(code, {
plugins: [plugin] // 这里如果不加plugin的话,生成的code就是源代码
})
console.log(target.code);
```

结果:

```js
const sum = function (a, b) {
return a + b;
};
```

### 实现插件

```js

```
1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/browserslist

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/escodegen

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/esgenerate

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/esparse

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/esvalidate

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/jsesc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/json5

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/parser

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions learnWebpack/ast-demo/node_modules/.bin/semver

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fb7a6df

Please sign in to comment.