mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
159 lines
4.2 KiB
JavaScript
159 lines
4.2 KiB
JavaScript
/**
|
|
* Copyright 2013 Facebook, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*global exports:true*/
|
|
|
|
/**
|
|
* Desugars ES6 Arrow functions to ES3 function expressions.
|
|
* If the function contains `this` expression -- automatically
|
|
* binds the function to current value of `this`.
|
|
*
|
|
* Single parameter, simple expression:
|
|
*
|
|
* [1, 2, 3].map(x => x * x);
|
|
*
|
|
* [1, 2, 3].map(function(x) { return x * x; });
|
|
*
|
|
* Several parameters, complex block:
|
|
*
|
|
* this.users.forEach((user, idx) => {
|
|
* return this.isActive(idx) && this.send(user);
|
|
* });
|
|
*
|
|
* this.users.forEach(function(user, idx) {
|
|
* return this.isActive(idx) && this.send(user);
|
|
* }.bind(this));
|
|
*
|
|
*/
|
|
var restParamVisitors = require('./es6-rest-param-visitors');
|
|
var destructuringVisitors = require('./es6-destructuring-visitors');
|
|
|
|
var Syntax = require('esprima-fb').Syntax;
|
|
var utils = require('../src/utils');
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
function visitArrowFunction(traverse, node, path, state) {
|
|
var notInExpression = (path[0].type === Syntax.ExpressionStatement);
|
|
|
|
// Wrap a function into a grouping operator, if it's not
|
|
// in the expression position.
|
|
if (notInExpression) {
|
|
utils.append('(', state);
|
|
}
|
|
|
|
utils.append('function', state);
|
|
renderParams(traverse, node, path, state);
|
|
|
|
// Skip arrow.
|
|
utils.catchupWhiteSpace(node.body.range[0], state);
|
|
|
|
var renderBody = node.body.type == Syntax.BlockStatement
|
|
? renderStatementBody
|
|
: renderExpressionBody;
|
|
|
|
path.unshift(node);
|
|
renderBody(traverse, node, path, state);
|
|
path.shift();
|
|
|
|
// Bind the function only if `this` value is used
|
|
// inside it or inside any sub-expression.
|
|
var containsBindingSyntax =
|
|
utils.containsChildMatching(node.body, function(node) {
|
|
return node.type === Syntax.ThisExpression
|
|
|| (node.type === Syntax.Identifier
|
|
&& node.name === "super");
|
|
});
|
|
|
|
if (containsBindingSyntax) {
|
|
utils.append('.bind(this)', state);
|
|
}
|
|
|
|
utils.catchupWhiteSpace(node.range[1], state);
|
|
|
|
// Close wrapper if not in the expression.
|
|
if (notInExpression) {
|
|
utils.append(')', state);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function renderParams(traverse, node, path, state) {
|
|
// To preserve inline typechecking directives, we
|
|
// distinguish between parens-free and paranthesized single param.
|
|
if (isParensFreeSingleParam(node, state) || !node.params.length) {
|
|
utils.append('(', state);
|
|
}
|
|
if (node.params.length !== 0) {
|
|
path.unshift(node);
|
|
traverse(node.params, path, state);
|
|
path.unshift();
|
|
}
|
|
utils.append(')', state);
|
|
}
|
|
|
|
function isParensFreeSingleParam(node, state) {
|
|
return node.params.length === 1 &&
|
|
state.g.source[state.g.position] !== '(';
|
|
}
|
|
|
|
function renderExpressionBody(traverse, node, path, state) {
|
|
// Wrap simple expression bodies into a block
|
|
// with explicit return statement.
|
|
utils.append('{', state);
|
|
|
|
// Special handling of rest param.
|
|
if (node.rest) {
|
|
utils.append(
|
|
restParamVisitors.renderRestParamSetup(node, state),
|
|
state
|
|
);
|
|
}
|
|
|
|
// Special handling of destructured params.
|
|
destructuringVisitors.renderDestructuredComponents(
|
|
node,
|
|
utils.updateState(state, {
|
|
localScope: {
|
|
parentNode: state.parentNode,
|
|
parentScope: state.parentScope,
|
|
identifiers: state.identifiers,
|
|
tempVarIndex: 0
|
|
}
|
|
})
|
|
);
|
|
|
|
utils.append('return ', state);
|
|
renderStatementBody(traverse, node, path, state);
|
|
utils.append(';}', state);
|
|
}
|
|
|
|
function renderStatementBody(traverse, node, path, state) {
|
|
traverse(node.body, path, state);
|
|
utils.catchup(node.body.range[1], state);
|
|
}
|
|
|
|
visitArrowFunction.test = function(node, path, state) {
|
|
return node.type === Syntax.ArrowFunctionExpression;
|
|
};
|
|
|
|
exports.visitorList = [
|
|
visitArrowFunction
|
|
];
|
|
|