Do not mutate ast (#8342)

This clones the given ast prior to working on it to avoid mutating the AST given to `transformFromAST`.
This commit is contained in:
Thiago Arrais 2018-07-23 23:20:55 -03:00 committed by Henry Zhu
parent d781e207c8
commit 6f3a800677
2 changed files with 40 additions and 0 deletions

View File

@ -2,6 +2,7 @@
import path from "path"; import path from "path";
import buildDebug from "debug"; import buildDebug from "debug";
import cloneDeep from "lodash/cloneDeep";
import * as t from "@babel/types"; import * as t from "@babel/types";
import type { PluginPasses } from "../config"; import type { PluginPasses } from "../config";
import convertSourceMap, { typeof Converter } from "convert-source-map"; import convertSourceMap, { typeof Converter } from "convert-source-map";
@ -75,6 +76,7 @@ export default function normalizeFile(
} else if (ast.type !== "File") { } else if (ast.type !== "File") {
throw new Error("AST root must be a Program or File node"); throw new Error("AST root must be a Program or File node");
} }
ast = cloneDeep(ast);
} else { } else {
// The parser's AST types aren't fully compatible with the types generated // The parser's AST types aren't fully compatible with the types generated
// by the logic in babel-types. // by the logic in babel-types.

View File

@ -12,6 +12,13 @@ function assertNotIgnored(result) {
expect(result).not.toBeNull(); expect(result).not.toBeNull();
} }
function parse(code, opts) {
return babel.parse(code, {
cwd: __dirname,
...opts,
});
}
function transform(code, opts) { function transform(code, opts) {
return babel.transform(code, { return babel.transform(code, {
cwd: __dirname, cwd: __dirname,
@ -43,6 +50,13 @@ function transformAsync(code, opts) {
}); });
} }
function transformFromAst(ast, code, opts) {
return babel.transformFromAst(ast, code, {
cwd: __dirname,
...opts,
});
}
describe("parser and generator options", function() { describe("parser and generator options", function() {
const recast = { const recast = {
parse: function(code, opts) { parse: function(code, opts) {
@ -168,6 +182,30 @@ describe("api", function() {
expect(options).toEqual({ babelrc: false }); expect(options).toEqual({ babelrc: false });
}); });
it("transformFromAst should not mutate the AST", function() {
const program = "const identifier = 1";
const node = parse(program);
const { code } = transformFromAst(node, program, {
plugins: [
function() {
return {
visitor: {
Identifier: function(path) {
path.node.name = "replaced";
},
},
};
},
],
});
expect(code).toBe("const replaced = 1;");
expect(node.program.body[0].declarations[0].id.name).toBe(
"identifier",
"original ast should not have been mutated",
);
});
it("options throw on falsy true", function() { it("options throw on falsy true", function() {
return expect(function() { return expect(function() {
transform("", { transform("", {