forked from daren.hsu/line_push
update
This commit is contained in:
+11
-9
@@ -13,27 +13,29 @@ exports.default = void 0;
|
||||
|
||||
var _helperPluginUtils = require("@babel/helper-plugin-utils");
|
||||
|
||||
var _params = _interopRequireDefault(require("./params"));
|
||||
var _params = require("./params");
|
||||
|
||||
var _rest = _interopRequireDefault(require("./rest"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
var _rest = require("./rest");
|
||||
|
||||
var _default = (0, _helperPluginUtils.declare)((api, options) => {
|
||||
var _api$assumption, _api$assumption2;
|
||||
|
||||
api.assertVersion(7);
|
||||
const {
|
||||
loose
|
||||
} = options;
|
||||
const ignoreFunctionLength = (_api$assumption = api.assumption("ignoreFunctionLength")) != null ? _api$assumption : options.loose;
|
||||
const noNewArrows = (_api$assumption2 = api.assumption("noNewArrows")) != null ? _api$assumption2 : true;
|
||||
return {
|
||||
name: "transform-parameters",
|
||||
visitor: {
|
||||
Function(path) {
|
||||
if (path.isArrowFunctionExpression() && path.get("params").some(param => param.isRestElement() || param.isAssignmentPattern())) {
|
||||
path.arrowFunctionToExpression();
|
||||
path.arrowFunctionToExpression({
|
||||
noNewArrows
|
||||
});
|
||||
if (!path.isFunctionExpression()) return;
|
||||
}
|
||||
|
||||
const convertedRest = (0, _rest.default)(path);
|
||||
const convertedParams = (0, _params.default)(path, loose);
|
||||
const convertedParams = (0, _params.default)(path, ignoreFunctionLength);
|
||||
|
||||
if (convertedRest || convertedParams) {
|
||||
path.scope.crawl();
|
||||
|
||||
+23
-76
@@ -7,44 +7,31 @@ exports.default = convertFunctionParams;
|
||||
|
||||
var _core = require("@babel/core");
|
||||
|
||||
const buildDefaultParam = (0, _core.template)(`
|
||||
var _shadowUtils = require("./shadow-utils");
|
||||
|
||||
const buildDefaultParam = _core.template.statement(`
|
||||
let VARIABLE_NAME =
|
||||
arguments.length > ARGUMENT_KEY && arguments[ARGUMENT_KEY] !== undefined ?
|
||||
arguments[ARGUMENT_KEY]
|
||||
:
|
||||
DEFAULT_VALUE;
|
||||
`);
|
||||
const buildLooseDefaultParam = (0, _core.template)(`
|
||||
|
||||
const buildLooseDefaultParam = _core.template.statement(`
|
||||
if (ASSIGNMENT_IDENTIFIER === UNDEFINED) {
|
||||
ASSIGNMENT_IDENTIFIER = DEFAULT_VALUE;
|
||||
}
|
||||
`);
|
||||
const buildLooseDestructuredDefaultParam = (0, _core.template)(`
|
||||
|
||||
const buildLooseDestructuredDefaultParam = _core.template.statement(`
|
||||
let ASSIGNMENT_IDENTIFIER = PARAMETER_NAME === UNDEFINED ? DEFAULT_VALUE : PARAMETER_NAME ;
|
||||
`);
|
||||
const buildSafeArgumentsAccess = (0, _core.template)(`
|
||||
|
||||
const buildSafeArgumentsAccess = _core.template.statement(`
|
||||
let $0 = arguments.length > $1 ? arguments[$1] : undefined;
|
||||
`);
|
||||
const iifeVisitor = {
|
||||
"ReferencedIdentifier|BindingIdentifier"(path, state) {
|
||||
const {
|
||||
scope,
|
||||
node
|
||||
} = path;
|
||||
const {
|
||||
name
|
||||
} = node;
|
||||
|
||||
if (name === "eval" || scope.getBinding(name) === state.scope.parent.getBinding(name) && state.scope.hasOwnBinding(name)) {
|
||||
state.needsOuterBinding = true;
|
||||
path.stop();
|
||||
}
|
||||
},
|
||||
|
||||
"TypeAnnotation|TSTypeAnnotation|TypeParameterDeclaration|TSTypeParameterDeclaration": path => path.skip()
|
||||
};
|
||||
|
||||
function convertFunctionParams(path, loose, shouldTransformParam, replaceRestElement) {
|
||||
function convertFunctionParams(path, ignoreFunctionLength, shouldTransformParam, replaceRestElement) {
|
||||
const params = path.get("params");
|
||||
const isSimpleParameterList = params.every(param => param.isIdentifier());
|
||||
if (isSimpleParameterList) return false;
|
||||
@@ -52,52 +39,21 @@ function convertFunctionParams(path, loose, shouldTransformParam, replaceRestEle
|
||||
node,
|
||||
scope
|
||||
} = path;
|
||||
const state = {
|
||||
stop: false,
|
||||
needsOuterBinding: false,
|
||||
scope
|
||||
};
|
||||
const body = [];
|
||||
const shadowedParams = new Set();
|
||||
|
||||
for (const param of params) {
|
||||
for (const name of Object.keys(param.getBindingIdentifiers())) {
|
||||
var _scope$bindings$name;
|
||||
|
||||
const constantViolations = (_scope$bindings$name = scope.bindings[name]) == null ? void 0 : _scope$bindings$name.constantViolations;
|
||||
|
||||
if (constantViolations) {
|
||||
for (const redeclarator of constantViolations) {
|
||||
const node = redeclarator.node;
|
||||
|
||||
switch (node.type) {
|
||||
case "VariableDeclarator":
|
||||
{
|
||||
if (node.init === null) {
|
||||
const declaration = redeclarator.parentPath;
|
||||
|
||||
if (!declaration.parentPath.isFor() || declaration.parentPath.get("body") === declaration) {
|
||||
redeclarator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shadowedParams.add(name);
|
||||
break;
|
||||
}
|
||||
|
||||
case "FunctionDeclaration":
|
||||
shadowedParams.add(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(0, _shadowUtils.collectShadowedParamsNames)(param, scope, shadowedParams);
|
||||
}
|
||||
|
||||
const state = {
|
||||
needsOuterBinding: false,
|
||||
scope
|
||||
};
|
||||
|
||||
if (shadowedParams.size === 0) {
|
||||
for (const param of params) {
|
||||
if (!param.isIdentifier()) param.traverse(iifeVisitor, state);
|
||||
if (!param.isIdentifier()) param.traverse(_shadowUtils.iifeVisitor, state);
|
||||
if (state.needsOuterBinding) break;
|
||||
}
|
||||
}
|
||||
@@ -114,12 +70,14 @@ function convertFunctionParams(path, loose, shouldTransformParam, replaceRestEle
|
||||
const transformedRestNodes = [];
|
||||
|
||||
if (replaceRestElement) {
|
||||
replaceRestElement(param.parentPath, param, transformedRestNodes);
|
||||
replaceRestElement(path, param, transformedRestNodes);
|
||||
}
|
||||
|
||||
const paramIsAssignmentPattern = param.isAssignmentPattern();
|
||||
|
||||
if (paramIsAssignmentPattern && (loose || node.kind === "set")) {
|
||||
if (paramIsAssignmentPattern && (ignoreFunctionLength || _core.types.isMethod(node, {
|
||||
kind: "set"
|
||||
}))) {
|
||||
const left = param.get("left");
|
||||
const right = param.get("right");
|
||||
const undefinedNode = scope.buildUndefinedNode();
|
||||
@@ -156,6 +114,7 @@ function convertFunctionParams(path, loose, shouldTransformParam, replaceRestEle
|
||||
body.push(defNode);
|
||||
} else if (param.isObjectPattern() || param.isArrayPattern()) {
|
||||
const uid = path.scope.generateUidIdentifier("ref");
|
||||
uid.typeAnnotation = param.node.typeAnnotation;
|
||||
|
||||
const defNode = _core.types.variableDeclaration("let", [_core.types.variableDeclarator(param.node, uid)]);
|
||||
|
||||
@@ -177,7 +136,7 @@ function convertFunctionParams(path, loose, shouldTransformParam, replaceRestEle
|
||||
path.ensureBlock();
|
||||
|
||||
if (state.needsOuterBinding || shadowedParams.size > 0) {
|
||||
body.push(buildScopeIIFE(shadowedParams, path.get("body").node));
|
||||
body.push((0, _shadowUtils.buildScopeIIFE)(shadowedParams, path.node.body));
|
||||
path.set("body", _core.types.blockStatement(body));
|
||||
const bodyPath = path.get("body.body");
|
||||
const arrowPath = bodyPath[bodyPath.length - 1].get("argument.callee");
|
||||
@@ -190,16 +149,4 @@ function convertFunctionParams(path, loose, shouldTransformParam, replaceRestEle
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function buildScopeIIFE(shadowedParams, body) {
|
||||
const args = [];
|
||||
const params = [];
|
||||
|
||||
for (const name of shadowedParams) {
|
||||
args.push(_core.types.identifier(name));
|
||||
params.push(_core.types.identifier(name));
|
||||
}
|
||||
|
||||
return _core.types.returnStatement(_core.types.callExpression(_core.types.arrowFunctionExpression(params, body), params));
|
||||
}
|
||||
+51
-18
@@ -7,7 +7,9 @@ exports.default = convertFunctionRest;
|
||||
|
||||
var _core = require("@babel/core");
|
||||
|
||||
const buildRest = (0, _core.template)(`
|
||||
var _shadowUtils = require("./shadow-utils");
|
||||
|
||||
const buildRest = _core.template.statement(`
|
||||
for (var LEN = ARGUMENTS.length,
|
||||
ARRAY = new Array(ARRAY_LEN),
|
||||
KEY = START;
|
||||
@@ -16,13 +18,16 @@ const buildRest = (0, _core.template)(`
|
||||
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
|
||||
}
|
||||
`);
|
||||
const restIndex = (0, _core.template)(`
|
||||
|
||||
const restIndex = _core.template.expression(`
|
||||
(INDEX < OFFSET || ARGUMENTS.length <= INDEX) ? undefined : ARGUMENTS[INDEX]
|
||||
`);
|
||||
const restIndexImpure = (0, _core.template)(`
|
||||
|
||||
const restIndexImpure = _core.template.expression(`
|
||||
REF = INDEX, (REF < OFFSET || ARGUMENTS.length <= REF) ? undefined : ARGUMENTS[REF]
|
||||
`);
|
||||
const restLength = (0, _core.template)(`
|
||||
|
||||
const restLength = _core.template.expression(`
|
||||
ARGUMENTS.length <= OFFSET ? 0 : ARGUMENTS.length - OFFSET
|
||||
`);
|
||||
|
||||
@@ -148,17 +153,19 @@ function optimiseIndexGetter(path, argsId, offset) {
|
||||
const offsetLiteral = _core.types.numericLiteral(offset);
|
||||
|
||||
let index;
|
||||
const parent = path.parent;
|
||||
|
||||
if (_core.types.isNumericLiteral(path.parent.property)) {
|
||||
index = _core.types.numericLiteral(path.parent.property.value + offset);
|
||||
if (_core.types.isNumericLiteral(parent.property)) {
|
||||
index = _core.types.numericLiteral(parent.property.value + offset);
|
||||
} else if (offset === 0) {
|
||||
index = path.parent.property;
|
||||
index = parent.property;
|
||||
} else {
|
||||
index = _core.types.binaryExpression("+", path.parent.property, _core.types.cloneNode(offsetLiteral));
|
||||
index = _core.types.binaryExpression("+", parent.property, _core.types.cloneNode(offsetLiteral));
|
||||
}
|
||||
|
||||
const {
|
||||
scope
|
||||
scope,
|
||||
parentPath
|
||||
} = path;
|
||||
|
||||
if (!scope.isPure(index)) {
|
||||
@@ -167,27 +174,27 @@ function optimiseIndexGetter(path, argsId, offset) {
|
||||
id: temp,
|
||||
kind: "var"
|
||||
});
|
||||
path.parentPath.replaceWith(restIndexImpure({
|
||||
parentPath.replaceWith(restIndexImpure({
|
||||
ARGUMENTS: argsId,
|
||||
OFFSET: offsetLiteral,
|
||||
INDEX: index,
|
||||
REF: _core.types.cloneNode(temp)
|
||||
}));
|
||||
} else {
|
||||
const parentPath = path.parentPath;
|
||||
parentPath.replaceWith(restIndex({
|
||||
ARGUMENTS: argsId,
|
||||
OFFSET: offsetLiteral,
|
||||
INDEX: index
|
||||
}));
|
||||
const offsetTestPath = parentPath.get("test").get("left");
|
||||
const valRes = offsetTestPath.evaluate();
|
||||
const replacedParentPath = parentPath;
|
||||
const offsetTestPath = replacedParentPath.get("test");
|
||||
const valRes = offsetTestPath.get("left").evaluate();
|
||||
|
||||
if (valRes.confident) {
|
||||
if (valRes.value === true) {
|
||||
parentPath.replaceWith(parentPath.scope.buildUndefinedNode());
|
||||
replacedParentPath.replaceWith(scope.buildUndefinedNode());
|
||||
} else {
|
||||
parentPath.get("test").replaceWith(parentPath.get("test").get("right"));
|
||||
offsetTestPath.replaceWith(offsetTestPath.get("right"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,9 +217,30 @@ function convertFunctionRest(path) {
|
||||
scope
|
||||
} = path;
|
||||
if (!hasRest(node)) return false;
|
||||
let rest = node.params.pop().argument;
|
||||
const restPath = path.get(`params.${node.params.length - 1}.argument`);
|
||||
|
||||
const argsId = _core.types.identifier("arguments");
|
||||
if (!restPath.isIdentifier()) {
|
||||
const shadowedParams = new Set();
|
||||
(0, _shadowUtils.collectShadowedParamsNames)(restPath, path.scope, shadowedParams);
|
||||
let needsIIFE = shadowedParams.size > 0;
|
||||
|
||||
if (!needsIIFE) {
|
||||
const state = {
|
||||
needsOuterBinding: false,
|
||||
scope
|
||||
};
|
||||
restPath.traverse(_shadowUtils.iifeVisitor, state);
|
||||
needsIIFE = state.needsOuterBinding;
|
||||
}
|
||||
|
||||
if (needsIIFE) {
|
||||
path.ensureBlock();
|
||||
path.set("body", _core.types.blockStatement([(0, _shadowUtils.buildScopeIIFE)(shadowedParams, path.node.body)]));
|
||||
}
|
||||
}
|
||||
|
||||
let rest = restPath.node;
|
||||
node.params.pop();
|
||||
|
||||
if (_core.types.isPattern(rest)) {
|
||||
const pattern = rest;
|
||||
@@ -220,9 +248,14 @@ function convertFunctionRest(path) {
|
||||
|
||||
const declar = _core.types.variableDeclaration("let", [_core.types.variableDeclarator(pattern, rest)]);
|
||||
|
||||
path.ensureBlock();
|
||||
node.body.body.unshift(declar);
|
||||
} else if (rest.name === "arguments") {
|
||||
scope.rename(rest.name);
|
||||
}
|
||||
|
||||
const argsId = _core.types.identifier("arguments");
|
||||
|
||||
const paramsCount = getParamsCount(node);
|
||||
const state = {
|
||||
references: [],
|
||||
@@ -259,7 +292,7 @@ function convertFunctionRest(path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
state.references = state.references.concat(state.candidates.map(({
|
||||
state.references.push(...state.candidates.map(({
|
||||
path
|
||||
}) => path));
|
||||
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.buildScopeIIFE = buildScopeIIFE;
|
||||
exports.collectShadowedParamsNames = collectShadowedParamsNames;
|
||||
exports.iifeVisitor = void 0;
|
||||
|
||||
var _core = require("@babel/core");
|
||||
|
||||
const iifeVisitor = {
|
||||
"ReferencedIdentifier|BindingIdentifier"(path, state) {
|
||||
const {
|
||||
scope,
|
||||
node
|
||||
} = path;
|
||||
const {
|
||||
name
|
||||
} = node;
|
||||
|
||||
if (name === "eval" || scope.getBinding(name) === state.scope.parent.getBinding(name) && state.scope.hasOwnBinding(name)) {
|
||||
state.needsOuterBinding = true;
|
||||
path.stop();
|
||||
}
|
||||
},
|
||||
|
||||
"TypeAnnotation|TSTypeAnnotation|TypeParameterDeclaration|TSTypeParameterDeclaration": path => path.skip()
|
||||
};
|
||||
exports.iifeVisitor = iifeVisitor;
|
||||
|
||||
function collectShadowedParamsNames(param, functionScope, shadowedParams) {
|
||||
for (const name of Object.keys(param.getBindingIdentifiers())) {
|
||||
var _functionScope$bindin;
|
||||
|
||||
const constantViolations = (_functionScope$bindin = functionScope.bindings[name]) == null ? void 0 : _functionScope$bindin.constantViolations;
|
||||
|
||||
if (constantViolations) {
|
||||
for (const redeclarator of constantViolations) {
|
||||
const node = redeclarator.node;
|
||||
|
||||
switch (node.type) {
|
||||
case "VariableDeclarator":
|
||||
{
|
||||
if (node.init === null) {
|
||||
const declaration = redeclarator.parentPath;
|
||||
|
||||
if (!declaration.parentPath.isFor() || declaration.parentPath.get("body") === declaration) {
|
||||
redeclarator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shadowedParams.add(name);
|
||||
break;
|
||||
}
|
||||
|
||||
case "FunctionDeclaration":
|
||||
shadowedParams.add(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildScopeIIFE(shadowedParams, body) {
|
||||
const args = [];
|
||||
const params = [];
|
||||
|
||||
for (const name of shadowedParams) {
|
||||
args.push(_core.types.identifier(name));
|
||||
params.push(_core.types.identifier(name));
|
||||
}
|
||||
|
||||
return _core.types.returnStatement(_core.types.callExpression(_core.types.arrowFunctionExpression(params, body), args));
|
||||
}
|
||||
Reference in New Issue
Block a user