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 {disableLegacyContext} from 'shared/ReactFeatureFlags';
    
  11. import getComponentNameFromType from 'shared/getComponentNameFromType';
    
  12. import checkPropTypes from 'shared/checkPropTypes';
    
  13. 
    
  14. let warnedAboutMissingGetChildContext;
    
  15. 
    
  16. if (__DEV__) {
    
  17.   warnedAboutMissingGetChildContext = ({}: {[string]: boolean});
    
  18. }
    
  19. 
    
  20. export const emptyContextObject: {} = {};
    
  21. if (__DEV__) {
    
  22.   Object.freeze(emptyContextObject);
    
  23. }
    
  24. 
    
  25. export function getMaskedContext(type: any, unmaskedContext: Object): Object {
    
  26.   if (disableLegacyContext) {
    
  27.     return emptyContextObject;
    
  28.   } else {
    
  29.     const contextTypes = type.contextTypes;
    
  30.     if (!contextTypes) {
    
  31.       return emptyContextObject;
    
  32.     }
    
  33. 
    
  34.     const context: {[string]: $FlowFixMe} = {};
    
  35.     for (const key in contextTypes) {
    
  36.       context[key] = unmaskedContext[key];
    
  37.     }
    
  38. 
    
  39.     if (__DEV__) {
    
  40.       const name = getComponentNameFromType(type) || 'Unknown';
    
  41.       checkPropTypes(contextTypes, context, 'context', name);
    
  42.     }
    
  43. 
    
  44.     return context;
    
  45.   }
    
  46. }
    
  47. 
    
  48. export function processChildContext(
    
  49.   instance: any,
    
  50.   type: any,
    
  51.   parentContext: Object,
    
  52.   childContextTypes: Object,
    
  53. ): Object {
    
  54.   if (disableLegacyContext) {
    
  55.     return parentContext;
    
  56.   } else {
    
  57.     // TODO (bvaughn) Replace this behavior with an invariant() in the future.
    
  58.     // It has only been added in Fiber to match the (unintentional) behavior in Stack.
    
  59.     if (typeof instance.getChildContext !== 'function') {
    
  60.       if (__DEV__) {
    
  61.         const componentName = getComponentNameFromType(type) || 'Unknown';
    
  62. 
    
  63.         if (!warnedAboutMissingGetChildContext[componentName]) {
    
  64.           warnedAboutMissingGetChildContext[componentName] = true;
    
  65.           console.error(
    
  66.             '%s.childContextTypes is specified but there is no getChildContext() method ' +
    
  67.               'on the instance. You can either define getChildContext() on %s or remove ' +
    
  68.               'childContextTypes from it.',
    
  69.             componentName,
    
  70.             componentName,
    
  71.           );
    
  72.         }
    
  73.       }
    
  74.       return parentContext;
    
  75.     }
    
  76. 
    
  77.     const childContext = instance.getChildContext();
    
  78.     for (const contextKey in childContext) {
    
  79.       if (!(contextKey in childContextTypes)) {
    
  80.         throw new Error(
    
  81.           `${
    
  82.             getComponentNameFromType(type) || 'Unknown'
    
  83.           }.getChildContext(): key "${contextKey}" is not defined in childContextTypes.`,
    
  84.         );
    
  85.       }
    
  86.     }
    
  87.     if (__DEV__) {
    
  88.       const name = getComponentNameFromType(type) || 'Unknown';
    
  89.       checkPropTypes(childContextTypes, childContext, 'child context', name);
    
  90.     }
    
  91. 
    
  92.     return {...parentContext, ...childContext};
    
  93.   }
    
  94. }