Added spec arrow transformer.
Enforces: * `new arrowFn(...)` is disallowed; * `arrowFn.prototype` does not exist.
This commit is contained in:
parent
eaaa279aa5
commit
15ae0b669b
@ -85,6 +85,7 @@ export default class File {
|
||||
"get",
|
||||
"set",
|
||||
"class-call-check",
|
||||
"new-arrow-check",
|
||||
"object-destructuring-empty",
|
||||
"temporal-undefined",
|
||||
"temporal-assert-defined",
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
(function (instance, arrowFn) {
|
||||
if (instance instanceof arrowFn) {
|
||||
throw new TypeError("Cannot instantiate an arrow function");
|
||||
}
|
||||
});
|
||||
@ -5,5 +5,5 @@ export function ArrowFunctionExpression(node) {
|
||||
|
||||
node.expression = false;
|
||||
node.type = "FunctionExpression";
|
||||
node.shadow = true;
|
||||
node.shadow = node.shadow || true;
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
};
|
||||
|
||||
export function ArrowFunctionExpression(node, parent, scope, file) {
|
||||
if (node.shadow) return;
|
||||
node.shadow = { this: false };
|
||||
|
||||
var {id} = node;
|
||||
var expr = node;
|
||||
|
||||
if (!id) {
|
||||
id = scope.parent.generateDeclaredUidIdentifier("arrow");
|
||||
expr = t.assignmentExpression("=", id, expr);
|
||||
}
|
||||
|
||||
// make sure that arrow function won't be instantiated
|
||||
t.ensureBlock(node).body.unshift(t.expressionStatement(t.callExpression(file.addHelper("new-arrow-check"), [
|
||||
t.thisExpression(),
|
||||
id
|
||||
])));
|
||||
|
||||
return t.callExpression(t.memberExpression(expr, t.identifier("bind")), [t.thisExpression()]);
|
||||
}
|
||||
@ -26,6 +26,7 @@ export default {
|
||||
"es7.decorators": require("./es7/decorators"),
|
||||
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
|
||||
"validation.react": require("./validation/react"),
|
||||
"es6.spec.arrowFunctions": require("./es6/spec.arrow-functions"),
|
||||
"es6.arrowFunctions": require("./es6/arrow-functions"),
|
||||
"spec.blockScopedFunctions": require("./spec/block-scoped-functions"),
|
||||
"optimisation.react.constantElements": require("./optimisation/react.constant-elements"),
|
||||
|
||||
@ -6,7 +6,7 @@ export var metadata = {
|
||||
|
||||
function remap(path, key, create) {
|
||||
// ensure that we're shadowed
|
||||
if (!path.inShadow()) return;
|
||||
if (!path.inShadow(key)) return;
|
||||
|
||||
var fnPath = path.findParent((path) => !path.is("shadow") && (path.isFunction() || path.isProgram()));
|
||||
|
||||
@ -22,8 +22,10 @@ function remap(path, key, create) {
|
||||
return id;
|
||||
}
|
||||
|
||||
export function ThisExpression() {
|
||||
return remap(this, "this", () => t.thisExpression());
|
||||
export function ThisExpression(node) {
|
||||
if (!node._shadowedFunctionLiteral) {
|
||||
return remap(this, "this", () => t.thisExpression());
|
||||
}
|
||||
}
|
||||
|
||||
export function ReferencedIdentifier(node) {
|
||||
|
||||
@ -62,11 +62,12 @@ export function inType(types) {
|
||||
* Description
|
||||
*/
|
||||
|
||||
export function inShadow() {
|
||||
export function inShadow(key) {
|
||||
var path = this;
|
||||
while (path) {
|
||||
if (path.isFunction()) {
|
||||
if (path.node.shadow) {
|
||||
var {shadow} = path.node;
|
||||
if (shadow && (shadow === true || shadow[key] !== false)) {
|
||||
return path;
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
arr.map(x => x * x);
|
||||
var f = (x, y) => x * y;
|
||||
(function () {
|
||||
return () => this;
|
||||
})();
|
||||
@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
var _arrow;
|
||||
|
||||
function _newArrowCheck(instance, arrowFn) { if (instance instanceof arrowFn) { throw new TypeError("Cannot instantiate an arrow function"); } }
|
||||
|
||||
arr.map((_arrow = function (x) {
|
||||
_newArrowCheck(this, _arrow);
|
||||
|
||||
return x * x;
|
||||
}).bind(this));
|
||||
var f = (function f(x, y) {
|
||||
_newArrowCheck(this, f);
|
||||
|
||||
return x * y;
|
||||
}).bind(this);
|
||||
(function () {
|
||||
var _arrow2;
|
||||
|
||||
return (_arrow2 = function () {
|
||||
_newArrowCheck(this, _arrow2);
|
||||
|
||||
return this;
|
||||
}).bind(this);
|
||||
})();
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"optional": ["es6.spec.arrowFunctions"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user