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. 'use strict';
    
  8. 
    
  9. const helperModuleImports = require('@babel/helper-module-imports');
    
  10. 
    
  11. module.exports = function replaceConsoleCalls(babel) {
    
  12.   let consoleErrors = new WeakMap();
    
  13.   function getConsoleError(path, file) {
    
  14.     if (!consoleErrors.has(file)) {
    
  15.       consoleErrors.set(
    
  16.         file,
    
  17.         helperModuleImports.addNamed(
    
  18.           path,
    
  19.           'error',
    
  20.           'shared/consoleWithStackDev',
    
  21.           {nameHint: 'consoleError'}
    
  22.         )
    
  23.       );
    
  24.     }
    
  25.     return babel.types.cloneDeep(consoleErrors.get(file));
    
  26.   }
    
  27. 
    
  28.   let consoleWarns = new WeakMap();
    
  29.   function getConsoleWarn(path, file) {
    
  30.     if (!consoleWarns.has(file)) {
    
  31.       consoleWarns.set(
    
  32.         file,
    
  33.         helperModuleImports.addNamed(
    
  34.           path,
    
  35.           'warn',
    
  36.           'shared/consoleWithStackDev',
    
  37.           {nameHint: 'consoleWarn'}
    
  38.         )
    
  39.       );
    
  40.     }
    
  41.     return babel.types.cloneDeep(consoleWarns.get(file));
    
  42.   }
    
  43. 
    
  44.   return {
    
  45.     visitor: {
    
  46.       CallExpression: function (path, pass) {
    
  47.         if (path.node.callee.type !== 'MemberExpression') {
    
  48.           return;
    
  49.         }
    
  50.         if (path.node.callee.property.type !== 'Identifier') {
    
  51.           // Don't process calls like console['error'](...)
    
  52.           // because they serve as an escape hatch.
    
  53.           return;
    
  54.         }
    
  55.         if (path.get('callee').matchesPattern('console.error')) {
    
  56.           if (this.opts.shouldError) {
    
  57.             throw path.buildCodeFrameError(
    
  58.               "This module has no access to the React object, so it can't " +
    
  59.                 'use console.error() with automatically appended stack. ' +
    
  60.                 "As a workaround, you can use console['error'] which won't " +
    
  61.                 'be transformed.'
    
  62.             );
    
  63.           }
    
  64.           const id = getConsoleError(path, pass.file);
    
  65.           path.node.callee = id;
    
  66.         }
    
  67.         if (path.get('callee').matchesPattern('console.warn')) {
    
  68.           if (this.opts.shouldError) {
    
  69.             throw path.buildCodeFrameError(
    
  70.               "This module has no access to the React object, so it can't " +
    
  71.                 'use console.warn() with automatically appended stack. ' +
    
  72.                 "As a workaround, you can use console['warn'] which won't " +
    
  73.                 'be transformed.'
    
  74.             );
    
  75.           }
    
  76.           const id = getConsoleWarn(path, pass.file);
    
  77.           path.node.callee = id;
    
  78.         }
    
  79.       },
    
  80.     },
    
  81.   };
    
  82. };