Fix global reference for use-built-ins plugin (#6478)
* Consider instance type for polyfills. * Add test cases for evaluated objects. * preset-env fixtures: babel-polyfill -> @babel/polyfill * Split up fixtures with evaluated variables.
This commit is contained in:
committed by
Henry Zhu
parent
1a7194a22f
commit
9cf017b2ca
@@ -24,6 +24,11 @@ function has(obj: Object, key: string): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
function getType(target: any): string {
|
||||
if (Array.isArray(target)) return "array";
|
||||
return typeof target;
|
||||
}
|
||||
|
||||
// function getObjectString(node: Object): string {
|
||||
// if (node.type === "Identifier") {
|
||||
// return node.name;
|
||||
@@ -176,14 +181,31 @@ export default function({ types: t }: { types: Object }): Plugin {
|
||||
const prop = node.property;
|
||||
|
||||
if (!t.isReferenced(obj, node)) return;
|
||||
|
||||
// doesn't reference the global
|
||||
if (path.scope.getBindingIdentifier(obj.name)) return;
|
||||
|
||||
if (has(definitions.staticMethods, obj.name)) {
|
||||
const staticMethods = definitions.staticMethods[obj.name];
|
||||
if (has(staticMethods, prop.name)) {
|
||||
const builtIn = staticMethods[prop.name];
|
||||
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(definitions.staticMethods, evaluatedPropType)) {
|
||||
const staticMethods = definitions.staticMethods[evaluatedPropType];
|
||||
if (has(staticMethods, propName)) {
|
||||
const builtIn = staticMethods[propName];
|
||||
addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
|
||||
// if (obj.name === "Array" && prop.name === "from") {
|
||||
// addImport(
|
||||
@@ -195,35 +217,13 @@ export default function({ types: t }: { types: Object }): Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!node.computed &&
|
||||
t.isIdentifier(prop) &&
|
||||
has(definitions.instanceMethods, prop.name)
|
||||
) {
|
||||
if (has(definitions.instanceMethods, propName)) {
|
||||
//warnOnInstanceMethod(state, getObjectString(node));
|
||||
const builtIn = definitions.instanceMethods[prop.name];
|
||||
addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
|
||||
} else if (node.computed) {
|
||||
if (
|
||||
t.isStringLiteral(prop) &&
|
||||
has(definitions.instanceMethods, prop.value)
|
||||
) {
|
||||
const builtIn = definitions.instanceMethods[prop.value];
|
||||
//warnOnInstanceMethod(state, `${obj.name}['${prop.value}']`);
|
||||
addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
|
||||
} else {
|
||||
const res = path.get("property").evaluate();
|
||||
if (res.confident) {
|
||||
const builtIn = definitions.instanceMethods[res.value];
|
||||
//warnOnInstanceMethod(state, `${obj.name}['${res.value}']`);
|
||||
addUnsupported(
|
||||
path.get("property"),
|
||||
state.opts.polyfills,
|
||||
builtIn,
|
||||
this.builtIns,
|
||||
);
|
||||
}
|
||||
let builtIn = definitions.instanceMethods[propName];
|
||||
if (instanceType) {
|
||||
builtIn = builtIn.filter(item => item.includes(instanceType));
|
||||
}
|
||||
addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
var objectClass = Object;
|
||||
var arrayInstance = [];
|
||||
var assignStr = "assign";
|
||||
var entriesStr = "entries";
|
||||
var valuesStr = "values";
|
||||
var inclidesStr = "includes";
|
||||
var findStr = "find";
|
||||
|
||||
// Allow static methods be assigned to variables only directly in the module.
|
||||
externalVar[valuesStr]; // don't include
|
||||
objectClass[assignStr]({}); // include
|
||||
arrayInstance[entriesStr]({}); // don't include
|
||||
@@ -0,0 +1,14 @@
|
||||
import "@babel/polyfill/lib/core-js/modules/es6.object.assign";
|
||||
var objectClass = Object;
|
||||
var arrayInstance = [];
|
||||
var assignStr = "assign";
|
||||
var entriesStr = "entries";
|
||||
var valuesStr = "values";
|
||||
var inclidesStr = "includes";
|
||||
var findStr = "find"; // Allow static methods be assigned to variables only directly in the module.
|
||||
|
||||
externalVar[valuesStr]; // don't include
|
||||
|
||||
objectClass[assignStr]({}); // include
|
||||
|
||||
arrayInstance[entriesStr]({}); // don't include
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
["../../../../lib", {
|
||||
"useBuiltIns": "usage",
|
||||
"modules": false
|
||||
}]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
var arrayInstance = [];
|
||||
var inclidesStr = "includes";
|
||||
var findStr = "find";
|
||||
|
||||
// Allow instance methods be assigned to variables.
|
||||
arrayInstance[inclidesStr](); // include
|
||||
externalVar[findStr]; // include
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import "@babel/polyfill/lib/core-js/modules/es6.array.find";
|
||||
import "@babel/polyfill/lib/core-js/modules/es7.array.includes";
|
||||
var arrayInstance = [];
|
||||
var inclidesStr = "includes";
|
||||
var findStr = "find"; // Allow instance methods be assigned to variables.
|
||||
|
||||
arrayInstance[inclidesStr](); // include
|
||||
|
||||
externalVar[findStr]; // include
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
["../../../../lib", {
|
||||
"useBuiltIns": "usage",
|
||||
"modules": false
|
||||
}]
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user