/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import ReactSharedInternals from 'shared/ReactSharedInternals'; import { IndeterminateComponent, FunctionComponent, FunctionComponentLazy, ClassComponent, ClassComponentLazy, HostComponent, Mode, } from 'shared/ReactWorkTags'; import describeComponentFrame from 'shared/describeComponentFrame'; import getComponentName from 'shared/getComponentName'; const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; import type {Fiber} from './ReactFiber'; type LifeCyclePhase = 'render' | 'getChildContext'; function describeFiber(fiber: Fiber): string { switch (fiber.tag) { case IndeterminateComponent: case FunctionComponent: case FunctionComponentLazy: case ClassComponent: case ClassComponentLazy: case HostComponent: case Mode: const owner = fiber._debugOwner; const source = fiber._debugSource; const name = getComponentName(fiber.type); let ownerName = null; if (owner) { ownerName = getComponentName(owner.type); } return describeComponentFrame(name, source, ownerName); default: return ''; } } export function getStackByFiberInDevAndProd(workInProgress: Fiber): string { let info = ''; let node = workInProgress; do { info += describeFiber(node); node = node.return; } while (node); return info; } export let current: Fiber | null = null; export let phase: LifeCyclePhase | null = null; export function getCurrentFiberOwnerNameInDevOrNull(): string | null { if (__DEV__) { if (current === null) { return null; } const owner = current._debugOwner; if (owner !== null && typeof owner !== 'undefined') { return getComponentName(owner.type); } } return null; } export function getCurrentFiberStackInDev(): string { if (__DEV__) { if (current === null) { return ''; } // Safe because if current fiber exists, we are reconciling, // and it is guaranteed to be the work-in-progress version. return getStackByFiberInDevAndProd(current); } return ''; } export function resetCurrentFiber() { if (__DEV__) { ReactDebugCurrentFrame.getCurrentStack = null; current = null; phase = null; } } export function setCurrentFiber(fiber: Fiber) { if (__DEV__) { ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; current = fiber; phase = null; } } export function setCurrentPhase(lifeCyclePhase: LifeCyclePhase | null) { if (__DEV__) { phase = lifeCyclePhase; } }