Optimize and remove state from typeof-symbol transform (#5955)
Also fixes a bug with returning a Symbol from a Class constructor (because the transform wasn’t run on helpers before).
This commit is contained in:
committed by
Henry Zhu
parent
9d612e717e
commit
797fb3c2e4
@@ -362,7 +362,7 @@ helpers.get = template(`
|
||||
helpers.inherits = template(`
|
||||
(function (subClass, superClass) {
|
||||
if (typeof superClass !== "function" && superClass !== null) {
|
||||
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
||||
throw new TypeError("Super expression must either be null or a function");
|
||||
}
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
||||
constructor: {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"plugins": ["transform-es2015-classes", "transform-es2015-block-scoping"]
|
||||
"plugins": ["transform-es2015-classes", "transform-es2015-block-scoping", "transform-es2015-typeof-symbol"]
|
||||
}
|
||||
|
||||
9
packages/babel-plugin-transform-es2015-classes/test/fixtures/exec/return-symbol.js
vendored
Normal file
9
packages/babel-plugin-transform-es2015-classes/test/fixtures/exec/return-symbol.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
return Symbol();
|
||||
}
|
||||
}
|
||||
|
||||
const f = new Foo;
|
||||
assert.ok(f instanceof Foo);
|
||||
assert.ok(typeof f === "object");
|
||||
@@ -1,8 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
export default function({ types: t }) {
|
||||
const IGNORE = Symbol();
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
Scope({ scope }) {
|
||||
@@ -13,8 +11,7 @@ export default function({ types: t }) {
|
||||
|
||||
UnaryExpression(path) {
|
||||
const { node, parent } = path;
|
||||
if (node[IGNORE]) return;
|
||||
if (path.find(path => path.node && !!path.node._generated)) return;
|
||||
if (node.operator !== "typeof") return;
|
||||
|
||||
if (
|
||||
path.parentPath.isBinaryExpression() &&
|
||||
@@ -32,24 +29,29 @@ export default function({ types: t }) {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.operator === "typeof") {
|
||||
const call = t.callExpression(this.addHelper("typeof"), [
|
||||
node.argument,
|
||||
]);
|
||||
if (path.get("argument").isIdentifier()) {
|
||||
const undefLiteral = t.stringLiteral("undefined");
|
||||
const unary = t.unaryExpression("typeof", node.argument);
|
||||
unary[IGNORE] = true;
|
||||
path.replaceWith(
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", unary, undefLiteral),
|
||||
undefLiteral,
|
||||
call,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
path.replaceWith(call);
|
||||
}
|
||||
const helper = this.addHelper("typeof");
|
||||
const isUnderHelper = path.findParent(path => {
|
||||
return path.isVariableDeclarator() && path.node.id === helper;
|
||||
});
|
||||
|
||||
if (isUnderHelper) {
|
||||
return;
|
||||
}
|
||||
|
||||
const call = t.callExpression(helper, [node.argument]);
|
||||
const arg = path.get("argument");
|
||||
if (arg.isIdentifier() && !path.scope.hasBinding(arg.node.name)) {
|
||||
const undefLiteral = t.stringLiteral("undefined");
|
||||
const unary = t.unaryExpression("typeof", node.argument);
|
||||
path.replaceWith(
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", unary, undefLiteral),
|
||||
undefLiteral,
|
||||
call,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
path.replaceWith(call);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -3,3 +3,7 @@ assert.ok(typeof s === "symbol");
|
||||
assert.equal(typeof s, "symbol");
|
||||
assert.equal(typeof typeof s.foo, "symbol");
|
||||
typeof s === "string";
|
||||
assert.isNotOk(typeof o === "symbol");
|
||||
assert.notEqual(typeof o, "symbol");
|
||||
assert.notEqual(typeof typeof o.foo, "symbol");
|
||||
typeof o === "string";
|
||||
|
||||
@@ -2,3 +2,7 @@ var s = Symbol("s");
|
||||
assert.equal(typeof s, "symbol");
|
||||
assert.ok(typeof s === "symbol");
|
||||
assert.ok(typeof Symbol.prototype === 'object', "`typeof Symbol.prototype` should be 'object'");
|
||||
assert.isNotOk(typeof o === "symbol");
|
||||
assert.notEqual(typeof o, "symbol");
|
||||
assert.notEqual(typeof typeof o, "symbol");
|
||||
typeof o === "string";
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
var s = Symbol("s");
|
||||
assert.ok((typeof s === "undefined" ? "undefined" : babelHelpers.typeof(s)) === "symbol");
|
||||
assert.equal(typeof s === "undefined" ? "undefined" : babelHelpers.typeof(s), "symbol");
|
||||
assert.ok(babelHelpers.typeof(s) === "symbol");
|
||||
assert.equal(babelHelpers.typeof(s), "symbol");
|
||||
assert.equal(babelHelpers.typeof(babelHelpers.typeof(s.foo)), "symbol");
|
||||
typeof s === "string";
|
||||
assert.isNotOk((typeof o === "undefined" ? "undefined" : babelHelpers.typeof(o)) === "symbol");
|
||||
assert.notEqual(typeof o === "undefined" ? "undefined" : babelHelpers.typeof(o), "symbol");
|
||||
assert.notEqual(babelHelpers.typeof(babelHelpers.typeof(o.foo)), "symbol");
|
||||
typeof o === "string";
|
||||
|
||||
Reference in New Issue
Block a user