diff --git a/packages/babel/src/traversal/path/replacement.js b/packages/babel/src/traversal/path/replacement.js index 262a5afa5b..16bda31e7a 100644 --- a/packages/babel/src/traversal/path/replacement.js +++ b/packages/babel/src/traversal/path/replacement.js @@ -1,4 +1,7 @@ +import codeFrame from "../../helpers/code-frame"; +import traverse from "../index"; import NodePath from "./index"; +import parse from "../../helpers/parse"; import * as t from "../../types"; /** @@ -60,11 +63,31 @@ export function replaceWithMultiple(nodes: Array) { } /** - * DEPRECATED + * Parse a string as an expression and replace the current node with the result. + * + * NOTE: This is typically not a good idea to use. Building source strings when + * transforming ASTs is an antipattern and SHOULD NOT be encouraged. Even if it's + * easier to use, your transforms will be extremely brittle. */ export function replaceWithSourceString(replacement) { - throw new Error("TODO"); + this.resync(); + + try { + replacement = `(${replacement})`; + replacement = parse(replacement); + } catch (err) { + var loc = err.loc; + if (loc) { + err.message += " - make sure this is an expression."; + err.message += "\n" + codeFrame(replacement, loc.line, loc.column + 1); + } + throw err; + } + + replacement = replacement.program.body[0].expression; + traverse.removeProperties(replacement); + return this.replaceWith(replacement); } /** diff --git a/packages/babel/test/path.js b/packages/babel/test/path.js new file mode 100644 index 0000000000..e203c55c9d --- /dev/null +++ b/packages/babel/test/path.js @@ -0,0 +1,23 @@ +var transform = require("../lib/transformation"); +var Plugin = require("../lib/transformation/plugin"); +var babel = require("../lib/api/node"); +var chai = require("chai"); + +suite("traversal path", function () { + test("replaceWithSourceString", function () { + var expectCode = "function foo() {}"; + + var actualCode = transform(expectCode, { + blacklist: "strict", + plugins: [new Plugin("foobar", { + visitor: { + FunctionDeclaration: function () { + this.replaceWithSourceString("console.whatever()"); + } + } + })] + }).code; + + chai.expect(actualCode).to.be.equal("console.whatever();"); + }); +});