From 53a3c44eda6a631b812d6507e12c7d62482f933c Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 26 Aug 2024 17:19:01 -0400 Subject: [PATCH] Remove findCurrentFiberUsingSlowPathByFiberInstance We always track the last committed Fiber on FiberInstance.data. --- .../src/backend/fiber/renderer.js | 221 +----------------- 1 file changed, 7 insertions(+), 214 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/fiber/renderer.js b/packages/react-devtools-shared/src/backend/fiber/renderer.js index 57eafa176f550..7b6514af2e787 100644 --- a/packages/react-devtools-shared/src/backend/fiber/renderer.js +++ b/packages/react-devtools-shared/src/backend/fiber/renderer.js @@ -3512,7 +3512,7 @@ export function attach( fiberInstance: FiberInstance, ): $ReadOnlyArray { const hostInstances = []; - const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance); + const fiber = fiberInstance.data; if (!fiber) { return hostInstances; } @@ -3563,8 +3563,7 @@ export function attach( // TODO: Handle VirtualInstance. return null; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); + const fiber = devtoolsInstance.data; if (fiber === null) { return null; } @@ -3672,208 +3671,6 @@ export function attach( return null; } - // This function is copied from React and should be kept in sync: - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js - function assertIsMounted(fiber: Fiber) { - if (getNearestMountedFiber(fiber) !== fiber) { - throw new Error('Unable to find node on an unmounted component.'); - } - } - - // This function is copied from React and should be kept in sync: - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js - function getNearestMountedFiber(fiber: Fiber): null | Fiber { - let node = fiber; - let nearestMounted: null | Fiber = fiber; - if (!fiber.alternate) { - // If there is no alternate, this might be a new tree that isn't inserted - // yet. If it is, then it will have a pending insertion effect on it. - let nextNode: Fiber = node; - do { - node = nextNode; - // TODO: This function, and these flags, are a leaked implementation - // detail. Once we start releasing DevTools in lockstep with React, we - // should import a function from the reconciler instead. - const Placement = 0b000000000000000000000000010; - const Hydrating = 0b000000000000001000000000000; - if ((node.flags & (Placement | Hydrating)) !== 0) { - // This is an insertion or in-progress hydration. The nearest possible - // mounted fiber is the parent but we need to continue to figure out - // if that one is still mounted. - nearestMounted = node.return; - } - // $FlowFixMe[incompatible-type] we bail out when we get a null - nextNode = node.return; - } while (nextNode); - } else { - while (node.return) { - node = node.return; - } - } - if (node.tag === HostRoot) { - // TODO: Check if this was a nested HostRoot when used with - // renderContainerIntoSubtree. - return nearestMounted; - } - // If we didn't hit the root, that means that we're in an disconnected tree - // that has been unmounted. - return null; - } - - // This function is copied from React and should be kept in sync: - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js - // It would be nice if we updated React to inject this function directly (vs just indirectly via findDOMNode). - // BEGIN copied code - function findCurrentFiberUsingSlowPathByFiberInstance( - fiberInstance: FiberInstance, - ): Fiber | null { - const fiber = fiberInstance.data; - const alternate = fiber.alternate; - if (!alternate) { - // If there is no alternate, then we only need to check if it is mounted. - const nearestMounted = getNearestMountedFiber(fiber); - - if (nearestMounted === null) { - throw new Error('Unable to find node on an unmounted component.'); - } - - if (nearestMounted !== fiber) { - return null; - } - return fiber; - } - // If we have two possible branches, we'll walk backwards up to the root - // to see what path the root points to. On the way we may hit one of the - // special cases and we'll deal with them. - let a: Fiber = fiber; - let b: Fiber = alternate; - while (true) { - const parentA = a.return; - if (parentA === null) { - // We're at the root. - break; - } - const parentB = parentA.alternate; - if (parentB === null) { - // There is no alternate. This is an unusual case. Currently, it only - // happens when a Suspense component is hidden. An extra fragment fiber - // is inserted in between the Suspense fiber and its children. Skip - // over this extra fragment fiber and proceed to the next parent. - const nextParent = parentA.return; - if (nextParent !== null) { - a = b = nextParent; - continue; - } - // If there's no parent, we're at the root. - break; - } - - // If both copies of the parent fiber point to the same child, we can - // assume that the child is current. This happens when we bailout on low - // priority: the bailed out fiber's child reuses the current child. - if (parentA.child === parentB.child) { - let child = parentA.child; - while (child) { - if (child === a) { - // We've determined that A is the current branch. - assertIsMounted(parentA); - return fiber; - } - if (child === b) { - // We've determined that B is the current branch. - assertIsMounted(parentA); - return alternate; - } - child = child.sibling; - } - - // We should never have an alternate for any mounting node. So the only - // way this could possibly happen is if this was unmounted, if at all. - throw new Error('Unable to find node on an unmounted component.'); - } - - if (a.return !== b.return) { - // The return pointer of A and the return pointer of B point to different - // fibers. We assume that return pointers never criss-cross, so A must - // belong to the child set of A.return, and B must belong to the child - // set of B.return. - a = parentA; - b = parentB; - } else { - // The return pointers point to the same fiber. We'll have to use the - // default, slow path: scan the child sets of each parent alternate to see - // which child belongs to which set. - // - // Search parent A's child set - let didFindChild = false; - let child = parentA.child; - while (child) { - if (child === a) { - didFindChild = true; - a = parentA; - b = parentB; - break; - } - if (child === b) { - didFindChild = true; - b = parentA; - a = parentB; - break; - } - child = child.sibling; - } - if (!didFindChild) { - // Search parent B's child set - child = parentB.child; - while (child) { - if (child === a) { - didFindChild = true; - a = parentB; - b = parentA; - break; - } - if (child === b) { - didFindChild = true; - b = parentB; - a = parentA; - break; - } - child = child.sibling; - } - - if (!didFindChild) { - throw new Error( - 'Child was not found in either parent set. This indicates a bug ' + - 'in React related to the return pointer. Please file an issue.', - ); - } - } - } - - if (a.alternate !== b) { - throw new Error( - "Return fibers should always be each others' alternates. " + - 'This error is likely caused by a bug in React. Please file an issue.', - ); - } - } - - // If the root is not a host container, we're in a disconnected tree. I.e. - // unmounted. - if (a.tag !== HostRoot) { - throw new Error('Unable to find node on an unmounted component.'); - } - - if (a.stateNode.current === a) { - // We've determined that A is the current branch. - return fiber; - } - // Otherwise B has to be current branch. - return alternate; - } - - // END copied code - function getElementAttributeByPath( id: number, path: Array, @@ -4058,8 +3855,7 @@ export function attach( return {instance, style}; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); + const fiber = devtoolsInstance.data; if (fiber !== null) { instance = fiber.stateNode; @@ -4115,7 +3911,7 @@ export function attach( function inspectFiberInstanceRaw( fiberInstance: FiberInstance, ): InspectedElement | null { - const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance); + const fiber = fiberInstance.data; if (fiber == null) { return null; } @@ -4877,8 +4673,7 @@ export function attach( // TODO: Handle VirtualInstance. return; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); + const fiber = devtoolsInstance.data; if (fiber !== null) { const instance = fiber.stateNode; @@ -4943,8 +4738,7 @@ export function attach( // TODO: Handle VirtualInstance. return; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); + const fiber = devtoolsInstance.data; if (fiber !== null) { const instance = fiber.stateNode; @@ -5019,8 +4813,7 @@ export function attach( // TODO: Handle VirtualInstance. return; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); + const fiber = devtoolsInstance.data; if (fiber !== null) { const instance = fiber.stateNode;