Skip to content
Permalink
Browse files

[runtime-corejs3] Only polyfill instance methods when it might be nee…

…ded (#9754)
  • Loading branch information...
nicolo-ribaudo committed Apr 2, 2019
1 parent 53e0622 commit e03eb17c0884e2674ca998013ef0266ba60ca702
@@ -1,4 +1,5 @@
import semver from "semver";
import { types as t } from "@babel/core";

export function hasMinVersion(minVersion, runtimeVersion) {
// If the range is unavailable, we're running the script during Babel's
@@ -30,3 +31,16 @@ export function hasMinVersion(minVersion, runtimeVersion) {
!semver.intersects(`>=8.0.0`, runtimeVersion)
);
}

// Note: We can't use NodePath#couldBeBaseType because it doesn't support arrays.
// Even if we added support for arrays, this package needs to be compatible with
// ^7.0.0 so we can't rely on it.
export function typeAnnotationToString(node) {
switch (node.type) {
case "GenericTypeAnnotation":
if (t.isIdentifier(node.id, { name: "Array" })) return "array";
break;
case "StringTypeAnnotation":
return "string";
}
}
@@ -6,6 +6,7 @@ import { types as t } from "@babel/core";

import getCoreJS2Definitions from "./runtime-corejs2-definitions";
import getCoreJS3Definitions from "./runtime-corejs3-definitions";
import { typeAnnotationToString } from "./helpers";

function resolveAbsoluteRuntime(moduleName: string, dirname: string) {
try {
@@ -112,6 +113,16 @@ export default declare((api, options, dirname) => {
);
}

function maybeNeedsPolyfill(path, methods, name) {
if (!methods[name].types) return true;

const typeAnnotation = path.get("object").getTypeAnnotation();
const type = typeAnnotationToString(typeAnnotation);
if (!type) return true;

return methods[name].types.some(name => name === type);
}

if (has(options, "useBuiltIns")) {
if (options.useBuiltIns) {
throw new Error(
@@ -284,7 +295,14 @@ export default declare((api, options, dirname) => {

// transform calling instance methods like `something.includes()`
if (injectCoreJS3 && !hasStaticMapping(object.name, propertyName)) {
if (hasMapping(InstanceProperties, propertyName)) {
if (
hasMapping(InstanceProperties, propertyName) &&
maybeNeedsPolyfill(
path.get("callee"),
InstanceProperties,
propertyName,
)
) {
let context1, context2;
if (t.isIdentifier(object)) {
context1 = object;
@@ -381,7 +399,11 @@ export default declare((api, options, dirname) => {
!hasStaticMapping(objectName, propertyName)
) {
// transform getting of instance methods like `method = something.includes`
if (injectCoreJS3 && hasMapping(InstanceProperties, propertyName)) {
if (
injectCoreJS3 &&
hasMapping(InstanceProperties, propertyName) &&
maybeNeedsPolyfill(path, InstanceProperties, propertyName)
) {
path.replaceWith(
t.callExpression(
this.addDefaultImport(
@@ -180,12 +180,16 @@ export default () => {
},
},

// NOTE: You can specify the object types whose method needs to be polyfilled.
// e.g. concat: { types: ["array"] }
// See ./helpers.js@typeAnnotationToString for the supported types

InstanceProperties: {
at: { stable: false, path: "at" },
bind: { stable: true, path: "bind" },
codePointAt: { stable: true, path: "code-point-at" },
codePoints: { stable: false, path: "code-points" },
concat: { stable: true, path: "concat" },
concat: { stable: true, path: "concat", types: ["array"] },
copyWithin: { stable: true, path: "copy-within" },
endsWith: { stable: true, path: "ends-with" },
entries: { stable: true, path: "entries" },
@@ -0,0 +1 @@
require(`./locale/${lan}`);
@@ -0,0 +1,6 @@
{
"plugins": [
["transform-runtime", { "corejs": 3 }],
"transform-template-literals"
]
}
@@ -0,0 +1 @@
require("./locale/".concat(lan));
@@ -0,0 +1,3 @@
"".concat(b);
[].concat(b);
a.concat(b);
@@ -0,0 +1,3 @@
{
"plugins": [["transform-runtime", { "corejs": 3 }]]
}
@@ -0,0 +1,9 @@
var _concatInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/concat");

var _context;

"".concat(b);

_concatInstanceProperty(_context = []).call(_context, b);

_concatInstanceProperty(a).call(a, b);

0 comments on commit e03eb17

Please sign in to comment.
You can’t perform that action at this time.