es7-rest-property-helpers.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /**
  2. * Copyright 2013-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. /*jslint node:true*/
  10. /**
  11. * Desugars ES7 rest properties into ES5 object iteration.
  12. */
  13. var Syntax = require('esprima-fb').Syntax;
  14. // TODO: This is a pretty massive helper, it should only be defined once, in the
  15. // transform's runtime environment. We don't currently have a runtime though.
  16. var restFunction =
  17. '(function(source, exclusion) {' +
  18. 'var rest = {};' +
  19. 'var hasOwn = Object.prototype.hasOwnProperty;' +
  20. 'if (source == null) {' +
  21. 'throw new TypeError();' +
  22. '}' +
  23. 'for (var key in source) {' +
  24. 'if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {' +
  25. 'rest[key] = source[key];' +
  26. '}' +
  27. '}' +
  28. 'return rest;' +
  29. '})';
  30. function getPropertyNames(properties) {
  31. var names = [];
  32. for (var i = 0; i < properties.length; i++) {
  33. var property = properties[i];
  34. if (property.type === Syntax.SpreadProperty) {
  35. continue;
  36. }
  37. if (property.type === Syntax.Identifier) {
  38. names.push(property.name);
  39. } else {
  40. names.push(property.key.name);
  41. }
  42. }
  43. return names;
  44. }
  45. function getRestFunctionCall(source, exclusion) {
  46. return restFunction + '(' + source + ',' + exclusion + ')';
  47. }
  48. function getSimpleShallowCopy(accessorExpression) {
  49. // This could be faster with 'Object.assign({}, ' + accessorExpression + ')'
  50. // but to unify code paths and avoid a ES6 dependency we use the same
  51. // helper as for the exclusion case.
  52. return getRestFunctionCall(accessorExpression, '{}');
  53. }
  54. function renderRestExpression(accessorExpression, excludedProperties) {
  55. var excludedNames = getPropertyNames(excludedProperties);
  56. if (!excludedNames.length) {
  57. return getSimpleShallowCopy(accessorExpression);
  58. }
  59. return getRestFunctionCall(
  60. accessorExpression,
  61. '{' + excludedNames.join(':1,') + ':1}'
  62. );
  63. }
  64. exports.renderRestExpression = renderRestExpression;