UNPKG

babel-core

Version:

A compiler for writing next generation JavaScript

165 lines (125 loc) 4.36 kB
"use strict"; exports.__esModule = true; // istanbul ignore next function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } // istanbul ignore next function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _helpersCallDelegate = require("../../../helpers/call-delegate"); var _helpersCallDelegate2 = _interopRequireDefault(_helpersCallDelegate); var _helpersGetFunctionArity = require("../../../helpers/get-function-arity"); var _helpersGetFunctionArity2 = _interopRequireDefault(_helpersGetFunctionArity); var _util = require("../../../../util"); var util = _interopRequireWildcard(_util); var _types = require("../../../../types"); var t = _interopRequireWildcard(_types); /** * [Please add a description.] */ var hasDefaults = function hasDefaults(node) { for (var i = 0; i < node.params.length; i++) { if (!t.isIdentifier(node.params[i])) return true; } return false; }; /** * [Please add a description.] */ var iifeVisitor = { /** * [Please add a description.] */ ReferencedIdentifier: function ReferencedIdentifier(node, parent, scope, state) { if (node.name !== "eval") { if (!state.scope.hasOwnBinding(node.name)) return; if (state.scope.bindingIdentifierEquals(node.name, node)) return; } state.iife = true; this.stop(); } }; /** * [Please add a description.] */ var visitor = { /** * [Please add a description.] */ Function: function Function(node, parent, scope, file) { if (!hasDefaults(node)) return; // ensure it's a block, useful for arrow functions this.ensureBlock(); var state = { iife: false, scope: scope }; var body = []; // var argsIdentifier = t.identifier("arguments"); argsIdentifier._shadowedFunctionLiteral = this; // push a default parameter definition function pushDefNode(left, right, i) { var defNode; if (exceedsLastNonDefault(i) || t.isPattern(left) || file.transformers["es6.spec.blockScoping"].canTransform()) { defNode = util.template("default-parameter", { VARIABLE_NAME: left, DEFAULT_VALUE: right, ARGUMENT_KEY: t.literal(i), ARGUMENTS: argsIdentifier }, true); } else { defNode = util.template("default-parameter-assign", { VARIABLE_NAME: left, DEFAULT_VALUE: right }, true); } defNode._blockHoist = node.params.length - i; body.push(defNode); } // check if an index exceeds the functions arity function exceedsLastNonDefault(i) { return i + 1 > lastNonDefaultParam; } // var lastNonDefaultParam = _helpersGetFunctionArity2["default"](node); // var params = this.get("params"); for (var i = 0; i < params.length; i++) { var param = params[i]; if (!param.isAssignmentPattern()) { if (!param.isIdentifier()) { param.traverse(iifeVisitor, state); } if (file.transformers["es6.spec.blockScoping"].canTransform() && param.isIdentifier()) { pushDefNode(param.node, t.identifier("undefined"), i); } continue; } var left = param.get("left"); var right = param.get("right"); if (exceedsLastNonDefault(i) || left.isPattern()) { var placeholder = scope.generateUidIdentifier("x"); placeholder._isDefaultPlaceholder = true; node.params[i] = placeholder; } else { node.params[i] = left.node; } if (!state.iife) { if (right.isIdentifier() && scope.hasOwnBinding(right.node.name)) { state.iife = true; } else { right.traverse(iifeVisitor, state); } } pushDefNode(left.node, right.node, i); } // we need to cut off all trailing default parameters node.params = node.params.slice(0, lastNonDefaultParam); if (state.iife) { body.push(_helpersCallDelegate2["default"](node, scope)); node.body = t.blockStatement(body); } else { node.body.body = body.concat(node.body.body); } } }; exports.visitor = visitor;