From 8d8782a701f2a1513d0ee186068780a5b2680658 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Mon, 23 Nov 2020 09:00:50 -0600 Subject: [PATCH 1/5] add tests on regression 12386 --- .../non-null-in-optional-chain/input.ts | 2 ++ .../non-null-in-optional-chain/options.json | 3 +++ .../non-null-in-optional-chain/output.js | 7 +++++++ 3 files changed, 12 insertions(+) create mode 100644 packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/input.ts create mode 100644 packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/options.json create mode 100644 packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/output.js diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/input.ts new file mode 100644 index 000000000000..778dc9064277 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/input.ts @@ -0,0 +1,2 @@ +const a = 1; +const b = () => a?.b?.c!.d; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/options.json new file mode 100644 index 000000000000..57204f16510c --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-typescript", "proposal-optional-chaining"] +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/output.js new file mode 100644 index 000000000000..a2a72afdb108 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/variable-declaration/non-null-in-optional-chain/output.js @@ -0,0 +1,7 @@ +const a = 1; + +const b = () => { + var _a$b; + + return a === null || a === void 0 ? void 0 : (_a$b = a.b) === null || _a$b === void 0 ? void 0 : _a$b.c.d; +}; From 3949b40ef38caad95415d5a54787ce917a3389eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Mon, 23 Nov 2020 23:17:51 -0500 Subject: [PATCH 2/5] fix: update cache on _replaceWith --- packages/babel-traverse/src/path/replacement.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index c3add1418745..16742db72a33 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -199,6 +199,11 @@ export function _replaceWith(node) { } this.debug(`Replace with ${node?.type}`); + const cache = pathCache.get(this.parent); + if (cache) { + cache.set(node, this); + cache.delete(this.node); + } this.node = this.container[this.key] = node; } From 04d106c9de0c6799429bf1fecd09b7779a3316e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 24 Nov 2020 00:02:01 -0500 Subject: [PATCH 3/5] fix: pathCache in replaceWithMultiple could be nullish --- packages/babel-traverse/src/path/replacement.js | 2 +- packages/babel-traverse/test/conversion.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index 16742db72a33..c54de58438c5 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -50,7 +50,7 @@ export function replaceWithMultiple(nodes: Array) { nodes = this._verifyNodeList(nodes); t.inheritLeadingComments(nodes[0], this.node); t.inheritTrailingComments(nodes[nodes.length - 1], this.node); - pathCache.get(this.parent).delete(this.node); + pathCache.get(this.parent)?.delete(this.node); this.node = this.container[this.key] = null; const paths = this.insertAfter(nodes); diff --git a/packages/babel-traverse/test/conversion.js b/packages/babel-traverse/test/conversion.js index 97bd0d4cdc53..54f90cab2666 100644 --- a/packages/babel-traverse/test/conversion.js +++ b/packages/babel-traverse/test/conversion.js @@ -51,6 +51,14 @@ describe("conversion", function () { expect(generateCode(rootPath)).toBe("() => {\n return false;\n};"); }); + it("preserves arrow function body's context", function () { + const rootPath = getPath("() => true").get("expression"); + const body = rootPath.get("body"); + rootPath.ensureBlock(); + body.replaceWithMultiple([t.booleanLiteral(false), t.emptyStatement()]); + expect(generateCode(rootPath)).toBe("() => {\n return false;\n};"); + }); + it("converts for loop with statement body to block", function () { const rootPath = getPath("for (;;) true;"); rootPath.ensureBlock(); From 9b91f0f540a932045bd21f7e50de69994e972504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 24 Nov 2020 11:52:02 -0500 Subject: [PATCH 4/5] Update packages/babel-traverse/src/path/replacement.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolò Ribaudo --- packages/babel-traverse/src/path/replacement.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index c54de58438c5..dc1512805172 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -199,11 +199,7 @@ export function _replaceWith(node) { } this.debug(`Replace with ${node?.type}`); - const cache = pathCache.get(this.parent); - if (cache) { - cache.set(node, this); - cache.delete(this.node); - } + pathCache.get(this.parent)?.set(node, this).delete(this.node); this.node = this.container[this.key] = node; } From 307b003de7385fe21458d36f6bb46a24e1a25205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 24 Nov 2020 13:53:28 -0500 Subject: [PATCH 5/5] test: add replaceWith test to traverse --- packages/babel-traverse/test/replacement.js | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/babel-traverse/test/replacement.js b/packages/babel-traverse/test/replacement.js index 0109e8cf04c2..e04d831e99f3 100644 --- a/packages/babel-traverse/test/replacement.js +++ b/packages/babel-traverse/test/replacement.js @@ -112,6 +112,33 @@ describe("path/replacement", function () { }); expect(visitCounter).toBe(1); }); + + // https://github.com/babel/babel/issues/12386 + it("updates pathCache with the replaced node", () => { + const ast = parse(`() => (a?.b)?.c`, { + createParenthesizedExpressions: true, + }); + traverse(ast, { + OptionalMemberExpression(path) { + path.node.type = "MemberExpression"; + // force `replaceWith` to replace `path.node` + path.replaceWith(path.node.__clone()); + path.parentPath.ensureBlock(); + + const aQuestionDotBNode = path.node.object.expression; + // avoid traversing to a?.b + aQuestionDotBNode.type = "MemberExpression"; + }, + ParenthesizedExpression(path) { + path.replaceWith(path.node.expression); + }, + }); + expect(generate(ast).code).toMatchInlineSnapshot(` + "() => { + return a.b.c; + };" + `); + }); }); describe("replaceWithMultiple", () => { it("does not add extra parentheses for a JSXElement with a JSXElement parent", () => {