1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import type {ReactElement, Source} from 'shared/ReactElementType';
    
  11. import type {ReactFragment, ReactPortal, ReactScope} from 'shared/ReactTypes';
    
  12. import type {Fiber} from './ReactInternalTypes';
    
  13. import type {RootTag} from './ReactRootTags';
    
  14. import type {WorkTag} from './ReactWorkTags';
    
  15. import type {TypeOfMode} from './ReactTypeOfMode';
    
  16. import type {Lanes} from './ReactFiberLane';
    
  17. import type {SuspenseInstance} from './ReactFiberConfig';
    
  18. import type {
    
  19.   OffscreenProps,
    
  20.   OffscreenInstance,
    
  21. } from './ReactFiberActivityComponent';
    
  22. import type {TracingMarkerInstance} from './ReactFiberTracingMarkerComponent';
    
  23. 
    
  24. import {
    
  25.   supportsResources,
    
  26.   supportsSingletons,
    
  27.   isHostHoistableType,
    
  28.   isHostSingletonType,
    
  29. } from './ReactFiberConfig';
    
  30. import {
    
  31.   createRootStrictEffectsByDefault,
    
  32.   enableCache,
    
  33.   enableProfilerTimer,
    
  34.   enableScopeAPI,
    
  35.   enableLegacyHidden,
    
  36.   forceConcurrentByDefaultForTesting,
    
  37.   allowConcurrentByDefault,
    
  38.   enableTransitionTracing,
    
  39.   enableDebugTracing,
    
  40.   enableFloat,
    
  41.   enableHostSingletons,
    
  42.   enableDO_NOT_USE_disableStrictPassiveEffect,
    
  43. } from 'shared/ReactFeatureFlags';
    
  44. import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
    
  45. import {ConcurrentRoot} from './ReactRootTags';
    
  46. import {
    
  47.   IndeterminateComponent,
    
  48.   ClassComponent,
    
  49.   HostRoot,
    
  50.   HostComponent,
    
  51.   HostText,
    
  52.   HostPortal,
    
  53.   HostHoistable,
    
  54.   HostSingleton,
    
  55.   ForwardRef,
    
  56.   Fragment,
    
  57.   Mode,
    
  58.   ContextProvider,
    
  59.   ContextConsumer,
    
  60.   Profiler,
    
  61.   SuspenseComponent,
    
  62.   SuspenseListComponent,
    
  63.   DehydratedFragment,
    
  64.   FunctionComponent,
    
  65.   MemoComponent,
    
  66.   SimpleMemoComponent,
    
  67.   LazyComponent,
    
  68.   ScopeComponent,
    
  69.   OffscreenComponent,
    
  70.   LegacyHiddenComponent,
    
  71.   CacheComponent,
    
  72.   TracingMarkerComponent,
    
  73. } from './ReactWorkTags';
    
  74. import {OffscreenVisible} from './ReactFiberActivityComponent';
    
  75. import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
    
  76. import {isDevToolsPresent} from './ReactFiberDevToolsHook';
    
  77. import {
    
  78.   resolveClassForHotReloading,
    
  79.   resolveFunctionForHotReloading,
    
  80.   resolveForwardRefForHotReloading,
    
  81. } from './ReactFiberHotReloading';
    
  82. import {NoLanes} from './ReactFiberLane';
    
  83. import {
    
  84.   NoMode,
    
  85.   ConcurrentMode,
    
  86.   DebugTracingMode,
    
  87.   ProfileMode,
    
  88.   StrictLegacyMode,
    
  89.   StrictEffectsMode,
    
  90.   ConcurrentUpdatesByDefaultMode,
    
  91.   NoStrictPassiveEffectsMode,
    
  92. } from './ReactTypeOfMode';
    
  93. import {
    
  94.   REACT_FORWARD_REF_TYPE,
    
  95.   REACT_FRAGMENT_TYPE,
    
  96.   REACT_DEBUG_TRACING_MODE_TYPE,
    
  97.   REACT_STRICT_MODE_TYPE,
    
  98.   REACT_PROFILER_TYPE,
    
  99.   REACT_PROVIDER_TYPE,
    
  100.   REACT_CONTEXT_TYPE,
    
  101.   REACT_SUSPENSE_TYPE,
    
  102.   REACT_SUSPENSE_LIST_TYPE,
    
  103.   REACT_MEMO_TYPE,
    
  104.   REACT_LAZY_TYPE,
    
  105.   REACT_SCOPE_TYPE,
    
  106.   REACT_OFFSCREEN_TYPE,
    
  107.   REACT_LEGACY_HIDDEN_TYPE,
    
  108.   REACT_CACHE_TYPE,
    
  109.   REACT_TRACING_MARKER_TYPE,
    
  110. } from 'shared/ReactSymbols';
    
  111. import {TransitionTracingMarker} from './ReactFiberTracingMarkerComponent';
    
  112. import {
    
  113.   detachOffscreenInstance,
    
  114.   attachOffscreenInstance,
    
  115. } from './ReactFiberCommitWork';
    
  116. import {getHostContext} from './ReactFiberHostContext';
    
  117. 
    
  118. export type {Fiber};
    
  119. 
    
  120. let hasBadMapPolyfill;
    
  121. 
    
  122. if (__DEV__) {
    
  123.   hasBadMapPolyfill = false;
    
  124.   try {
    
  125.     const nonExtensibleObject = Object.preventExtensions({});
    
  126.     /* eslint-disable no-new */
    
  127.     new Map([[nonExtensibleObject, null]]);
    
  128.     new Set([nonExtensibleObject]);
    
  129.     /* eslint-enable no-new */
    
  130.   } catch (e) {
    
  131.     // TODO: Consider warning about bad polyfills
    
  132.     hasBadMapPolyfill = true;
    
  133.   }
    
  134. }
    
  135. 
    
  136. function FiberNode(
    
  137.   this: $FlowFixMe,
    
  138.   tag: WorkTag,
    
  139.   pendingProps: mixed,
    
  140.   key: null | string,
    
  141.   mode: TypeOfMode,
    
  142. ) {
    
  143.   // Instance
    
  144.   this.tag = tag;
    
  145.   this.key = key;
    
  146.   this.elementType = null;
    
  147.   this.type = null;
    
  148.   this.stateNode = null;
    
  149. 
    
  150.   // Fiber
    
  151.   this.return = null;
    
  152.   this.child = null;
    
  153.   this.sibling = null;
    
  154.   this.index = 0;
    
  155. 
    
  156.   this.ref = null;
    
  157.   this.refCleanup = null;
    
  158. 
    
  159.   this.pendingProps = pendingProps;
    
  160.   this.memoizedProps = null;
    
  161.   this.updateQueue = null;
    
  162.   this.memoizedState = null;
    
  163.   this.dependencies = null;
    
  164. 
    
  165.   this.mode = mode;
    
  166. 
    
  167.   // Effects
    
  168.   this.flags = NoFlags;
    
  169.   this.subtreeFlags = NoFlags;
    
  170.   this.deletions = null;
    
  171. 
    
  172.   this.lanes = NoLanes;
    
  173.   this.childLanes = NoLanes;
    
  174. 
    
  175.   this.alternate = null;
    
  176. 
    
  177.   if (enableProfilerTimer) {
    
  178.     // Note: The following is done to avoid a v8 performance cliff.
    
  179.     //
    
  180.     // Initializing the fields below to smis and later updating them with
    
  181.     // double values will cause Fibers to end up having separate shapes.
    
  182.     // This behavior/bug has something to do with Object.preventExtension().
    
  183.     // Fortunately this only impacts DEV builds.
    
  184.     // Unfortunately it makes React unusably slow for some applications.
    
  185.     // To work around this, initialize the fields below with doubles.
    
  186.     //
    
  187.     // Learn more about this here:
    
  188.     // https://github.com/facebook/react/issues/14365
    
  189.     // https://bugs.chromium.org/p/v8/issues/detail?id=8538
    
  190.     this.actualDuration = Number.NaN;
    
  191.     this.actualStartTime = Number.NaN;
    
  192.     this.selfBaseDuration = Number.NaN;
    
  193.     this.treeBaseDuration = Number.NaN;
    
  194. 
    
  195.     // It's okay to replace the initial doubles with smis after initialization.
    
  196.     // This won't trigger the performance cliff mentioned above,
    
  197.     // and it simplifies other profiler code (including DevTools).
    
  198.     this.actualDuration = 0;
    
  199.     this.actualStartTime = -1;
    
  200.     this.selfBaseDuration = 0;
    
  201.     this.treeBaseDuration = 0;
    
  202.   }
    
  203. 
    
  204.   if (__DEV__) {
    
  205.     // This isn't directly used but is handy for debugging internals:
    
  206. 
    
  207.     this._debugSource = null;
    
  208.     this._debugOwner = null;
    
  209.     this._debugNeedsRemount = false;
    
  210.     this._debugHookTypes = null;
    
  211.     if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
    
  212.       Object.preventExtensions(this);
    
  213.     }
    
  214.   }
    
  215. }
    
  216. 
    
  217. // This is a constructor function, rather than a POJO constructor, still
    
  218. // please ensure we do the following:
    
  219. // 1) Nobody should add any instance methods on this. Instance methods can be
    
  220. //    more difficult to predict when they get optimized and they are almost
    
  221. //    never inlined properly in static compilers.
    
  222. // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
    
  223. //    always know when it is a fiber.
    
  224. // 3) We might want to experiment with using numeric keys since they are easier
    
  225. //    to optimize in a non-JIT environment.
    
  226. // 4) We can easily go from a constructor to a createFiber object literal if that
    
  227. //    is faster.
    
  228. // 5) It should be easy to port this to a C struct and keep a C implementation
    
  229. //    compatible.
    
  230. function createFiber(
    
  231.   tag: WorkTag,
    
  232.   pendingProps: mixed,
    
  233.   key: null | string,
    
  234.   mode: TypeOfMode,
    
  235. ): Fiber {
    
  236.   // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
    
  237.   return new FiberNode(tag, pendingProps, key, mode);
    
  238. }
    
  239. 
    
  240. function shouldConstruct(Component: Function) {
    
  241.   const prototype = Component.prototype;
    
  242.   return !!(prototype && prototype.isReactComponent);
    
  243. }
    
  244. 
    
  245. export function isSimpleFunctionComponent(type: any): boolean {
    
  246.   return (
    
  247.     typeof type === 'function' &&
    
  248.     !shouldConstruct(type) &&
    
  249.     type.defaultProps === undefined
    
  250.   );
    
  251. }
    
  252. 
    
  253. export function resolveLazyComponentTag(Component: Function): WorkTag {
    
  254.   if (typeof Component === 'function') {
    
  255.     return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
    
  256.   } else if (Component !== undefined && Component !== null) {
    
  257.     const $$typeof = Component.$$typeof;
    
  258.     if ($$typeof === REACT_FORWARD_REF_TYPE) {
    
  259.       return ForwardRef;
    
  260.     }
    
  261.     if ($$typeof === REACT_MEMO_TYPE) {
    
  262.       return MemoComponent;
    
  263.     }
    
  264.   }
    
  265.   return IndeterminateComponent;
    
  266. }
    
  267. 
    
  268. // This is used to create an alternate fiber to do work on.
    
  269. export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
    
  270.   let workInProgress = current.alternate;
    
  271.   if (workInProgress === null) {
    
  272.     // We use a double buffering pooling technique because we know that we'll
    
  273.     // only ever need at most two versions of a tree. We pool the "other" unused
    
  274.     // node that we're free to reuse. This is lazily created to avoid allocating
    
  275.     // extra objects for things that are never updated. It also allow us to
    
  276.     // reclaim the extra memory if needed.
    
  277.     workInProgress = createFiber(
    
  278.       current.tag,
    
  279.       pendingProps,
    
  280.       current.key,
    
  281.       current.mode,
    
  282.     );
    
  283.     workInProgress.elementType = current.elementType;
    
  284.     workInProgress.type = current.type;
    
  285.     workInProgress.stateNode = current.stateNode;
    
  286. 
    
  287.     if (__DEV__) {
    
  288.       // DEV-only fields
    
  289. 
    
  290.       workInProgress._debugSource = current._debugSource;
    
  291.       workInProgress._debugOwner = current._debugOwner;
    
  292.       workInProgress._debugHookTypes = current._debugHookTypes;
    
  293.     }
    
  294. 
    
  295.     workInProgress.alternate = current;
    
  296.     current.alternate = workInProgress;
    
  297.   } else {
    
  298.     workInProgress.pendingProps = pendingProps;
    
  299.     // Needed because Blocks store data on type.
    
  300.     workInProgress.type = current.type;
    
  301. 
    
  302.     // We already have an alternate.
    
  303.     // Reset the effect tag.
    
  304.     workInProgress.flags = NoFlags;
    
  305. 
    
  306.     // The effects are no longer valid.
    
  307.     workInProgress.subtreeFlags = NoFlags;
    
  308.     workInProgress.deletions = null;
    
  309. 
    
  310.     if (enableProfilerTimer) {
    
  311.       // We intentionally reset, rather than copy, actualDuration & actualStartTime.
    
  312.       // This prevents time from endlessly accumulating in new commits.
    
  313.       // This has the downside of resetting values for different priority renders,
    
  314.       // But works for yielding (the common case) and should support resuming.
    
  315.       workInProgress.actualDuration = 0;
    
  316.       workInProgress.actualStartTime = -1;
    
  317.     }
    
  318.   }
    
  319. 
    
  320.   // Reset all effects except static ones.
    
  321.   // Static effects are not specific to a render.
    
  322.   workInProgress.flags = current.flags & StaticMask;
    
  323.   workInProgress.childLanes = current.childLanes;
    
  324.   workInProgress.lanes = current.lanes;
    
  325. 
    
  326.   workInProgress.child = current.child;
    
  327.   workInProgress.memoizedProps = current.memoizedProps;
    
  328.   workInProgress.memoizedState = current.memoizedState;
    
  329.   workInProgress.updateQueue = current.updateQueue;
    
  330. 
    
  331.   // Clone the dependencies object. This is mutated during the render phase, so
    
  332.   // it cannot be shared with the current fiber.
    
  333.   const currentDependencies = current.dependencies;
    
  334.   workInProgress.dependencies =
    
  335.     currentDependencies === null
    
  336.       ? null
    
  337.       : {
    
  338.           lanes: currentDependencies.lanes,
    
  339.           firstContext: currentDependencies.firstContext,
    
  340.         };
    
  341. 
    
  342.   // These will be overridden during the parent's reconciliation
    
  343.   workInProgress.sibling = current.sibling;
    
  344.   workInProgress.index = current.index;
    
  345.   workInProgress.ref = current.ref;
    
  346.   workInProgress.refCleanup = current.refCleanup;
    
  347. 
    
  348.   if (enableProfilerTimer) {
    
  349.     workInProgress.selfBaseDuration = current.selfBaseDuration;
    
  350.     workInProgress.treeBaseDuration = current.treeBaseDuration;
    
  351.   }
    
  352. 
    
  353.   if (__DEV__) {
    
  354.     workInProgress._debugNeedsRemount = current._debugNeedsRemount;
    
  355.     switch (workInProgress.tag) {
    
  356.       case IndeterminateComponent:
    
  357.       case FunctionComponent:
    
  358.       case SimpleMemoComponent:
    
  359.         workInProgress.type = resolveFunctionForHotReloading(current.type);
    
  360.         break;
    
  361.       case ClassComponent:
    
  362.         workInProgress.type = resolveClassForHotReloading(current.type);
    
  363.         break;
    
  364.       case ForwardRef:
    
  365.         workInProgress.type = resolveForwardRefForHotReloading(current.type);
    
  366.         break;
    
  367.       default:
    
  368.         break;
    
  369.     }
    
  370.   }
    
  371. 
    
  372.   return workInProgress;
    
  373. }
    
  374. 
    
  375. // Used to reuse a Fiber for a second pass.
    
  376. export function resetWorkInProgress(
    
  377.   workInProgress: Fiber,
    
  378.   renderLanes: Lanes,
    
  379. ): Fiber {
    
  380.   // This resets the Fiber to what createFiber or createWorkInProgress would
    
  381.   // have set the values to before during the first pass. Ideally this wouldn't
    
  382.   // be necessary but unfortunately many code paths reads from the workInProgress
    
  383.   // when they should be reading from current and writing to workInProgress.
    
  384. 
    
  385.   // We assume pendingProps, index, key, ref, return are still untouched to
    
  386.   // avoid doing another reconciliation.
    
  387. 
    
  388.   // Reset the effect flags but keep any Placement tags, since that's something
    
  389.   // that child fiber is setting, not the reconciliation.
    
  390.   workInProgress.flags &= StaticMask | Placement;
    
  391. 
    
  392.   // The effects are no longer valid.
    
  393. 
    
  394.   const current = workInProgress.alternate;
    
  395.   if (current === null) {
    
  396.     // Reset to createFiber's initial values.
    
  397.     workInProgress.childLanes = NoLanes;
    
  398.     workInProgress.lanes = renderLanes;
    
  399. 
    
  400.     workInProgress.child = null;
    
  401.     workInProgress.subtreeFlags = NoFlags;
    
  402.     workInProgress.memoizedProps = null;
    
  403.     workInProgress.memoizedState = null;
    
  404.     workInProgress.updateQueue = null;
    
  405. 
    
  406.     workInProgress.dependencies = null;
    
  407. 
    
  408.     workInProgress.stateNode = null;
    
  409. 
    
  410.     if (enableProfilerTimer) {
    
  411.       // Note: We don't reset the actualTime counts. It's useful to accumulate
    
  412.       // actual time across multiple render passes.
    
  413.       workInProgress.selfBaseDuration = 0;
    
  414.       workInProgress.treeBaseDuration = 0;
    
  415.     }
    
  416.   } else {
    
  417.     // Reset to the cloned values that createWorkInProgress would've.
    
  418.     workInProgress.childLanes = current.childLanes;
    
  419.     workInProgress.lanes = current.lanes;
    
  420. 
    
  421.     workInProgress.child = current.child;
    
  422.     workInProgress.subtreeFlags = NoFlags;
    
  423.     workInProgress.deletions = null;
    
  424.     workInProgress.memoizedProps = current.memoizedProps;
    
  425.     workInProgress.memoizedState = current.memoizedState;
    
  426.     workInProgress.updateQueue = current.updateQueue;
    
  427.     // Needed because Blocks store data on type.
    
  428.     workInProgress.type = current.type;
    
  429. 
    
  430.     // Clone the dependencies object. This is mutated during the render phase, so
    
  431.     // it cannot be shared with the current fiber.
    
  432.     const currentDependencies = current.dependencies;
    
  433.     workInProgress.dependencies =
    
  434.       currentDependencies === null
    
  435.         ? null
    
  436.         : {
    
  437.             lanes: currentDependencies.lanes,
    
  438.             firstContext: currentDependencies.firstContext,
    
  439.           };
    
  440. 
    
  441.     if (enableProfilerTimer) {
    
  442.       // Note: We don't reset the actualTime counts. It's useful to accumulate
    
  443.       // actual time across multiple render passes.
    
  444.       workInProgress.selfBaseDuration = current.selfBaseDuration;
    
  445.       workInProgress.treeBaseDuration = current.treeBaseDuration;
    
  446.     }
    
  447.   }
    
  448. 
    
  449.   return workInProgress;
    
  450. }
    
  451. 
    
  452. export function createHostRootFiber(
    
  453.   tag: RootTag,
    
  454.   isStrictMode: boolean,
    
  455.   concurrentUpdatesByDefaultOverride: null | boolean,
    
  456. ): Fiber {
    
  457.   let mode;
    
  458.   if (tag === ConcurrentRoot) {
    
  459.     mode = ConcurrentMode;
    
  460.     if (isStrictMode === true || createRootStrictEffectsByDefault) {
    
  461.       mode |= StrictLegacyMode | StrictEffectsMode;
    
  462.     }
    
  463.     if (
    
  464.       // We only use this flag for our repo tests to check both behaviors.
    
  465.       forceConcurrentByDefaultForTesting
    
  466.     ) {
    
  467.       mode |= ConcurrentUpdatesByDefaultMode;
    
  468.     } else if (
    
  469.       // Only for internal experiments.
    
  470.       allowConcurrentByDefault &&
    
  471.       concurrentUpdatesByDefaultOverride
    
  472.     ) {
    
  473.       mode |= ConcurrentUpdatesByDefaultMode;
    
  474.     }
    
  475.   } else {
    
  476.     mode = NoMode;
    
  477.   }
    
  478. 
    
  479.   if (enableProfilerTimer && isDevToolsPresent) {
    
  480.     // Always collect profile timings when DevTools are present.
    
  481.     // This enables DevTools to start capturing timing at any point–
    
  482.     // Without some nodes in the tree having empty base times.
    
  483.     mode |= ProfileMode;
    
  484.   }
    
  485. 
    
  486.   return createFiber(HostRoot, null, null, mode);
    
  487. }
    
  488. 
    
  489. export function createFiberFromTypeAndProps(
    
  490.   type: any, // React$ElementType
    
  491.   key: null | string,
    
  492.   pendingProps: any,
    
  493.   source: null | Source,
    
  494.   owner: null | Fiber,
    
  495.   mode: TypeOfMode,
    
  496.   lanes: Lanes,
    
  497. ): Fiber {
    
  498.   let fiberTag = IndeterminateComponent;
    
  499.   // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
    
  500.   let resolvedType = type;
    
  501.   if (typeof type === 'function') {
    
  502.     if (shouldConstruct(type)) {
    
  503.       fiberTag = ClassComponent;
    
  504.       if (__DEV__) {
    
  505.         resolvedType = resolveClassForHotReloading(resolvedType);
    
  506.       }
    
  507.     } else {
    
  508.       if (__DEV__) {
    
  509.         resolvedType = resolveFunctionForHotReloading(resolvedType);
    
  510.       }
    
  511.     }
    
  512.   } else if (typeof type === 'string') {
    
  513.     if (
    
  514.       enableFloat &&
    
  515.       supportsResources &&
    
  516.       enableHostSingletons &&
    
  517.       supportsSingletons
    
  518.     ) {
    
  519.       const hostContext = getHostContext();
    
  520.       fiberTag = isHostHoistableType(type, pendingProps, hostContext)
    
  521.         ? HostHoistable
    
  522.         : isHostSingletonType(type)
    
  523.         ? HostSingleton
    
  524.         : HostComponent;
    
  525.     } else if (enableFloat && supportsResources) {
    
  526.       const hostContext = getHostContext();
    
  527.       fiberTag = isHostHoistableType(type, pendingProps, hostContext)
    
  528.         ? HostHoistable
    
  529.         : HostComponent;
    
  530.     } else if (enableHostSingletons && supportsSingletons) {
    
  531.       fiberTag = isHostSingletonType(type) ? HostSingleton : HostComponent;
    
  532.     } else {
    
  533.       fiberTag = HostComponent;
    
  534.     }
    
  535.   } else {
    
  536.     getTag: switch (type) {
    
  537.       case REACT_FRAGMENT_TYPE:
    
  538.         return createFiberFromFragment(pendingProps.children, mode, lanes, key);
    
  539.       case REACT_STRICT_MODE_TYPE:
    
  540.         fiberTag = Mode;
    
  541.         mode |= StrictLegacyMode;
    
  542.         if ((mode & ConcurrentMode) !== NoMode) {
    
  543.           // Strict effects should never run on legacy roots
    
  544.           mode |= StrictEffectsMode;
    
  545.           if (
    
  546.             enableDO_NOT_USE_disableStrictPassiveEffect &&
    
  547.             pendingProps.DO_NOT_USE_disableStrictPassiveEffect
    
  548.           ) {
    
  549.             mode |= NoStrictPassiveEffectsMode;
    
  550.           }
    
  551.         }
    
  552.         break;
    
  553.       case REACT_PROFILER_TYPE:
    
  554.         return createFiberFromProfiler(pendingProps, mode, lanes, key);
    
  555.       case REACT_SUSPENSE_TYPE:
    
  556.         return createFiberFromSuspense(pendingProps, mode, lanes, key);
    
  557.       case REACT_SUSPENSE_LIST_TYPE:
    
  558.         return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
    
  559.       case REACT_OFFSCREEN_TYPE:
    
  560.         return createFiberFromOffscreen(pendingProps, mode, lanes, key);
    
  561.       case REACT_LEGACY_HIDDEN_TYPE:
    
  562.         if (enableLegacyHidden) {
    
  563.           return createFiberFromLegacyHidden(pendingProps, mode, lanes, key);
    
  564.         }
    
  565.       // Fall through
    
  566.       case REACT_SCOPE_TYPE:
    
  567.         if (enableScopeAPI) {
    
  568.           return createFiberFromScope(type, pendingProps, mode, lanes, key);
    
  569.         }
    
  570.       // Fall through
    
  571.       case REACT_CACHE_TYPE:
    
  572.         if (enableCache) {
    
  573.           return createFiberFromCache(pendingProps, mode, lanes, key);
    
  574.         }
    
  575.       // Fall through
    
  576.       case REACT_TRACING_MARKER_TYPE:
    
  577.         if (enableTransitionTracing) {
    
  578.           return createFiberFromTracingMarker(pendingProps, mode, lanes, key);
    
  579.         }
    
  580.       // Fall through
    
  581.       case REACT_DEBUG_TRACING_MODE_TYPE:
    
  582.         if (enableDebugTracing) {
    
  583.           fiberTag = Mode;
    
  584.           mode |= DebugTracingMode;
    
  585.           break;
    
  586.         }
    
  587.       // Fall through
    
  588.       default: {
    
  589.         if (typeof type === 'object' && type !== null) {
    
  590.           switch (type.$$typeof) {
    
  591.             case REACT_PROVIDER_TYPE:
    
  592.               fiberTag = ContextProvider;
    
  593.               break getTag;
    
  594.             case REACT_CONTEXT_TYPE:
    
  595.               // This is a consumer
    
  596.               fiberTag = ContextConsumer;
    
  597.               break getTag;
    
  598.             case REACT_FORWARD_REF_TYPE:
    
  599.               fiberTag = ForwardRef;
    
  600.               if (__DEV__) {
    
  601.                 resolvedType = resolveForwardRefForHotReloading(resolvedType);
    
  602.               }
    
  603.               break getTag;
    
  604.             case REACT_MEMO_TYPE:
    
  605.               fiberTag = MemoComponent;
    
  606.               break getTag;
    
  607.             case REACT_LAZY_TYPE:
    
  608.               fiberTag = LazyComponent;
    
  609.               resolvedType = null;
    
  610.               break getTag;
    
  611.           }
    
  612.         }
    
  613.         let info = '';
    
  614.         if (__DEV__) {
    
  615.           if (
    
  616.             type === undefined ||
    
  617.             (typeof type === 'object' &&
    
  618.               type !== null &&
    
  619.               Object.keys(type).length === 0)
    
  620.           ) {
    
  621.             info +=
    
  622.               ' You likely forgot to export your component from the file ' +
    
  623.               "it's defined in, or you might have mixed up default and " +
    
  624.               'named imports.';
    
  625.           }
    
  626.           const ownerName = owner ? getComponentNameFromFiber(owner) : null;
    
  627.           if (ownerName) {
    
  628.             info += '\n\nCheck the render method of `' + ownerName + '`.';
    
  629.           }
    
  630.         }
    
  631. 
    
  632.         throw new Error(
    
  633.           'Element type is invalid: expected a string (for built-in ' +
    
  634.             'components) or a class/function (for composite components) ' +
    
  635.             `but got: ${type == null ? type : typeof type}.${info}`,
    
  636.         );
    
  637.       }
    
  638.     }
    
  639.   }
    
  640. 
    
  641.   const fiber = createFiber(fiberTag, pendingProps, key, mode);
    
  642.   fiber.elementType = type;
    
  643.   fiber.type = resolvedType;
    
  644.   fiber.lanes = lanes;
    
  645. 
    
  646.   if (__DEV__) {
    
  647.     fiber._debugSource = source;
    
  648.     fiber._debugOwner = owner;
    
  649.   }
    
  650. 
    
  651.   return fiber;
    
  652. }
    
  653. 
    
  654. export function createFiberFromElement(
    
  655.   element: ReactElement,
    
  656.   mode: TypeOfMode,
    
  657.   lanes: Lanes,
    
  658. ): Fiber {
    
  659.   let source = null;
    
  660.   let owner = null;
    
  661.   if (__DEV__) {
    
  662.     source = element._source;
    
  663.     owner = element._owner;
    
  664.   }
    
  665.   const type = element.type;
    
  666.   const key = element.key;
    
  667.   const pendingProps = element.props;
    
  668.   const fiber = createFiberFromTypeAndProps(
    
  669.     type,
    
  670.     key,
    
  671.     pendingProps,
    
  672.     source,
    
  673.     owner,
    
  674.     mode,
    
  675.     lanes,
    
  676.   );
    
  677.   if (__DEV__) {
    
  678.     fiber._debugSource = element._source;
    
  679.     fiber._debugOwner = element._owner;
    
  680.   }
    
  681.   return fiber;
    
  682. }
    
  683. 
    
  684. export function createFiberFromFragment(
    
  685.   elements: ReactFragment,
    
  686.   mode: TypeOfMode,
    
  687.   lanes: Lanes,
    
  688.   key: null | string,
    
  689. ): Fiber {
    
  690.   const fiber = createFiber(Fragment, elements, key, mode);
    
  691.   fiber.lanes = lanes;
    
  692.   return fiber;
    
  693. }
    
  694. 
    
  695. function createFiberFromScope(
    
  696.   scope: ReactScope,
    
  697.   pendingProps: any,
    
  698.   mode: TypeOfMode,
    
  699.   lanes: Lanes,
    
  700.   key: null | string,
    
  701. ) {
    
  702.   const fiber = createFiber(ScopeComponent, pendingProps, key, mode);
    
  703.   fiber.type = scope;
    
  704.   fiber.elementType = scope;
    
  705.   fiber.lanes = lanes;
    
  706.   return fiber;
    
  707. }
    
  708. 
    
  709. function createFiberFromProfiler(
    
  710.   pendingProps: any,
    
  711.   mode: TypeOfMode,
    
  712.   lanes: Lanes,
    
  713.   key: null | string,
    
  714. ): Fiber {
    
  715.   if (__DEV__) {
    
  716.     if (typeof pendingProps.id !== 'string') {
    
  717.       console.error(
    
  718.         'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.',
    
  719.         typeof pendingProps.id,
    
  720.       );
    
  721.     }
    
  722.   }
    
  723. 
    
  724.   const fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
    
  725.   fiber.elementType = REACT_PROFILER_TYPE;
    
  726.   fiber.lanes = lanes;
    
  727. 
    
  728.   if (enableProfilerTimer) {
    
  729.     fiber.stateNode = {
    
  730.       effectDuration: 0,
    
  731.       passiveEffectDuration: 0,
    
  732.     };
    
  733.   }
    
  734. 
    
  735.   return fiber;
    
  736. }
    
  737. 
    
  738. export function createFiberFromSuspense(
    
  739.   pendingProps: any,
    
  740.   mode: TypeOfMode,
    
  741.   lanes: Lanes,
    
  742.   key: null | string,
    
  743. ): Fiber {
    
  744.   const fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
    
  745.   fiber.elementType = REACT_SUSPENSE_TYPE;
    
  746.   fiber.lanes = lanes;
    
  747.   return fiber;
    
  748. }
    
  749. 
    
  750. export function createFiberFromSuspenseList(
    
  751.   pendingProps: any,
    
  752.   mode: TypeOfMode,
    
  753.   lanes: Lanes,
    
  754.   key: null | string,
    
  755. ): Fiber {
    
  756.   const fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
    
  757.   fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
    
  758.   fiber.lanes = lanes;
    
  759.   return fiber;
    
  760. }
    
  761. 
    
  762. export function createFiberFromOffscreen(
    
  763.   pendingProps: OffscreenProps,
    
  764.   mode: TypeOfMode,
    
  765.   lanes: Lanes,
    
  766.   key: null | string,
    
  767. ): Fiber {
    
  768.   const fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
    
  769.   fiber.elementType = REACT_OFFSCREEN_TYPE;
    
  770.   fiber.lanes = lanes;
    
  771.   const primaryChildInstance: OffscreenInstance = {
    
  772.     _visibility: OffscreenVisible,
    
  773.     _pendingVisibility: OffscreenVisible,
    
  774.     _pendingMarkers: null,
    
  775.     _retryCache: null,
    
  776.     _transitions: null,
    
  777.     _current: null,
    
  778.     detach: () => detachOffscreenInstance(primaryChildInstance),
    
  779.     attach: () => attachOffscreenInstance(primaryChildInstance),
    
  780.   };
    
  781.   fiber.stateNode = primaryChildInstance;
    
  782.   return fiber;
    
  783. }
    
  784. 
    
  785. export function createFiberFromLegacyHidden(
    
  786.   pendingProps: OffscreenProps,
    
  787.   mode: TypeOfMode,
    
  788.   lanes: Lanes,
    
  789.   key: null | string,
    
  790. ): Fiber {
    
  791.   const fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode);
    
  792.   fiber.elementType = REACT_LEGACY_HIDDEN_TYPE;
    
  793.   fiber.lanes = lanes;
    
  794.   // Adding a stateNode for legacy hidden because it's currently using
    
  795.   // the offscreen implementation, which depends on a state node
    
  796.   const instance: OffscreenInstance = {
    
  797.     _visibility: OffscreenVisible,
    
  798.     _pendingVisibility: OffscreenVisible,
    
  799.     _pendingMarkers: null,
    
  800.     _transitions: null,
    
  801.     _retryCache: null,
    
  802.     _current: null,
    
  803.     detach: () => detachOffscreenInstance(instance),
    
  804.     attach: () => attachOffscreenInstance(instance),
    
  805.   };
    
  806.   fiber.stateNode = instance;
    
  807.   return fiber;
    
  808. }
    
  809. 
    
  810. export function createFiberFromCache(
    
  811.   pendingProps: any,
    
  812.   mode: TypeOfMode,
    
  813.   lanes: Lanes,
    
  814.   key: null | string,
    
  815. ): Fiber {
    
  816.   const fiber = createFiber(CacheComponent, pendingProps, key, mode);
    
  817.   fiber.elementType = REACT_CACHE_TYPE;
    
  818.   fiber.lanes = lanes;
    
  819.   return fiber;
    
  820. }
    
  821. 
    
  822. export function createFiberFromTracingMarker(
    
  823.   pendingProps: any,
    
  824.   mode: TypeOfMode,
    
  825.   lanes: Lanes,
    
  826.   key: null | string,
    
  827. ): Fiber {
    
  828.   const fiber = createFiber(TracingMarkerComponent, pendingProps, key, mode);
    
  829.   fiber.elementType = REACT_TRACING_MARKER_TYPE;
    
  830.   fiber.lanes = lanes;
    
  831.   const tracingMarkerInstance: TracingMarkerInstance = {
    
  832.     tag: TransitionTracingMarker,
    
  833.     transitions: null,
    
  834.     pendingBoundaries: null,
    
  835.     aborts: null,
    
  836.     name: pendingProps.name,
    
  837.   };
    
  838.   fiber.stateNode = tracingMarkerInstance;
    
  839.   return fiber;
    
  840. }
    
  841. 
    
  842. export function createFiberFromText(
    
  843.   content: string,
    
  844.   mode: TypeOfMode,
    
  845.   lanes: Lanes,
    
  846. ): Fiber {
    
  847.   const fiber = createFiber(HostText, content, null, mode);
    
  848.   fiber.lanes = lanes;
    
  849.   return fiber;
    
  850. }
    
  851. 
    
  852. export function createFiberFromHostInstanceForDeletion(): Fiber {
    
  853.   const fiber = createFiber(HostComponent, null, null, NoMode);
    
  854.   fiber.elementType = 'DELETED';
    
  855.   return fiber;
    
  856. }
    
  857. 
    
  858. export function createFiberFromDehydratedFragment(
    
  859.   dehydratedNode: SuspenseInstance,
    
  860. ): Fiber {
    
  861.   const fiber = createFiber(DehydratedFragment, null, null, NoMode);
    
  862.   fiber.stateNode = dehydratedNode;
    
  863.   return fiber;
    
  864. }
    
  865. 
    
  866. export function createFiberFromPortal(
    
  867.   portal: ReactPortal,
    
  868.   mode: TypeOfMode,
    
  869.   lanes: Lanes,
    
  870. ): Fiber {
    
  871.   const pendingProps = portal.children !== null ? portal.children : [];
    
  872.   const fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
    
  873.   fiber.lanes = lanes;
    
  874.   fiber.stateNode = {
    
  875.     containerInfo: portal.containerInfo,
    
  876.     pendingChildren: null, // Used by persistent updates
    
  877.     implementation: portal.implementation,
    
  878.   };
    
  879.   return fiber;
    
  880. }
    
  881. 
    
  882. // Used for stashing WIP properties to replay failed work in DEV.
    
  883. export function assignFiberPropertiesInDEV(
    
  884.   target: Fiber | null,
    
  885.   source: Fiber,
    
  886. ): Fiber {
    
  887.   if (target === null) {
    
  888.     // This Fiber's initial properties will always be overwritten.
    
  889.     // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
    
  890.     target = createFiber(IndeterminateComponent, null, null, NoMode);
    
  891.   }
    
  892. 
    
  893.   // This is intentionally written as a list of all properties.
    
  894.   // We tried to use Object.assign() instead but this is called in
    
  895.   // the hottest path, and Object.assign() was too slow:
    
  896.   // https://github.com/facebook/react/issues/12502
    
  897.   // This code is DEV-only so size is not a concern.
    
  898. 
    
  899.   target.tag = source.tag;
    
  900.   target.key = source.key;
    
  901.   target.elementType = source.elementType;
    
  902.   target.type = source.type;
    
  903.   target.stateNode = source.stateNode;
    
  904.   target.return = source.return;
    
  905.   target.child = source.child;
    
  906.   target.sibling = source.sibling;
    
  907.   target.index = source.index;
    
  908.   target.ref = source.ref;
    
  909.   target.refCleanup = source.refCleanup;
    
  910.   target.pendingProps = source.pendingProps;
    
  911.   target.memoizedProps = source.memoizedProps;
    
  912.   target.updateQueue = source.updateQueue;
    
  913.   target.memoizedState = source.memoizedState;
    
  914.   target.dependencies = source.dependencies;
    
  915.   target.mode = source.mode;
    
  916.   target.flags = source.flags;
    
  917.   target.subtreeFlags = source.subtreeFlags;
    
  918.   target.deletions = source.deletions;
    
  919.   target.lanes = source.lanes;
    
  920.   target.childLanes = source.childLanes;
    
  921.   target.alternate = source.alternate;
    
  922.   if (enableProfilerTimer) {
    
  923.     target.actualDuration = source.actualDuration;
    
  924.     target.actualStartTime = source.actualStartTime;
    
  925.     target.selfBaseDuration = source.selfBaseDuration;
    
  926.     target.treeBaseDuration = source.treeBaseDuration;
    
  927.   }
    
  928. 
    
  929.   target._debugSource = source._debugSource;
    
  930.   target._debugOwner = source._debugOwner;
    
  931.   target._debugNeedsRemount = source._debugNeedsRemount;
    
  932.   target._debugHookTypes = source._debugHookTypes;
    
  933.   return target;
    
  934. }