react / wstein / node_modules / react / node_modules / envify / node_modules / jstransform / visitors / es6-arrow-function-visitors.js
80540 views/**1* Copyright 2013 Facebook, Inc.2*3* Licensed under the Apache License, Version 2.0 (the "License");4* you may not use this file except in compliance with the License.5* You may obtain a copy of the License at6*7* http://www.apache.org/licenses/LICENSE-2.08*9* Unless required by applicable law or agreed to in writing, software10* distributed under the License is distributed on an "AS IS" BASIS,11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12* See the License for the specific language governing permissions and13* limitations under the License.14*/1516/*global exports:true*/1718/**19* Desugars ES6 Arrow functions to ES3 function expressions.20* If the function contains `this` expression -- automatically21* binds the function to current value of `this`.22*23* Single parameter, simple expression:24*25* [1, 2, 3].map(x => x * x);26*27* [1, 2, 3].map(function(x) { return x * x; });28*29* Several parameters, complex block:30*31* this.users.forEach((user, idx) => {32* return this.isActive(idx) && this.send(user);33* });34*35* this.users.forEach(function(user, idx) {36* return this.isActive(idx) && this.send(user);37* }.bind(this));38*39*/40var restParamVisitors = require('./es6-rest-param-visitors');41var destructuringVisitors = require('./es6-destructuring-visitors');4243var Syntax = require('esprima-fb').Syntax;44var utils = require('../src/utils');4546/**47* @public48*/49function visitArrowFunction(traverse, node, path, state) {50var notInExpression = (path[0].type === Syntax.ExpressionStatement);5152// Wrap a function into a grouping operator, if it's not53// in the expression position.54if (notInExpression) {55utils.append('(', state);56}5758utils.append('function', state);59renderParams(traverse, node, path, state);6061// Skip arrow.62utils.catchupWhiteSpace(node.body.range[0], state);6364var renderBody = node.body.type == Syntax.BlockStatement65? renderStatementBody66: renderExpressionBody;6768path.unshift(node);69renderBody(traverse, node, path, state);70path.shift();7172// Bind the function only if `this` value is used73// inside it or inside any sub-expression.74var containsBindingSyntax =75utils.containsChildMatching(node.body, function(node) {76return node.type === Syntax.ThisExpression77|| (node.type === Syntax.Identifier78&& node.name === "super");79});8081if (containsBindingSyntax) {82utils.append('.bind(this)', state);83}8485utils.catchupWhiteSpace(node.range[1], state);8687// Close wrapper if not in the expression.88if (notInExpression) {89utils.append(')', state);90}9192return false;93}9495function renderParams(traverse, node, path, state) {96// To preserve inline typechecking directives, we97// distinguish between parens-free and paranthesized single param.98if (isParensFreeSingleParam(node, state) || !node.params.length) {99utils.append('(', state);100}101if (node.params.length !== 0) {102path.unshift(node);103traverse(node.params, path, state);104path.unshift();105}106utils.append(')', state);107}108109function isParensFreeSingleParam(node, state) {110return node.params.length === 1 &&111state.g.source[state.g.position] !== '(';112}113114function renderExpressionBody(traverse, node, path, state) {115// Wrap simple expression bodies into a block116// with explicit return statement.117utils.append('{', state);118119// Special handling of rest param.120if (node.rest) {121utils.append(122restParamVisitors.renderRestParamSetup(node, state),123state124);125}126127// Special handling of destructured params.128destructuringVisitors.renderDestructuredComponents(129node,130utils.updateState(state, {131localScope: {132parentNode: state.parentNode,133parentScope: state.parentScope,134identifiers: state.identifiers,135tempVarIndex: 0136}137})138);139140utils.append('return ', state);141renderStatementBody(traverse, node, path, state);142utils.append(';}', state);143}144145function renderStatementBody(traverse, node, path, state) {146traverse(node.body, path, state);147utils.catchup(node.body.range[1], state);148}149150visitArrowFunction.test = function(node, path, state) {151return node.type === Syntax.ArrowFunctionExpression;152};153154exports.visitorList = [155visitArrowFunction156];157158159160