text: "use strict";
  
  module.exports = function({ types: t }) {
    return {
      name: "transform-comment-console",
      visitor: {
        CallExpression(path, state) {
          const callee = path.get("callee");
  
          if (!callee.isMemberExpression()) return;
  
          if (isIncludedConsole(callee, state.opts.exclude)) {
            // console.log()
            if (path.parentPath.isExpressionStatement()) {
              path.remove();
            } else {
              path.replaceWith(createVoid0());
            }
          } else if (isIncludedConsoleBind(callee, state.opts.exclude)) {
            // console.log.bind()
            path.replaceWith(createNoop());
          }
        },
        MemberExpression: {
          exit(path, state) {
            if (
              isIncludedConsole(path, state.opts.exclude) &&
              !path.parentPath.isMemberExpression()
            ) {
              if (
                path.parentPath.isAssignmentExpression() &&
                path.parentKey === "left"
              ) {
                path.parentPath.get("right").replaceWith(createNoop());
              } else {
                path.replaceWith(createNoop());
              }
            }
          }
        }
      }
    };
  
    function isGlobalConsoleId(id) {
      const name = "console";
      return (
        id.isIdentifier({ name }) &&
        !id.scope.getBinding(name) &&
        id.scope.hasGlobal(name)
      );
    }
  
    function isExcluded(property, excludeArray) {
      return (
        excludeArray && excludeArray.some(name => property.isIdentifier({ name }))
      );
    }
  
    function isIncludedConsole(memberExpr, excludeArray) {
      const object = memberExpr.get("object");
      const property = memberExpr.get("property");
  
      if (isExcluded(property, excludeArray)) return false;
  
      if (isGlobalConsoleId(object)) return true;
  
      return (
        isGlobalConsoleId(object.get("object")) &&
        (property.isIdentifier({ name: "call" }) ||
          property.isIdentifier({ name: "apply" }))
      );
    }
  
    function isIncludedConsoleBind(memberExpr, excludeArray) {
      const object = memberExpr.get("object");
  
      if (!object.isMemberExpression()) return false;
      if (isExcluded(object.get("property"), excludeArray)) return false;
  
      return (
        isGlobalConsoleId(object.get("object")) &&
        memberExpr.get("property").isIdentifier({ name: "bind" })
      );
    }
  
    function createNoop() {
      return t.functionExpression(null, [], t.blockStatement([]));
    }
  
    function createVoid0() {
      return t.unaryExpression("void", t.numericLiteral(0));
    }
  };
  