/** * 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. */ /*jslint node:true*/ /** * Desugars ES7 rest properties into ES5 object iteration. */ var Syntax = require('esprima-fb').Syntax; // TODO: This is a pretty massive helper, it should only be defined once, in the // transform's runtime environment. We don't currently have a runtime though. var restFunction = '(function(source, exclusion) {' + 'var rest = {};' + 'var hasOwn = Object.prototype.hasOwnProperty;' + 'if (source == null) {' + 'throw new TypeError();' + '}' + 'for (var key in source) {' + 'if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {' + 'rest[key] = source[key];' + '}' + '}' + 'return rest;' + '})'; function getPropertyNames(properties) { var names = []; for (var i = 0; i < properties.length; i++) { var property = properties[i]; if (property.type === Syntax.SpreadProperty) { continue; } if (property.type === Syntax.Identifier) { names.push(property.name); } else { names.push(property.key.name); } } return names; } function getRestFunctionCall(source, exclusion) { return restFunction + '(' + source + ',' + exclusion + ')'; } function getSimpleShallowCopy(accessorExpression) { // This could be faster with 'Object.assign({}, ' + accessorExpression + ')' // but to unify code paths and avoid a ES6 dependency we use the same // helper as for the exclusion case. return getRestFunctionCall(accessorExpression, '{}'); } function renderRestExpression(accessorExpression, excludedProperties) { var excludedNames = getPropertyNames(excludedProperties); if (!excludedNames.length) { return getSimpleShallowCopy(accessorExpression); } return getRestFunctionCall( accessorExpression, '{' + excludedNames.join(':1,') + ':1}' ); } exports.renderRestExpression = renderRestExpression;