diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/@babel/plugin-transform-parameters | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/@babel/plugin-transform-parameters')
5 files changed, 612 insertions, 0 deletions
diff --git a/node_modules/@babel/plugin-transform-parameters/README.md b/node_modules/@babel/plugin-transform-parameters/README.md new file mode 100644 index 00000000..1c96bcee --- /dev/null +++ b/node_modules/@babel/plugin-transform-parameters/README.md @@ -0,0 +1,94 @@ +# @babel/plugin-transform-parameters + +> Compile ES2015 default and rest parameters to ES5 + +This plugin transforms ES2015 parameters to ES5, this includes: + +- Destructuring parameters +- Default parameters +- Rest parameters + +## Examples + +**In** + +```javascript +function test(x = "hello", { a, b }, ...args) { + console.log(x, a, b, args); +} +``` + +**Out** + +```javascript +function test() { + var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "hello"; + var _ref = arguments[1]; + var a = _ref.a, + b = _ref.b; + + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + console.log(x, a, b, args); +} +``` + +## Installation + +```sh +npm install --save-dev @babel/plugin-transform-parameters +``` + +## Caveats + +Default parameters desugar into `let` declarations to retain proper semantics. If this is +not supported in your environment then you'll need the +[@babel/plugin-transform-block-scoping](http://babeljs.io/docs/plugins/transform-block-scoping) plugin. + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["@babel/plugin-transform-parameters"] +} +``` + +### Via CLI + +```sh +babel --plugins @babel/plugin-transform-parameters script.js +``` + +### Via Node API + +```javascript +require("@babel/core").transform("code", { + plugins: ["@babel/plugin-transform-parameters"] +}); +``` + +## Options + +### `loose` + +`boolean`, defaults to `false`. + +In loose mode, parameters with default values will be counted into the arity of the function. This is not spec behavior where these parameters do not add to function arity. + +The `loose` implementation is a more performant solution as JavaScript engines will fully optimize a function that doesn't reference `arguments`. Please do your own benchmarking and determine if this option is the right fit for your application. + +```javascript +// Spec behavior +function bar1 (arg1 = 1) {} +bar1.length // 0 + +// Loose mode +function bar1 (arg1 = 1) {} +bar1.length // 1 +``` diff --git a/node_modules/@babel/plugin-transform-parameters/lib/index.js b/node_modules/@babel/plugin-transform-parameters/lib/index.js new file mode 100644 index 00000000..9d21bad0 --- /dev/null +++ b/node_modules/@babel/plugin-transform-parameters/lib/index.js @@ -0,0 +1,46 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +function _helperPluginUtils() { + const data = require("@babel/helper-plugin-utils"); + + _helperPluginUtils = function _helperPluginUtils() { + return data; + }; + + return data; +} + +var _params = _interopRequireDefault(require("./params")); + +var _rest = _interopRequireDefault(require("./rest")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _helperPluginUtils().declare)((api, options) => { + api.assertVersion(7); + const loose = options.loose; + return { + visitor: { + Function(path) { + if (path.isArrowFunctionExpression() && path.get("params").some(param => param.isRestElement() || param.isAssignmentPattern())) { + path.arrowFunctionToExpression(); + } + + const convertedRest = (0, _rest.default)(path); + const convertedParams = (0, _params.default)(path, loose); + + if (convertedRest || convertedParams) { + path.scope.crawl(); + } + } + + } + }; +}); + +exports.default = _default;
\ No newline at end of file diff --git a/node_modules/@babel/plugin-transform-parameters/lib/params.js b/node_modules/@babel/plugin-transform-parameters/lib/params.js new file mode 100644 index 00000000..3563e08e --- /dev/null +++ b/node_modules/@babel/plugin-transform-parameters/lib/params.js @@ -0,0 +1,163 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = convertFunctionParams; + +function _helperCallDelegate() { + const data = _interopRequireDefault(require("@babel/helper-call-delegate")); + + _helperCallDelegate = function _helperCallDelegate() { + return data; + }; + + return data; +} + +function _core() { + const data = require("@babel/core"); + + _core = function _core() { + return data; + }; + + return data; +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const buildDefaultParam = (0, _core().template)(` + let VARIABLE_NAME = + arguments.length > ARGUMENT_KEY && arguments[ARGUMENT_KEY] !== undefined ? + arguments[ARGUMENT_KEY] + : + DEFAULT_VALUE; +`); +const buildLooseDefaultParam = (0, _core().template)(` + if (ASSIGNMENT_IDENTIFIER === UNDEFINED) { + ASSIGNMENT_IDENTIFIER = DEFAULT_VALUE; + } +`); +const buildLooseDestructuredDefaultParam = (0, _core().template)(` + let ASSIGNMENT_IDENTIFIER = PARAMETER_NAME === UNDEFINED ? DEFAULT_VALUE : PARAMETER_NAME ; +`); +const buildSafeArgumentsAccess = (0, _core().template)(` + let $0 = arguments.length > $1 ? arguments[$1] : undefined; +`); + +function isSafeBinding(scope, node) { + if (!scope.hasOwnBinding(node.name)) return true; + + const _scope$getOwnBinding = scope.getOwnBinding(node.name), + kind = _scope$getOwnBinding.kind; + + return kind === "param" || kind === "local"; +} + +const iifeVisitor = { + ReferencedIdentifier(path, state) { + const scope = path.scope, + node = path.node; + + if (node.name === "eval" || !isSafeBinding(scope, node)) { + state.iife = true; + path.stop(); + } + }, + + Scope(path) { + path.skip(); + } + +}; + +function convertFunctionParams(path, loose) { + const node = path.node, + scope = path.scope; + const state = { + iife: false, + scope: scope + }; + const body = []; + const params = path.get("params"); + let firstOptionalIndex = null; + + for (let i = 0; i < params.length; i++) { + const param = params[i]; + + if (param.isAssignmentPattern() && loose) { + const left = param.get("left"); + const right = param.get("right"); + const undefinedNode = scope.buildUndefinedNode(); + + if (left.isIdentifier()) { + body.push(buildLooseDefaultParam({ + ASSIGNMENT_IDENTIFIER: _core().types.cloneNode(left.node), + DEFAULT_VALUE: right.node, + UNDEFINED: undefinedNode + })); + param.replaceWith(left.node); + } else if (left.isObjectPattern() || left.isArrayPattern()) { + const paramName = scope.generateUidIdentifier(); + body.push(buildLooseDestructuredDefaultParam({ + ASSIGNMENT_IDENTIFIER: left.node, + DEFAULT_VALUE: right.node, + PARAMETER_NAME: _core().types.cloneNode(paramName), + UNDEFINED: undefinedNode + })); + param.replaceWith(paramName); + } + } else if (param.isAssignmentPattern()) { + if (firstOptionalIndex === null) firstOptionalIndex = i; + const left = param.get("left"); + const right = param.get("right"); + + if (!state.iife) { + if (right.isIdentifier() && !isSafeBinding(scope, right.node)) { + state.iife = true; + } else { + right.traverse(iifeVisitor, state); + } + } + + const defNode = buildDefaultParam({ + VARIABLE_NAME: left.node, + DEFAULT_VALUE: right.node, + ARGUMENT_KEY: _core().types.numericLiteral(i) + }); + body.push(defNode); + } else if (firstOptionalIndex !== null) { + const defNode = buildSafeArgumentsAccess([param.node, _core().types.numericLiteral(i)]); + body.push(defNode); + } else if (param.isObjectPattern() || param.isArrayPattern()) { + const uid = path.scope.generateUidIdentifier("ref"); + + const defNode = _core().types.variableDeclaration("let", [_core().types.variableDeclarator(param.node, uid)]); + + body.push(defNode); + param.replaceWith(_core().types.cloneNode(uid)); + } + + if (!state.iife && !param.isIdentifier()) { + param.traverse(iifeVisitor, state); + } + } + + if (body.length === 0) return false; + + if (firstOptionalIndex !== null) { + node.params = node.params.slice(0, firstOptionalIndex); + } + + path.ensureBlock(); + + if (state.iife) { + body.push((0, _helperCallDelegate().default)(path, scope)); + path.set("body", _core().types.blockStatement(body)); + } else { + path.get("body").unshiftContainer("body", body); + } + + return true; +}
\ No newline at end of file diff --git a/node_modules/@babel/plugin-transform-parameters/lib/rest.js b/node_modules/@babel/plugin-transform-parameters/lib/rest.js new file mode 100644 index 00000000..82238e81 --- /dev/null +++ b/node_modules/@babel/plugin-transform-parameters/lib/rest.js @@ -0,0 +1,286 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = convertFunctionRest; + +function _core() { + const data = require("@babel/core"); + + _core = function _core() { + return data; + }; + + return data; +} + +const buildRest = (0, _core().template)(` + for (var LEN = ARGUMENTS.length, + ARRAY = new Array(ARRAY_LEN), + KEY = START; + KEY < LEN; + KEY++) { + ARRAY[ARRAY_KEY] = ARGUMENTS[KEY]; + } +`); +const restIndex = (0, _core().template)(` + (INDEX < OFFSET || ARGUMENTS.length <= INDEX) ? undefined : ARGUMENTS[INDEX] +`); +const restIndexImpure = (0, _core().template)(` + REF = INDEX, (REF < OFFSET || ARGUMENTS.length <= REF) ? undefined : ARGUMENTS[REF] +`); +const restLength = (0, _core().template)(` + ARGUMENTS.length <= OFFSET ? 0 : ARGUMENTS.length - OFFSET +`); + +function referencesRest(path, state) { + if (path.node.name === state.name) { + return path.scope.bindingIdentifierEquals(state.name, state.outerBinding); + } + + return false; +} + +const memberExpressionOptimisationVisitor = { + Scope(path, state) { + if (!path.scope.bindingIdentifierEquals(state.name, state.outerBinding)) { + path.skip(); + } + }, + + Flow(path) { + if (path.isTypeCastExpression()) return; + path.skip(); + }, + + Function(path, state) { + const oldNoOptimise = state.noOptimise; + state.noOptimise = true; + path.traverse(memberExpressionOptimisationVisitor, state); + state.noOptimise = oldNoOptimise; + path.skip(); + }, + + ReferencedIdentifier(path, state) { + const node = path.node; + + if (node.name === "arguments") { + state.deopted = true; + } + + if (!referencesRest(path, state)) return; + + if (state.noOptimise) { + state.deopted = true; + } else { + const parentPath = path.parentPath; + + if (parentPath.listKey === "params" && parentPath.key < state.offset) { + return; + } + + if (parentPath.isMemberExpression({ + object: node + })) { + const grandparentPath = parentPath.parentPath; + const argsOptEligible = !state.deopted && !(grandparentPath.isAssignmentExpression() && parentPath.node === grandparentPath.node.left || grandparentPath.isLVal() || grandparentPath.isForXStatement() || grandparentPath.isUpdateExpression() || grandparentPath.isUnaryExpression({ + operator: "delete" + }) || (grandparentPath.isCallExpression() || grandparentPath.isNewExpression()) && parentPath.node === grandparentPath.node.callee); + + if (argsOptEligible) { + if (parentPath.node.computed) { + if (parentPath.get("property").isBaseType("number")) { + state.candidates.push({ + cause: "indexGetter", + path + }); + return; + } + } else if (parentPath.node.property.name === "length") { + state.candidates.push({ + cause: "lengthGetter", + path + }); + return; + } + } + } + + if (state.offset === 0 && parentPath.isSpreadElement()) { + const call = parentPath.parentPath; + + if (call.isCallExpression() && call.node.arguments.length === 1) { + state.candidates.push({ + cause: "argSpread", + path + }); + return; + } + } + + state.references.push(path); + } + }, + + BindingIdentifier(path, state) { + if (referencesRest(path, state)) { + state.deopted = true; + } + } + +}; + +function hasRest(node) { + const length = node.params.length; + return length > 0 && _core().types.isRestElement(node.params[length - 1]); +} + +function optimiseIndexGetter(path, argsId, offset) { + const offsetLiteral = _core().types.numericLiteral(offset); + + let index; + + if (_core().types.isNumericLiteral(path.parent.property)) { + index = _core().types.numericLiteral(path.parent.property.value + offset); + } else if (offset === 0) { + index = path.parent.property; + } else { + index = _core().types.binaryExpression("+", path.parent.property, _core().types.cloneNode(offsetLiteral)); + } + + const scope = path.scope; + + if (!scope.isPure(index)) { + const temp = scope.generateUidIdentifierBasedOnNode(index); + scope.push({ + id: temp, + kind: "var" + }); + path.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(); + + if (valRes.confident) { + if (valRes.value === true) { + parentPath.replaceWith(parentPath.scope.buildUndefinedNode()); + } else { + parentPath.get("test").replaceWith(parentPath.get("test").get("right")); + } + } + } +} + +function optimiseLengthGetter(path, argsId, offset) { + if (offset) { + path.parentPath.replaceWith(restLength({ + ARGUMENTS: argsId, + OFFSET: _core().types.numericLiteral(offset) + })); + } else { + path.replaceWith(argsId); + } +} + +function convertFunctionRest(path) { + const node = path.node, + scope = path.scope; + if (!hasRest(node)) return false; + const rest = node.params.pop().argument; + + const argsId = _core().types.identifier("arguments"); + + const state = { + references: [], + offset: node.params.length, + argumentsNode: argsId, + outerBinding: scope.getBindingIdentifier(rest.name), + candidates: [], + name: rest.name, + deopted: false + }; + path.traverse(memberExpressionOptimisationVisitor, state); + + if (!state.deopted && !state.references.length) { + var _arr = state.candidates; + + for (var _i = 0; _i < _arr.length; _i++) { + const _ref = _arr[_i]; + const path = _ref.path, + cause = _ref.cause; + + const clonedArgsId = _core().types.cloneNode(argsId); + + switch (cause) { + case "indexGetter": + optimiseIndexGetter(path, clonedArgsId, state.offset); + break; + + case "lengthGetter": + optimiseLengthGetter(path, clonedArgsId, state.offset); + break; + + default: + path.replaceWith(clonedArgsId); + } + } + + return true; + } + + state.references = state.references.concat(state.candidates.map(({ + path + }) => path)); + + const start = _core().types.numericLiteral(node.params.length); + + const key = scope.generateUidIdentifier("key"); + const len = scope.generateUidIdentifier("len"); + let arrKey, arrLen; + + if (node.params.length) { + arrKey = _core().types.binaryExpression("-", _core().types.cloneNode(key), _core().types.cloneNode(start)); + arrLen = _core().types.conditionalExpression(_core().types.binaryExpression(">", _core().types.cloneNode(len), _core().types.cloneNode(start)), _core().types.binaryExpression("-", _core().types.cloneNode(len), _core().types.cloneNode(start)), _core().types.numericLiteral(0)); + } else { + arrKey = _core().types.identifier(key.name); + arrLen = _core().types.identifier(len.name); + } + + const loop = buildRest({ + ARGUMENTS: argsId, + ARRAY_KEY: arrKey, + ARRAY_LEN: arrLen, + START: start, + ARRAY: rest, + KEY: key, + LEN: len + }); + + if (state.deopted) { + node.body.body.unshift(loop); + } else { + let target = path.getEarliestCommonAncestorFrom(state.references).getStatementParent(); + target.findParent(path => { + if (path.isLoop()) { + target = path; + } else { + return path.isFunction(); + } + }); + target.insertBefore(loop); + } + + return true; +}
\ No newline at end of file diff --git a/node_modules/@babel/plugin-transform-parameters/package.json b/node_modules/@babel/plugin-transform-parameters/package.json new file mode 100644 index 00000000..6d9e2881 --- /dev/null +++ b/node_modules/@babel/plugin-transform-parameters/package.json @@ -0,0 +1,23 @@ +{ + "name": "@babel/plugin-transform-parameters", + "version": "7.0.0-beta.47", + "description": "Compile ES2015 default and rest parameters to ES5", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-parameters", + "license": "MIT", + "main": "lib/index.js", + "dependencies": { + "@babel/helper-call-delegate": "7.0.0-beta.47", + "@babel/helper-get-function-arity": "7.0.0-beta.47", + "@babel/helper-plugin-utils": "7.0.0-beta.47" + }, + "keywords": [ + "babel-plugin" + ], + "peerDependencies": { + "@babel/core": "7.0.0-beta.47" + }, + "devDependencies": { + "@babel/core": "7.0.0-beta.47", + "@babel/helper-plugin-test-runner": "7.0.0-beta.47" + } +} |
