Repository: facebook/react
Pull request: [DevTools] Remove findCurrentFiberUsingSlowPathByFiberInstance

We always track the last committed Fiber on `FiberInstance.data`.

https://github.com/facebook/react/blob/dcae56f8b72f625d8affe5729ca9991b31a492ac/packages/react-devtools-shared/src/backend/fiber/renderer.js#L3068

So we can now remove this complex slow path to get the current fiber.

Changed files:
filename: packages/react-devtools-shared/src/backend/fiber/renderer.js
patch: @@ -3550,7 +3550,7 @@ export function attach(
     fiberInstance: FiberInstance,
   ): $ReadOnlyArray<HostInstance> {
     const hostInstances = [];
-    const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance);
+    const fiber = fiberInstance.data;
     if (!fiber) {
       return hostInstances;
     }
@@ -3601,8 +3601,7 @@ export function attach(
         // TODO: Handle VirtualInstance.
         return null;
       }
-      const fiber =
-        findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
+      const fiber = devtoolsInstance.data;
       if (fiber === null) {
         return null;
       }
@@ -3710,208 +3709,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<string | number>,
@@ -4096,8 +3893,7 @@ export function attach(
       return {instance, style};
     }
 
-    const fiber =
-      findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
+    const fiber = devtoolsInstance.data;
     if (fiber !== null) {
       instance = fiber.stateNode;
 
@@ -4153,7 +3949,7 @@ export function attach(
   function inspectFiberInstanceRaw(
     fiberInstance: FiberInstance,
   ): InspectedElement | null {
-    const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance);
+    const fiber = fiberInstance.data;
     if (fiber == null) {
       return null;
     }
@@ -4913,8 +4709,7 @@ export function attach(
       // TODO: Handle VirtualInstance.
       return;
     }
-    const fiber =
-      findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
+    const fiber = devtoolsInstance.data;
     if (fiber !== null) {
       const instance = fiber.stateNode;
 
@@ -4979,8 +4774,7 @@ export function attach(
       // TODO: Handle VirtualInstance.
       return;
     }
-    const fiber =
-      findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
+    const fiber = devtoolsInstance.data;
     if (fiber !== null) {
       const instance = fiber.stateNode;
 
@@ -5055,8 +4849,7 @@ export function attach(
       // TODO: Handle VirtualInstance.
       return;
     }
-    const fiber =
-      findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
+    const fiber = devtoolsInstance.data;
     if (fiber !== null) {
       const instance = fiber.stateNode;