diff --git a/src/babel/transformation/transformers/other/runtime/definitions.json b/src/babel/transformation/transformers/other/runtime/definitions.json index c2062fae06..691a0df3eb 100644 --- a/src/babel/transformation/transformers/other/runtime/definitions.json +++ b/src/babel/transformation/transformers/other/runtime/definitions.json @@ -81,6 +81,7 @@ "cosh": "math/cosh", "expm1": "math/expm1", "fround": "math/fround", + "hypot": "math/hypot", "pot": "math/pot", "imul": "math/imul", "log10": "math/log10", @@ -110,6 +111,30 @@ "toPrimitive": "symbol/to-primitive", "toStringTag": "symbol/to-string-tag", "unscopables": "symbol/unscopables" + }, + "String": { + "at": "string/at", + "codePointAt": "string/code-point-at", + "endsWith": "string/ends-with", + "escapeHTML": "string/escape-html", + "fromCodePoint": "string/from-code-point", + "includes": "string/includes", + "raw": "string/raw", + "repeat": "string/repeat", + "startsWith": "string/starts-with", + "unescapeHTML": "string/unescape-html" + }, + "Number": { + "epsilon": "number/epsilon", + "isFinite": "number/is-finite", + "isInteger": "number/is-integer", + "isNaN": "number/is-nan", + "isSafeInteger": "number/is-safe-integer", + "MAX_SAFE_INTEGER": "number/max-safe-integer", + "MIN_SAFE_INTEGER": "number/min-safe-integer", + "parseFloat": "number/parse-float", + "parseInt": "number/parse-int", + "random": "number/random" } } } diff --git a/src/babel/transformation/transformers/other/runtime/index.js b/src/babel/transformation/transformers/other/runtime/index.js index 81b22a6c82..6c137e49ba 100644 --- a/src/babel/transformation/transformers/other/runtime/index.js +++ b/src/babel/transformation/transformers/other/runtime/index.js @@ -1,4 +1,5 @@ import includes from "lodash/collection/includes"; +import traverse from "../../../../traversal"; import * as util from "../../../../util"; import has from "lodash/object/has"; import * as t from "../../../../types"; @@ -8,53 +9,87 @@ var isSymbolIterator = t.buildMatchMemberExpression("Symbol.iterator"); const RUNTIME_MODULE_NAME = "babel-runtime"; -var astVisitor = { - enter(node, parent, scope, file) { - var prop; +var astVisitor = traverse.explode({ + Identifier(node, parent, scope, file) { + if (!this.isReferenced()) return; + if (t.isMemberExpression(parent)) return; + if (!has(definitions.builtins, node.name)) return; + if (scope.getBindingIdentifier(node.name)) return; - if (this.isMemberExpression() && this.isReferenced()) { + // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise + var modulePath = definitions.builtins[node.name]; + return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, true); + }, + + CallExpression(node, parent, scope, file) { + // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) + + var callee = node.callee; + if (node.arguments.length) return; + + if (!t.isMemberExpression(callee)) return; + if (!callee.computed) return; + + var prop = callee.property; + if (!isSymbolIterator(prop)) return; + + return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", true), [callee.object]); + }, + + BinaryExpression(node, parent, scope, file) { + // Symbol.iterator in arr -> core.$for.isIterable(arr) + + if (node.operator !== "in") return; + + var left = node.left; + if (!isSymbolIterator(left)) return; + + return t.callExpression( + file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", true), + [node.right] + ); + }, + + MemberExpression: { + enter(node, parent, scope, file) { // Array.from -> _core.Array.from + + if (!this.isReferenced()) return; + var obj = node.object; - prop = node.property; + var prop = node.property; if (!t.isReferenced(obj, node)) return; if (node.computed) return; + if (!has(definitions.methods, obj.name)) return; - if (!has(definitions.methods[obj.name], prop.name)) return; + + var methods = definitions.methods[obj.name]; + if (!has(methods, prop.name)) return; + if (scope.getBindingIdentifier(obj.name)) return; - var modulePath = definitions.methods[obj.name][prop.name]; + var modulePath = methods[prop.name]; return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, true); - } else if (this.isReferencedIdentifier() && !t.isMemberExpression(parent) && has(definitions.builtins, node.name) && !scope.getBindingIdentifier(node.name)) { - // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise - var modulePath = definitions.builtins[node.name]; - return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, true); - } else if (this.isCallExpression()) { - // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) + }, - var callee = node.callee; - if (node.arguments.length) return false; + exit(node, parent, scope, file) { + if (!this.isReferenced()) return; - if (!t.isMemberExpression(callee)) return false; - if (!callee.computed) return false; + var prop = node.property; + var obj = node.object; - prop = callee.property; - if (!isSymbolIterator(prop)) return false; + if (!has(definitions.builtins, obj.name)) return; - return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", true), [callee.object]); - } else if (this.isBinaryExpression()) { - // Symbol.iterator in arr -> core.$for.isIterable(arr) - - if (node.operator !== "in") return; - - var left = node.left; - if (!isSymbolIterator(left)) return; - - return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", true), [node.right]); + var modulePath = definitions.builtins[obj.name]; + return t.memberExpression( + file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, true), + prop + ); } } -}; +}); exports.metadata = { optional: true diff --git a/src/babel/traversal/index.js b/src/babel/traversal/index.js index dd095707e2..07801b333b 100644 --- a/src/babel/traversal/index.js +++ b/src/babel/traversal/index.js @@ -78,6 +78,9 @@ traverse.removeProperties = function (tree) { traverse.explode = function (obj) { for (var type in obj) { var fns = obj[type]; + if (typeof fns === "function") { + obj[type] = fns = { enter: fns }; + } var aliases = t.FLIPPED_ALIAS_KEYS[type]; if (aliases) { diff --git a/test/core/fixtures/transformation/runtime/catch-all/actual.js b/test/core/fixtures/transformation/runtime/catch-all/actual.js new file mode 100644 index 0000000000..8e9b315294 --- /dev/null +++ b/test/core/fixtures/transformation/runtime/catch-all/actual.js @@ -0,0 +1 @@ +Promise.resolve; diff --git a/test/core/fixtures/transformation/runtime/catch-all/expected.js b/test/core/fixtures/transformation/runtime/catch-all/expected.js new file mode 100644 index 0000000000..52dd0c3016 --- /dev/null +++ b/test/core/fixtures/transformation/runtime/catch-all/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +var _Promise = require("babel-runtime/core-js/promise")["default"]; + +_Promise.resolve;