合并两个AST

发布于 2022-09-12 23:12:07 字数 248 浏览 24 评论 0

image

题目描述

通过修改ast语法树,来修改JavaScript

题目来源及自己的思路

使用到了@babel/parser@babel/traverse@babel/generator

最后想得到相同方法里执行的代码,合并到一个里面

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

土豪 2022-09-19 23:12:07

代码

import * as babel from "@babel/core";
import * as types from "babel-types";

const code1 = `var obj = {
    hello() {
        console.log(111)
    }
}`;

const code2 = `var obj = {
    hello() {
        console.log(222)
    }
}`;

const code1ObjeMethods: Map<string, babel.types.ObjectMethod> = new Map();

//获取code1对象里的objectMethod成员
babel.transform(code1, {
  plugins: [
    {
      visitor: {
        ObjectMethod(path) {
          code1ObjeMethods.set(
            (path.node.key as any).name as string,
            path.node
          );
        }
      }
    }
  ]
});

// const cloneStatement = (statement: babel.types.Statement): types.Statement => {
//     return types.
// }

const result = babel.transform(code2, {
  plugins: [
    {
      visitor: {
        ObjectMethod(path) {
          const methodName = (path.node.key as any).name;
          const code1Method = code1ObjeMethods.get(methodName);
          if (code1Method) {
            const blockStatement = types.blockStatement([
              ...(code1Method.body.body as any),
              ...(path.node.body.body as any)
            ]);

            const newObjectMethod = types.objectMethod(
              "method",
              (path.node.key as unknown) as types.Identifier,
              path.node.params as any,
              blockStatement
            );

            // console.log(blockStatement)

            path.replaceWith(newObjectMethod as any);
            path.skip();
          }
        }
      }
    }
  ]
});

console.log(result?.code);

package.json

{
  "name": "merge-obj",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@babel/core": "^7.13.15",
    "@types/babel-types": "^7.0.9",
    "@types/babel__core": "^7.1.14",
    "@types/node": "^14.14.37",
    "babel-types": "^6.26.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "lib": ["dom", "es6", "dom.iterable", "scripthost", "esnext", "ES2020"],
    "sourceMap": true /* Generates corresponding '.map' file. */,
    "outDir": "./dist" /* Redirect output structure to the directory. */,
    "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
    "removeComments": true /* Do not emit comments to output. */,
    "noEmitOnError": true,

    "strict": true /* Enable all strict type-checking options. */,
    "noUnusedLocals": false /* Report errors on unused locals. */,
    "noUnusedParameters": true /* Report errors on unused parameters. */,
    "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  },
  "exclude": [
    "node_modules" // would be the default
  ]
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文