123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = _default;
- var _builtInDefinitions = require("./built-in-definitions");
- var _debug = require("./debug");
- var _utils = require("./utils");
- function has(obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key);
- }
- function getType(target) {
- if (Array.isArray(target)) return "array";
- return typeof target;
- }
- function _default({
- types: t
- }) {
- function addImport(path, builtIn, builtIns) {
- if (builtIn && !builtIns.has(builtIn)) {
- builtIns.add(builtIn);
- (0, _utils.createImport)(path, builtIn);
- }
- }
- 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);
- }
- }
- }
- const addAndRemovePolyfillImports = {
- ImportDeclaration(path) {
- if (path.node.specifiers.length === 0 && (0, _utils.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 ((0, _utils.isRequire)(t, 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();
- }
- });
- }
- },
- ReferencedIdentifier(path, state) {
- const {
- node,
- parent,
- scope
- } = path;
- if (t.isMemberExpression(parent)) return;
- if (!has(_builtInDefinitions.definitions.builtins, node.name)) return;
- if (scope.getBindingIdentifier(node.name)) return;
- const builtIn = _builtInDefinitions.definitions.builtins[node.name];
- addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
- },
- CallExpression(path) {
- if (path.node.arguments.length) return;
- const callee = path.node.callee;
- if (!t.isMemberExpression(callee)) return;
- if (!callee.computed) return;
- if (!path.get("callee.property").matchesPattern("Symbol.iterator")) {
- return;
- }
- addImport(path, "web.dom.iterable", this.builtIns);
- },
- BinaryExpression(path) {
- if (path.node.operator !== "in") return;
- if (!path.get("left").matchesPattern("Symbol.iterator")) return;
- addImport(path, "web.dom.iterable", this.builtIns);
- },
- YieldExpression(path) {
- if (!path.node.delegate) return;
- addImport(path, "web.dom.iterable", this.builtIns);
- },
- MemberExpression: {
- enter(path, state) {
- if (!path.isReferenced()) return;
- const {
- node
- } = path;
- const obj = node.object;
- const prop = node.property;
- if (!t.isReferenced(obj, node)) return;
- let instanceType;
- let evaluatedPropType = obj.name;
- let propName = prop.name;
- if (node.computed) {
- if (t.isStringLiteral(prop)) {
- propName = prop.value;
- } else {
- const res = path.get("property").evaluate();
- if (res.confident && res.value) {
- propName = res.value;
- }
- }
- }
- if (path.scope.getBindingIdentifier(obj.name)) {
- const result = path.get("object").evaluate();
- if (result.value) {
- instanceType = getType(result.value);
- } else if (result.deopt && result.deopt.isIdentifier()) {
- evaluatedPropType = result.deopt.node.name;
- }
- }
- if (has(_builtInDefinitions.definitions.staticMethods, evaluatedPropType)) {
- const staticMethods = _builtInDefinitions.definitions.staticMethods[evaluatedPropType];
- if (has(staticMethods, propName)) {
- const builtIn = staticMethods[propName];
- addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
- }
- }
- if (has(_builtInDefinitions.definitions.instanceMethods, propName)) {
- let builtIn = _builtInDefinitions.definitions.instanceMethods[propName];
- if (instanceType) {
- builtIn = builtIn.filter(item => item.includes(instanceType));
- }
- addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
- }
- },
- exit(path, state) {
- if (!path.isReferenced()) return;
- const {
- node
- } = path;
- const obj = node.object;
- if (!has(_builtInDefinitions.definitions.builtins, obj.name)) return;
- if (path.scope.getBindingIdentifier(obj.name)) return;
- const builtIn = _builtInDefinitions.definitions.builtins[obj.name];
- addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
- }
- },
- VariableDeclarator(path, state) {
- if (!path.isReferenced()) return;
- const {
- node
- } = path;
- const obj = node.init;
- if (!t.isObjectPattern(node.id)) return;
- if (!t.isReferenced(obj, node)) return;
- if (obj && path.scope.getBindingIdentifier(obj.name)) return;
- for (let prop of node.id.properties) {
- prop = prop.key;
- if (!node.computed && t.isIdentifier(prop) && has(_builtInDefinitions.definitions.instanceMethods, prop.name)) {
- const builtIn = _builtInDefinitions.definitions.instanceMethods[prop.name];
- addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
- }
- }
- },
- Function(path, state) {
- if (!this.usesRegenerator && (path.node.generator || path.node.async)) {
- this.usesRegenerator = true;
- if (state.opts.regenerator) {
- addImport(path, "regenerator-runtime", this.builtIns);
- }
- }
- }
- };
- return {
- name: "use-built-ins",
- pre() {
- this.builtIns = new Set();
- this.usesRegenerator = false;
- },
- post() {
- const {
- debug,
- onDebug
- } = this.opts;
- if (debug) {
- (0, _debug.logUsagePolyfills)(this.builtIns, this.file.opts.filename, onDebug);
- }
- },
- visitor: addAndRemovePolyfillImports
- };
- }
|