diff --git a/packages/babel-helper-wrap-function/src/index.js b/packages/babel-helper-wrap-function/src/index.js index 2a086abcb3..c05d80fc4f 100644 --- a/packages/babel-helper-wrap-function/src/index.js +++ b/packages/babel-helper-wrap-function/src/index.js @@ -89,11 +89,8 @@ function plainFunction(path: NodePath, callId: Object) { }); if (isDeclaration) { - const basePath = path.parentPath.isExportDeclaration() - ? path.parentPath - : path; - basePath.insertAfter(container[1]); path.replaceWith(container[0]); + path.insertAfter(container[1]); } else { const retFunction = container.callee.body.body[1].argument; if (!functionId) { diff --git a/packages/babel-plugin-proposal-class-properties/src/index.js b/packages/babel-plugin-proposal-class-properties/src/index.js index 25d9507d6b..ac77abf58a 100644 --- a/packages/babel-plugin-proposal-class-properties/src/index.js +++ b/packages/babel-plugin-proposal-class-properties/src/index.js @@ -228,15 +228,9 @@ export default function(api, options) { if (path.isClassExpression()) { path.scope.push({ id: ref }); path.replaceWith(t.assignmentExpression("=", ref, path.node)); - } else { - // path.isClassDeclaration() - if (!path.node.id) { - path.node.id = ref; - } - - if (path.parentPath.isExportDeclaration()) { - path = path.parentPath; - } + } else if (!path.node.id) { + // Anonymous class declaration + path.node.id = ref; } path.insertAfter(nodes); diff --git a/packages/babel-plugin-transform-typescript/src/enum.js b/packages/babel-plugin-transform-typescript/src/enum.js index 0dd3d1e927..23ae6d0077 100644 --- a/packages/babel-plugin-transform-typescript/src/enum.js +++ b/packages/babel-plugin-transform-typescript/src/enum.js @@ -14,25 +14,14 @@ export default function transpileEnum(path, t) { switch (path.parent.type) { case "BlockStatement": + case "ExportNamedDeclaration": case "Program": { - const isGlobal = t.isProgram(path.parent); // && !path.parent.body.some(t.isModuleDeclaration); + path.insertAfter(fill); if (seen(path.parentPath)) { - path.replaceWith(fill); - } else { - path.replaceWithMultiple([ - makeVar(node.id, t, isGlobal ? "var" : "let"), - fill, - ]); - } - break; - } - - case "ExportNamedDeclaration": { - path.parentPath.insertAfter(fill); - if (seen(path.parentPath.parentPath)) { path.remove(); } else { - path.replaceWith(makeVar(node.id, t, "let")); + const isGlobal = t.isProgram(path.parent); // && !path.parent.body.some(t.isModuleDeclaration); + path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let")); } break; } @@ -42,6 +31,10 @@ export default function transpileEnum(path, t) { } function seen(parentPath: Path) { + if (parentPath.isExportDeclaration()) { + return seen(parentPath.parentPath); + } + if (parentPath.getData(name)) { return true; } else { diff --git a/packages/babel-traverse/src/path/lib/hoister.js b/packages/babel-traverse/src/path/lib/hoister.js index 043e650de9..ec7b279913 100644 --- a/packages/babel-traverse/src/path/lib/hoister.js +++ b/packages/babel-traverse/src/path/lib/hoister.js @@ -128,12 +128,6 @@ export default class PathHoister { } } - // We can't insert before/after a child of an export declaration, so move up - // to the declaration itself. - if (path.parentPath.isExportDeclaration()) { - path = path.parentPath; - } - return path; } diff --git a/packages/babel-traverse/src/path/modification.js b/packages/babel-traverse/src/path/modification.js index 6230a17980..4eaf93543e 100644 --- a/packages/babel-traverse/src/path/modification.js +++ b/packages/babel-traverse/src/path/modification.js @@ -16,7 +16,8 @@ export function insertBefore(nodes) { if ( this.parentPath.isExpressionStatement() || - this.parentPath.isLabeledStatement() + this.parentPath.isLabeledStatement() || + this.parentPath.isExportDeclaration() ) { return this.parentPath.insertBefore(nodes); } else if ( @@ -96,7 +97,8 @@ export function insertAfter(nodes) { if ( this.parentPath.isExpressionStatement() || - this.parentPath.isLabeledStatement() + this.parentPath.isLabeledStatement() || + this.parentPath.isExportDeclaration() ) { return this.parentPath.insertAfter(nodes); } else if ( diff --git a/packages/babel-traverse/test/modification.js b/packages/babel-traverse/test/modification.js index ea7db834fe..e526b4d6b4 100644 --- a/packages/babel-traverse/test/modification.js +++ b/packages/babel-traverse/test/modification.js @@ -4,8 +4,8 @@ import { parse } from "babylon"; import generate from "@babel/generator"; import * as t from "@babel/types"; -function getPath(code) { - const ast = parse(code); +function getPath(code, parserOpts) { + const ast = parse(code, parserOpts); let path; traverse(ast, { Program: function(_path) { @@ -118,6 +118,41 @@ describe("modification", function() { "if (x) {\n b\n\n for (var i = 0; i < 0; i++) {}\n}", ); }); + + describe("when the parent is an export declaration inserts the node before", function() { + it("the ExportNamedDeclaration", function() { + const bodyPath = getPath("export function a() {}", { + sourceType: "module", + }).parentPath; + const fnPath = bodyPath.get("body.0.declaration"); + fnPath.insertBefore(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.0").node, t.identifier("x")); + }); + + it("the ExportDefaultDeclaration, if a declaration is exported", function() { + const bodyPath = getPath("export default function () {}", { + sourceType: "module", + }).parentPath; + const fnPath = bodyPath.get("body.0.declaration"); + fnPath.insertBefore(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.0").node, t.identifier("x")); + }); + + it("the exported expression", function() { + const bodyPath = getPath("export default 2;", { + sourceType: "module", + }).parentPath; + const path = bodyPath.get("body.0.declaration"); + path.insertBefore(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.0").node, t.identifier("x")); + }); + }); }); describe("insertAfter", function() { @@ -170,5 +205,40 @@ describe("modification", function() { "if (x) {\n for (var i = 0; i < 0; i++) {}\n\n b\n}", ); }); + + describe("when the parent is an export declaration inserts the node after", function() { + it("the ExportNamedDeclaration", function() { + const bodyPath = getPath("export function a() {}", { + sourceType: "module", + }).parentPath; + const fnPath = bodyPath.get("body.0.declaration"); + fnPath.insertAfter(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.1").node, t.identifier("x")); + }); + + it("the ExportDefaultDeclaration, if a declaration is exported", function() { + const bodyPath = getPath("export default function () {}", { + sourceType: "module", + }).parentPath; + const fnPath = bodyPath.get("body.0.declaration"); + fnPath.insertAfter(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.1").node, t.identifier("x")); + }); + + it("the exported expression", function() { + const bodyPath = getPath("export default 2;", { + sourceType: "module", + }).parentPath; + const path = bodyPath.get("body.0.declaration"); + path.insertAfter(t.identifier("x")); + + assert.equal(bodyPath.get("body").length, 2); + assert.deepEqual(bodyPath.get("body.1").node, t.identifier("x")); + }); + }); }); });