enable prefer const (#5113)

This commit is contained in:
Henry Zhu
2017-01-14 09:48:52 -05:00
committed by GitHub
parent 982850731e
commit 672adba9a1
177 changed files with 1862 additions and 1863 deletions

View File

@@ -5,7 +5,7 @@ import callDelegate from "babel-helper-call-delegate";
import template from "babel-template";
import * as t from "babel-types";
let buildDefaultParam = template(`
const buildDefaultParam = template(`
let VARIABLE_NAME =
ARGUMENTS.length > ARGUMENT_KEY && ARGUMENTS[ARGUMENT_KEY] !== undefined ?
ARGUMENTS[ARGUMENT_KEY]
@@ -13,12 +13,12 @@ let buildDefaultParam = template(`
DEFAULT_VALUE;
`);
let buildCutOff = template(`
const buildCutOff = template(`
let $0 = $1[$2];
`);
function hasDefaults(node) {
for (let param of (node.params: Array<Object>)) {
for (const param of (node.params: Array<Object>)) {
if (!t.isIdentifier(param)) return true;
}
return false;
@@ -30,7 +30,7 @@ function isSafeBinding(scope, node) {
return kind === "param" || kind === "local";
}
let iifeVisitor = {
const iifeVisitor = {
ReferencedIdentifier(path, state) {
const { scope, node } = path;
if (node.name === "eval" || !isSafeBinding(scope, node)) {
@@ -45,23 +45,23 @@ let iifeVisitor = {
}
};
export let visitor = {
export const visitor = {
Function(path) {
let { node, scope } = path;
const { node, scope } = path;
if (!hasDefaults(node)) return;
// ensure it's a block, useful for arrow functions
path.ensureBlock();
let state = {
const state = {
iife: false,
scope: scope
};
let body = [];
const body = [];
//
let argsIdentifier = t.identifier("arguments");
const argsIdentifier = t.identifier("arguments");
argsIdentifier._shadowedFunctionLiteral = path;
// push a default parameter definition
@@ -77,12 +77,12 @@ export let visitor = {
}
//
let lastNonDefaultParam = getFunctionArity(node);
const lastNonDefaultParam = getFunctionArity(node);
//
let params = path.get("params");
const params = path.get("params");
for (let i = 0; i < params.length; i++) {
let param = params[i];
const param = params[i];
if (!param.isAssignmentPattern()) {
if (!state.iife && !param.isIdentifier()) {
@@ -92,12 +92,12 @@ export let visitor = {
continue;
}
let left = param.get("left");
let right = param.get("right");
const left = param.get("left");
const right = param.get("right");
//
if (i >= lastNonDefaultParam || left.isPattern()) {
let placeholder = scope.generateUidIdentifier("x");
const placeholder = scope.generateUidIdentifier("x");
placeholder._isDefaultPlaceholder = true;
node.params[i] = placeholder;
} else {
@@ -119,10 +119,10 @@ export let visitor = {
// add declarations for trailing parameters
for (let i = lastNonDefaultParam + 1; i < node.params.length; i++) {
let param = node.params[i];
const param = node.params[i];
if (param._isDefaultPlaceholder) continue;
let declar = buildCutOff(param, argsIdentifier, t.numericLiteral(i));
const declar = buildCutOff(param, argsIdentifier, t.numericLiteral(i));
declar._blockHoist = node.params.length - i;
body.push(declar);
}

View File

@@ -1,20 +1,20 @@
import * as t from "babel-types";
export let visitor = {
export const visitor = {
Function(path) {
let params: Array = path.get("params");
const params: Array = path.get("params");
// If there's a rest param, no need to loop through it. Also, we need to
// hoist one more level to get `declar` at the right spot.
let hoistTweak = t.isRestElement(params[params.length - 1]) ? 1 : 0;
let outputParamsLength = params.length - hoistTweak;
const hoistTweak = t.isRestElement(params[params.length - 1]) ? 1 : 0;
const outputParamsLength = params.length - hoistTweak;
for (let i = 0; i < outputParamsLength; i++) {
let param = params[i];
const param = params[i];
if (param.isArrayPattern() || param.isObjectPattern()) {
let uid = path.scope.generateUidIdentifier("ref");
const uid = path.scope.generateUidIdentifier("ref");
let declar = t.variableDeclaration("let", [
const declar = t.variableDeclaration("let", [
t.variableDeclarator(param.node, uid)
]);
declar._blockHoist = outputParamsLength - i;

View File

@@ -10,8 +10,8 @@ export default function () {
visitor: visitors.merge([{
ArrowFunctionExpression(path) {
// default/rest visitors require access to `arguments`
let params: Array<NodePath> = path.get("params");
for (let param of params) {
const params: Array<NodePath> = path.get("params");
for (const param of params) {
if (param.isRestElement() || param.isAssignmentPattern()) {
path.arrowFunctionToShadowed();
break;

View File

@@ -3,7 +3,7 @@
import template from "babel-template";
import * as t from "babel-types";
let buildRest = template(`
const buildRest = template(`
for (var LEN = ARGUMENTS.length,
ARRAY = Array(ARRAY_LEN),
KEY = START;
@@ -13,19 +13,19 @@ let buildRest = template(`
}
`);
let restIndex = template(`
const restIndex = template(`
ARGUMENTS.length <= INDEX ? undefined : ARGUMENTS[INDEX]
`);
let restIndexImpure = template(`
const restIndexImpure = template(`
REF = INDEX, ARGUMENTS.length <= REF ? undefined : ARGUMENTS[REF]
`);
let restLength = template(`
const restLength = template(`
ARGUMENTS.length <= OFFSET ? 0 : ARGUMENTS.length - OFFSET
`);
let memberExpressionOptimisationVisitor = {
const memberExpressionOptimisationVisitor = {
Scope(path, state) {
// check if this scope has a local binding that will shadow the rest parameter
if (!path.scope.bindingIdentifierEquals(state.name, state.outerBinding)) {
@@ -43,7 +43,7 @@ let memberExpressionOptimisationVisitor = {
"Function|ClassProperty": function (path, state) {
// Detect whether any reference to rest is contained in nested functions to
// determine if deopt is necessary.
let oldNoOptimise = state.noOptimise;
const oldNoOptimise = state.noOptimise;
state.noOptimise = true;
path.traverse(memberExpressionOptimisationVisitor, state);
state.noOptimise = oldNoOptimise;
@@ -54,7 +54,7 @@ let memberExpressionOptimisationVisitor = {
},
ReferencedIdentifier(path, state) {
let { node } = path;
const { node } = path;
// we can't guarantee the purity of arguments
if (node.name === "arguments") {
@@ -67,7 +67,7 @@ let memberExpressionOptimisationVisitor = {
if (state.noOptimise) {
state.deopted = true;
} else {
let {parentPath} = path;
const {parentPath} = path;
// Is this identifier the right hand side of a default parameter?
if (parentPath.listKey === "params" && parentPath.key < state.offset) {
@@ -77,9 +77,9 @@ let memberExpressionOptimisationVisitor = {
// ex: `args[0]`
// ex: `args.whatever`
if (parentPath.isMemberExpression({ object: node })) {
let grandparentPath = parentPath.parentPath;
const grandparentPath = parentPath.parentPath;
let argsOptEligible = !state.deopted && !(
const argsOptEligible = !state.deopted && !(
// ex: `args[0] = "whatever"`
(
grandparentPath.isAssignmentExpression() &&
@@ -134,7 +134,7 @@ let memberExpressionOptimisationVisitor = {
// optimise single spread args in calls
// ex: fn(...args)
if (state.offset === 0 && parentPath.isSpreadElement()) {
let call = parentPath.parentPath;
const call = parentPath.parentPath;
if (call.isCallExpression() && call.node.arguments.length === 1) {
state.candidates.push({cause: "argSpread", path});
return;
@@ -175,7 +175,7 @@ function optimiseIndexGetter(path, argsId, offset) {
const { scope } = path;
if (!scope.isPure(index)) {
let temp = scope.generateUidIdentifierBasedOnNode(index);
const temp = scope.generateUidIdentifierBasedOnNode(index);
scope.push({id: temp, kind: "var"});
path.parentPath.replaceWith(restIndexImpure({
ARGUMENTS: argsId,
@@ -201,20 +201,20 @@ function optimiseLengthGetter(path, argsId, offset) {
}
}
export let visitor = {
export const visitor = {
Function(path) {
let { node, scope } = path;
const { node, scope } = path;
if (!hasRest(node)) return;
let rest = node.params.pop().argument;
const rest = node.params.pop().argument;
let argsId = t.identifier("arguments");
const argsId = t.identifier("arguments");
// otherwise `arguments` will be remapped in arrow functions
argsId._shadowedFunctionLiteral = path;
// check and optimise for extremely common cases
let state = {
const state = {
references: [],
offset: node.params.length,
@@ -246,7 +246,7 @@ export let visitor = {
// There are only "shorthand" references
if (!state.deopted && !state.references.length) {
for (let {path, cause} of (state.candidates: Array)) {
for (const {path, cause} of (state.candidates: Array)) {
switch (cause) {
case "indexGetter":
optimiseIndexGetter(path, argsId, state.offset);
@@ -268,9 +268,9 @@ export let visitor = {
// deopt shadowed functions as transforms like regenerator may try touch the allocation loop
state.deopted = state.deopted || !!node.shadow;
let start = t.numericLiteral(node.params.length);
let key = scope.generateUidIdentifier("key");
let len = scope.generateUidIdentifier("len");
const start = t.numericLiteral(node.params.length);
const key = scope.generateUidIdentifier("key");
const len = scope.generateUidIdentifier("len");
let arrKey = key;
let arrLen = len;
@@ -293,7 +293,7 @@ export let visitor = {
);
}
let loop = buildRest({
const loop = buildRest({
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,
ARRAY_LEN: arrLen,