Fixed mutation bug in CommitTreeBuilder
Brian Vaughn committed
Mar 17, 2019 at 10:25 UTC
d685efd72f4f769c1bef63b77f31f12015c8d762
1 file changed
+13
-5
src/devtools/views/Profiler/CommitTreeBuilder.js
+13
-5
@@ -152,8 +152,16 @@ function updateTree(
152
commitTree: CommitTree,
153
operations: Uint32Array
154
): CommitTree {
155
+ // Clone the original tree so edits don't affect it.
156
const nodes = new Map(commitTree.nodes);
157
158
+ // Clone nodes before mutating them so edits don't affect them.
159
+ const getClonedNode = (id: number): Node => {
160
+ const clonedNode = ((Object.assign({}, nodes.get(id)): any): Node);
161
+ nodes.set(id, clonedNode);
162
+ return clonedNode;
163
+ };
164
+
165
let i = 2;
166
while (i < operations.length) {
167
let id: number = ((null: any): number);
@@ -202,7 +210,7 @@ function updateTree(
210
// For now, we avoid adding it to the tree twice by checking if it's already been mounted.
211
// Maybe in the future we'll revisit this.
212
} else {
205
- parentNode = ((nodes.get(parentID): any): Node);
213
+ parentNode = getClonedNode(parentID);
214
parentNode.children = parentNode.children.concat(id);
215
216
debug(
@@ -228,12 +236,12 @@ function updateTree(
236
237
i = i + 2;
238
231
- node = ((nodes.get(id): any): Node);
239
+ node = getClonedNode(id);
240
parentID = node.parentID;
241
242
nodes.delete(id);
243
236
- parentNode = ((nodes.get(parentID): any): Node);
244
+ parentNode = getClonedNode(parentID);
245
if (parentNode == null) {
246
// No-op
247
} else {
@@ -256,14 +264,14 @@ function updateTree(
264
265
debug('Re-order', `fiber ${id} children ${children.join(',')}`);
266
259
- node = ((nodes.get(id): any): Node);
267
+ node = getClonedNode(id);
268
node.children = Array.from(children);
269
270
break;
271
case TREE_OPERATION_UPDATE_TREE_BASE_DURATION:
272
id = operations[i + 1];
273
266
- node = ((nodes.get(id): any): Node);
274
+ node = getClonedNode(id);
275
node.treeBaseDuration = operations[i + 2] / 1000; // Convert microseconds back to milliseconds;
276
277
debug(