<commit_before>import { definitions } from "./built-in-definitions";

function isPolyfillSource(value) {
  return value === "babel-polyfill";
}

function warnOnInstanceMethod() {
  // state.opts.debug &&
  //   console.warn(
  //     `Adding a polyfill: An instance method may have been used: ${details}`,
  //   );
}

function has(obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key);
}

function getObjectString(node) {
  if (node.type === "Identifier") {
    return node.name;
  } else if (node.type === "MemberExpression") {
    return `${getObjectString(node.object)}.${getObjectString(node.property)}`;
  }
}

const modulePathMap = {
  "regenerator-runtime": "babel-polyfill/lib/regenerator-runtime/runtime",
};

const getModulePath = module => {
  return modulePathMap[module] ||
    `babel-polyfill/lib/core-js/modules/${module}`;
};

export default function({ types: t }) {
  function addImport(path, builtIn, builtIns) {
    if (builtIn && !builtIns.has(builtIn)) {
      builtIns.add(builtIn);

      const importDec = t.importDeclaration(
        [],
        t.stringLiteral(getModulePath(builtIn)),
      );

      importDec._blockHoist = 3;
      const programPath = path.find(path => path.isProgram());
      programPath.unshiftContainer("body", importDec);
    }
  }

  function addUnsupported(path, polyfills, builtIn, builtIns) {
    if (Array.isArray(builtIn)) {
      for (const i of builtIn) {
        if (polyfills.has(i)) {
          addImport(path, i, builtIns);
        }
      }
    } else {
      if (polyfills.has(builtIn)) {
        addImport(path, builtIn, builtIns);
      }
    }
  }

  function isRequire(path) {
    return t.isExpressionStatement(path.node) &&
      t.isCallExpression(path.node.expression) &&
      t.isIdentifier(path.node.expression.callee) &&
      path.node.expression.callee.name === "require" &&
      path.node.expression.arguments.length === 1 &&
      t.isStringLiteral(path.node.expression.arguments[0]) &&
      isPolyfillSource(path.node.expression.arguments[0].value);
  }

  const addAndRemovePolyfillImports = {
    ImportDeclaration(path) {
      if (
        path.node.specifiers.length === 0 &&
        isPolyfillSource(path.node.source.value)
      ) {
        console.warn(
          `
When setting "useBuiltIns: true", polyfills are automatically imported when needed.
Please remove the "import 'babel-polyfill'" call or use "useBuiltIns: 'entry'" instead.
`,
        );
        path.remove();
      }
    },
    Program: {
      enter(path) {
        path.get("body").forEach(bodyPath => {
          if (isRequire(bodyPath)) {
            console.warn(
              `
When setting "useBuiltIns: true", polyfills are automatically imported when needed.
Please remove the "require('babel-polyfill')" call or use "useBuiltIns: 'entry'" instead.
`,
            );
            bodyPath.remove();
          }
        });
      },
    },

    // Symbol()
    // new Promise
    ReferencedIdentifier(path, state) {
      const { node, parent, scope } = path;

      if (t.isMemberExpression(parent)) return;
      if (!has(definitions.builtins, node.name)) return;
      if (scope.getBindingIdentifier(node.name)) return;

      const builtIn = definitions.builtins[node.name];
      addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
    },<commit_msg>Update `useBuiltIns : true` warning. (#300)<commit_after>import { definitions } from "./built-in-definitions";

function isPolyfillSource(value) {
  return value === "babel-polyfill";
}

function warnOnInstanceMethod() {
  // state.opts.debug &&
  //   console.warn(
  //     `Adding a polyfill: An instance method may have been used: ${details}`,
  //   );
}

function has(obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key);
}

function getObjectString(node) {
  if (node.type === "Identifier") {
    return node.name;
  } else if (node.type === "MemberExpression") {
    return `${getObjectString(node.object)}.${getObjectString(node.property)}`;
  }
}

const modulePathMap = {
  "regenerator-runtime": "babel-polyfill/lib/regenerator-runtime/runtime",
};

const getModulePath = module => {
  return modulePathMap[module] ||
    `babel-polyfill/lib/core-js/modules/${module}`;
};

export default function({ types: t }) {
  function addImport(path, builtIn, builtIns) {
    if (builtIn && !builtIns.has(builtIn)) {
      builtIns.add(builtIn);

      const importDec = t.importDeclaration(
        [],
        t.stringLiteral(getModulePath(builtIn)),
      );

      importDec._blockHoist = 3;
      const programPath = path.find(path => path.isProgram());
      programPath.unshiftContainer("body", importDec);
    }
  }

  function addUnsupported(path, polyfills, builtIn, builtIns) {
    if (Array.isArray(builtIn)) {
      for (const i of builtIn) {
        if (polyfills.has(i)) {
          addImport(path, i, builtIns);
        }
      }
    } else {
      if (polyfills.has(builtIn)) {
        addImport(path, builtIn, builtIns);
      }
    }
  }

  function isRequire(path) {
    return t.isExpressionStatement(path.node) &&
      t.isCallExpression(path.node.expression) &&
      t.isIdentifier(path.node.expression.callee) &&
      path.node.expression.callee.name === "require" &&
      path.node.expression.arguments.length === 1 &&
      t.isStringLiteral(path.node.expression.arguments[0]) &&
      isPolyfillSource(path.node.expression.arguments[0].value);
  }

  const addAndRemovePolyfillImports = {
    ImportDeclaration(path) {
      if (
        path.node.specifiers.length === 0 &&
        isPolyfillSource(path.node.source.value)
      ) {
        console.warn(
          `
When setting \`useBuiltIns: 'usage'\`, polyfills are automatically imported when needed.
Please remove the \`import 'babel-polyfill'\` call or use \`useBuiltIns: 'entry'\` instead.
`,
        );
        path.remove();
      }
    },
    Program: {
      enter(path) {
        path.get("body").forEach(bodyPath => {
          if (isRequire(bodyPath)) {
            console.warn(
              `
When setting \`useBuiltIns: 'usage'\`, polyfills are automatically imported when needed.
Please remove the \`require('babel-polyfill')\` call or use \`useBuiltIns: 'entry'\` instead.
`,
            );
            bodyPath.remove();
          }
        });
      },
    },

    // Symbol()
    // new Promise
    ReferencedIdentifier(path, state) {
      const { node, parent, scope } = path;

      if (t.isMemberExpression(parent)) return;
      if (!has(definitions.builtins, node.name)) return;
      if (scope.getBindingIdentifier(node.name)) return;

      const builtIn = definitions.builtins[node.name];
      addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
    },
{'fraction_non_alphanumeric': 0.14380924170616113, 'fraction_numerical': 0.0019253554502369668, 'mean_word_length': 2.8174109666478238, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7388747', 'n_tokens_mistral': 2098, 'n_tokens_neox': 2056, 'n_words': 398}