diff --git a/packages/babel-traverse/src/context.js b/packages/babel-traverse/src/context.js index 5dd830f91d00..12f76d0c9ad4 100644 --- a/packages/babel-traverse/src/context.js +++ b/packages/babel-traverse/src/context.js @@ -95,7 +95,7 @@ export default class TraversalContext { this.queue = queue; this.priorityQueue = []; - const visited = []; + const visited = new WeakSet(); let stop = false; // visit the queue @@ -120,8 +120,9 @@ export default class TraversalContext { } // ensure we don't visit the same node twice - if (visited.indexOf(path.node) >= 0) continue; - visited.push(path.node); + const { node } = path; + if (visited.has(node)) continue; + if (node) visited.add(node); if (path.visit()) { stop = true; diff --git a/packages/babel-traverse/src/path/index.js b/packages/babel-traverse/src/path/index.js index 84f3664333fb..fb13ec9bf488 100644 --- a/packages/babel-traverse/src/path/index.js +++ b/packages/babel-traverse/src/path/index.js @@ -67,24 +67,16 @@ export default class NodePath { const targetNode = container[key]; - const paths = pathCache.get(parent) || []; - if (!pathCache.has(parent)) { + let paths = pathCache.get(parent); + if (!paths) { + paths = new Map(); pathCache.set(parent, paths); } - let path; - - for (let i = 0; i < paths.length; i++) { - const pathCheck = paths[i]; - if (pathCheck.node === targetNode) { - path = pathCheck; - break; - } - } - + let path = paths.get(targetNode); if (!path) { path = new NodePath(hub, parent); - paths.push(path); + if (targetNode) paths.set(targetNode, path); } path.setup(parentPath, container, listKey, key); diff --git a/packages/babel-traverse/src/path/modification.js b/packages/babel-traverse/src/path/modification.js index 1f6d2a0b32db..1402f1e3ae41 100644 --- a/packages/babel-traverse/src/path/modification.js +++ b/packages/babel-traverse/src/path/modification.js @@ -163,8 +163,7 @@ export function updateSiblingKeys(fromIndex, incrementBy) { if (!this.parent) return; const paths = pathCache.get(this.parent); - for (let i = 0; i < paths.length; i++) { - const path = paths[i]; + for (const [, path] of paths) { if (path.key >= fromIndex) { path.key += incrementBy; } diff --git a/packages/babel-traverse/src/path/removal.js b/packages/babel-traverse/src/path/removal.js index 07144f2b6bc5..a8bd4523fdc6 100644 --- a/packages/babel-traverse/src/path/removal.js +++ b/packages/babel-traverse/src/path/removal.js @@ -1,6 +1,7 @@ // This file contains methods responsible for removing a node. import { hooks } from "./lib/removal-hooks"; +import { path as pathCache } from "../cache"; import { REMOVED, SHOULD_SKIP } from "./index"; export function remove() { @@ -44,6 +45,7 @@ export function _remove() { export function _markRemoved() { // this.shouldSkip = true; this.removed = true; this._traverseFlags |= SHOULD_SKIP | REMOVED; + if (this.parent) pathCache.get(this.parent).delete(this.node); this.node = null; } diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index 211940841367..c3add1418745 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -3,6 +3,7 @@ import { codeFrameColumns } from "@babel/code-frame"; import traverse from "../index"; import NodePath from "./index"; +import { path as pathCache } from "../cache"; import { parse } from "@babel/parser"; import * as t from "@babel/types"; @@ -49,6 +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); this.node = this.container[this.key] = null; const paths = this.insertAfter(nodes);