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 {LazyComponent} from 'react/src/ReactLazy';
    
  11. import type {ReactContext, ReactProviderType} from 'shared/ReactTypes';
    
  12. 
    
  13. import {
    
  14.   REACT_CONTEXT_TYPE,
    
  15.   REACT_FORWARD_REF_TYPE,
    
  16.   REACT_FRAGMENT_TYPE,
    
  17.   REACT_PORTAL_TYPE,
    
  18.   REACT_MEMO_TYPE,
    
  19.   REACT_PROFILER_TYPE,
    
  20.   REACT_PROVIDER_TYPE,
    
  21.   REACT_STRICT_MODE_TYPE,
    
  22.   REACT_SUSPENSE_TYPE,
    
  23.   REACT_SUSPENSE_LIST_TYPE,
    
  24.   REACT_LAZY_TYPE,
    
  25.   REACT_CACHE_TYPE,
    
  26.   REACT_TRACING_MARKER_TYPE,
    
  27.   REACT_SERVER_CONTEXT_TYPE,
    
  28. } from 'shared/ReactSymbols';
    
  29. 
    
  30. import {
    
  31.   enableServerContext,
    
  32.   enableTransitionTracing,
    
  33.   enableCache,
    
  34. } from './ReactFeatureFlags';
    
  35. 
    
  36. // Keep in sync with react-reconciler/getComponentNameFromFiber
    
  37. function getWrappedName(
    
  38.   outerType: mixed,
    
  39.   innerType: any,
    
  40.   wrapperName: string,
    
  41. ): string {
    
  42.   const displayName = (outerType: any).displayName;
    
  43.   if (displayName) {
    
  44.     return displayName;
    
  45.   }
    
  46.   const functionName = innerType.displayName || innerType.name || '';
    
  47.   return functionName !== '' ? `${wrapperName}(${functionName})` : wrapperName;
    
  48. }
    
  49. 
    
  50. // Keep in sync with react-reconciler/getComponentNameFromFiber
    
  51. function getContextName(type: ReactContext<any>) {
    
  52.   return type.displayName || 'Context';
    
  53. }
    
  54. 
    
  55. // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
    
  56. export default function getComponentNameFromType(type: mixed): string | null {
    
  57.   if (type == null) {
    
  58.     // Host root, text node or just invalid type.
    
  59.     return null;
    
  60.   }
    
  61.   if (__DEV__) {
    
  62.     if (typeof (type: any).tag === 'number') {
    
  63.       console.error(
    
  64.         'Received an unexpected object in getComponentNameFromType(). ' +
    
  65.           'This is likely a bug in React. Please file an issue.',
    
  66.       );
    
  67.     }
    
  68.   }
    
  69.   if (typeof type === 'function') {
    
  70.     return (type: any).displayName || type.name || null;
    
  71.   }
    
  72.   if (typeof type === 'string') {
    
  73.     return type;
    
  74.   }
    
  75.   switch (type) {
    
  76.     case REACT_FRAGMENT_TYPE:
    
  77.       return 'Fragment';
    
  78.     case REACT_PORTAL_TYPE:
    
  79.       return 'Portal';
    
  80.     case REACT_PROFILER_TYPE:
    
  81.       return 'Profiler';
    
  82.     case REACT_STRICT_MODE_TYPE:
    
  83.       return 'StrictMode';
    
  84.     case REACT_SUSPENSE_TYPE:
    
  85.       return 'Suspense';
    
  86.     case REACT_SUSPENSE_LIST_TYPE:
    
  87.       return 'SuspenseList';
    
  88.     case REACT_CACHE_TYPE:
    
  89.       if (enableCache) {
    
  90.         return 'Cache';
    
  91.       }
    
  92.     // Fall through
    
  93.     case REACT_TRACING_MARKER_TYPE:
    
  94.       if (enableTransitionTracing) {
    
  95.         return 'TracingMarker';
    
  96.       }
    
  97.   }
    
  98.   if (typeof type === 'object') {
    
  99.     switch (type.$$typeof) {
    
  100.       case REACT_CONTEXT_TYPE:
    
  101.         const context: ReactContext<any> = (type: any);
    
  102.         return getContextName(context) + '.Consumer';
    
  103.       case REACT_PROVIDER_TYPE:
    
  104.         const provider: ReactProviderType<any> = (type: any);
    
  105.         return getContextName(provider._context) + '.Provider';
    
  106.       case REACT_FORWARD_REF_TYPE:
    
  107.         return getWrappedName(type, type.render, 'ForwardRef');
    
  108.       case REACT_MEMO_TYPE:
    
  109.         const outerName = (type: any).displayName || null;
    
  110.         if (outerName !== null) {
    
  111.           return outerName;
    
  112.         }
    
  113.         return getComponentNameFromType(type.type) || 'Memo';
    
  114.       case REACT_LAZY_TYPE: {
    
  115.         const lazyComponent: LazyComponent<any, any> = (type: any);
    
  116.         const payload = lazyComponent._payload;
    
  117.         const init = lazyComponent._init;
    
  118.         try {
    
  119.           return getComponentNameFromType(init(payload));
    
  120.         } catch (x) {
    
  121.           return null;
    
  122.         }
    
  123.       }
    
  124.       case REACT_SERVER_CONTEXT_TYPE:
    
  125.         if (enableServerContext) {
    
  126.           const context2 = ((type: any): ReactContext<any>);
    
  127.           return (context2.displayName || context2._globalName) + '.Provider';
    
  128.         }
    
  129.     }
    
  130.   }
    
  131.   return null;
    
  132. }