From fa11361354d12375d327a2288dafbaafb42d0853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hua=CC=81ng=20Ju=CC=80nlia=CC=80ng?= Date: Fri, 7 Jun 2019 00:02:16 -0400 Subject: [PATCH] WIP: working on third test case --- .../babel-traverse/src/scope/lib/renamer.js | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/babel-traverse/src/scope/lib/renamer.js b/packages/babel-traverse/src/scope/lib/renamer.js index cdfd90819681..89dee46e76c1 100644 --- a/packages/babel-traverse/src/scope/lib/renamer.js +++ b/packages/babel-traverse/src/scope/lib/renamer.js @@ -29,6 +29,24 @@ const renameVisitor = { }, }; +function isSafeBinding(scope, node) { + if (!scope.hasOwnBinding(node.name)) return true; + const { kind } = scope.getOwnBinding(node.name); + return kind === "param" || kind === "local"; +} + +const outerBindingVisitor = { + ReferencedIdentifier(path, state) { + const { node } = path; + if (node.name === state.oldName && !isSafeBinding(state.scope, node)) { + state.paramDefaultOuterBinding = true; + path.stop(); + } + }, + Scope(path) { + path.skip(); + }, +}; export default class Renamer { constructor(binding: Binding, oldName: string, newName: string) { this.newName = newName; @@ -116,7 +134,37 @@ export default class Renamer { } } - scope.traverse(block || scope.block, renameVisitor, this); + const state = { + paramDefaultOuterBinding: false, + scope, + oldName, + }; + if (scope.path.isFunction()) { + const params = scope.path.get("params"); + for (let i = 0; i < params.length; i++) { + const param = params[i]; + if (param.isAssignmentPattern()) { + const right = param.get("right"); + if (!state.paramDefaultOuterBinding) { + if ( + right.isIdentifier() && + right.node.body.name === oldName && + !isSafeBinding(scope, right.node.body) + ) { + state.paramDefaultOuterBinding = true; + break; + } else { + right.traverse(outerBindingVisitor, state); + } + } + } + } + } + if (state.paramDefaultOuterBinding) { + scope.traverse(block || scope.block.body, renameVisitor, this); + } else { + scope.traverse(block || scope.block, renameVisitor, this); + } if (!block) { scope.removeOwnBinding(oldName);