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 {ReactContext, ReactProviderType} from 'shared/ReactTypes';
    
  11. import type {Fiber} from './ReactInternalTypes';
    
  12. 
    
  13. import {enableLegacyHidden} from 'shared/ReactFeatureFlags';
    
  14. 
    
  15. import {
    
  16.   FunctionComponent,
    
  17.   ClassComponent,
    
  18.   IndeterminateComponent,
    
  19.   HostRoot,
    
  20.   HostPortal,
    
  21.   HostComponent,
    
  22.   HostHoistable,
    
  23.   HostSingleton,
    
  24.   HostText,
    
  25.   Fragment,
    
  26.   Mode,
    
  27.   ContextConsumer,
    
  28.   ContextProvider,
    
  29.   ForwardRef,
    
  30.   Profiler,
    
  31.   SuspenseComponent,
    
  32.   MemoComponent,
    
  33.   SimpleMemoComponent,
    
  34.   LazyComponent,
    
  35.   IncompleteClassComponent,
    
  36.   DehydratedFragment,
    
  37.   SuspenseListComponent,
    
  38.   ScopeComponent,
    
  39.   OffscreenComponent,
    
  40.   LegacyHiddenComponent,
    
  41.   CacheComponent,
    
  42.   TracingMarkerComponent,
    
  43. } from 'react-reconciler/src/ReactWorkTags';
    
  44. import getComponentNameFromType from 'shared/getComponentNameFromType';
    
  45. import {REACT_STRICT_MODE_TYPE} from 'shared/ReactSymbols';
    
  46. 
    
  47. // Keep in sync with shared/getComponentNameFromType
    
  48. function getWrappedName(
    
  49.   outerType: mixed,
    
  50.   innerType: any,
    
  51.   wrapperName: string,
    
  52. ): string {
    
  53.   const functionName = innerType.displayName || innerType.name || '';
    
  54.   return (
    
  55.     (outerType: any).displayName ||
    
  56.     (functionName !== '' ? `${wrapperName}(${functionName})` : wrapperName)
    
  57.   );
    
  58. }
    
  59. 
    
  60. // Keep in sync with shared/getComponentNameFromType
    
  61. function getContextName(type: ReactContext<any>) {
    
  62.   return type.displayName || 'Context';
    
  63. }
    
  64. 
    
  65. export default function getComponentNameFromFiber(fiber: Fiber): string | null {
    
  66.   const {tag, type} = fiber;
    
  67.   switch (tag) {
    
  68.     case CacheComponent:
    
  69.       return 'Cache';
    
  70.     case ContextConsumer:
    
  71.       const context: ReactContext<any> = (type: any);
    
  72.       return getContextName(context) + '.Consumer';
    
  73.     case ContextProvider:
    
  74.       const provider: ReactProviderType<any> = (type: any);
    
  75.       return getContextName(provider._context) + '.Provider';
    
  76.     case DehydratedFragment:
    
  77.       return 'DehydratedFragment';
    
  78.     case ForwardRef:
    
  79.       return getWrappedName(type, type.render, 'ForwardRef');
    
  80.     case Fragment:
    
  81.       return 'Fragment';
    
  82.     case HostHoistable:
    
  83.     case HostSingleton:
    
  84.     case HostComponent:
    
  85.       // Host component type is the display name (e.g. "div", "View")
    
  86.       return type;
    
  87.     case HostPortal:
    
  88.       return 'Portal';
    
  89.     case HostRoot:
    
  90.       return 'Root';
    
  91.     case HostText:
    
  92.       return 'Text';
    
  93.     case LazyComponent:
    
  94.       // Name comes from the type in this case; we don't have a tag.
    
  95.       return getComponentNameFromType(type);
    
  96.     case Mode:
    
  97.       if (type === REACT_STRICT_MODE_TYPE) {
    
  98.         // Don't be less specific than shared/getComponentNameFromType
    
  99.         return 'StrictMode';
    
  100.       }
    
  101.       return 'Mode';
    
  102.     case OffscreenComponent:
    
  103.       return 'Offscreen';
    
  104.     case Profiler:
    
  105.       return 'Profiler';
    
  106.     case ScopeComponent:
    
  107.       return 'Scope';
    
  108.     case SuspenseComponent:
    
  109.       return 'Suspense';
    
  110.     case SuspenseListComponent:
    
  111.       return 'SuspenseList';
    
  112.     case TracingMarkerComponent:
    
  113.       return 'TracingMarker';
    
  114.     // The display name for this tags come from the user-provided type:
    
  115.     case ClassComponent:
    
  116.     case FunctionComponent:
    
  117.     case IncompleteClassComponent:
    
  118.     case IndeterminateComponent:
    
  119.     case MemoComponent:
    
  120.     case SimpleMemoComponent:
    
  121.       if (typeof type === 'function') {
    
  122.         return (type: any).displayName || type.name || null;
    
  123.       }
    
  124.       if (typeof type === 'string') {
    
  125.         return type;
    
  126.       }
    
  127.       break;
    
  128.     case LegacyHiddenComponent:
    
  129.       if (enableLegacyHidden) {
    
  130.         return 'LegacyHidden';
    
  131.       }
    
  132.   }
    
  133. 
    
  134.   return null;
    
  135. }