es6-object-computed-property-visitors.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. var es6ObjectConciseMethods = require('./es6-object-concise-method-visitors');
  11. var es7SpreadProperties = require('./es7-spread-property-visitors');
  12. var Syntax = require('esprima-fb').Syntax;
  13. var utils = require('../src/utils');
  14. function process(traverse, node, path, state) {
  15. utils.catchupWhiteSpace(node.range[0], state);
  16. traverse(node, path, state);
  17. utils.catchup(node.range[1], state);
  18. }
  19. /**
  20. * Note: This visitor is capable of handling the following transforms too:
  21. * - ES7 object literal spread,
  22. * - ES6 object concise methods,
  23. * - ES6 object short notation,
  24. * This is because of limitations in the jstransform framework, which isn't
  25. * capable of feeding the output of one visitor to another. Additionally,
  26. * any attempt to share logic between these visitors only increases code
  27. * complixity. And so, we are forced to create a single complex one that
  28. * handles all cases.
  29. *
  30. * {alpha: 12, \'beta\': 34, ['gam' + 'ma']: 56} // before
  31. * (_={},_.alpha=12,_['beta']=34,_['gam' + 'ma']=56,_) // after
  32. */
  33. function es6ObjectComputedProperties(traverse, node, path, state) {
  34. var obj = utils.injectTempVar(state);
  35. utils.append('(' + obj + '={}', state);
  36. for (var ii = 0; ii < node.properties.length; ++ii) {
  37. var property = node.properties[ii];
  38. utils.append(',', state);
  39. if (property.type === Syntax.SpreadProperty) {
  40. utils.append('Object.assign(' + obj, state);
  41. var nextComputedPropertyIndex = ii + 1;
  42. while (
  43. nextComputedPropertyIndex < node.properties.length &&
  44. !node.properties[nextComputedPropertyIndex].computed
  45. ) {
  46. nextComputedPropertyIndex += 1;
  47. }
  48. utils.catchupWhiteSpace(node.properties[ii].range[0], state);
  49. var lastWasSpread = es7SpreadProperties.renderSpreadProperties(
  50. traverse,
  51. node.properties.slice(ii, nextComputedPropertyIndex),
  52. path,
  53. state,
  54. true // previousWasSpread
  55. );
  56. utils.append((lastWasSpread ? '' : '}') + ')', state);
  57. ii = nextComputedPropertyIndex - 1;
  58. continue;
  59. // short notation / dot access
  60. } else if (
  61. property.type === Syntax.Property &&
  62. property.key.type === Syntax.Identifier &&
  63. !property.computed
  64. ) {
  65. utils.append(obj + '.' + property.key.name + '=', state);
  66. // literals / computed properties
  67. } else if (property.type === Syntax.Property) {
  68. utils.append(obj + '[', state);
  69. process(traverse, property.key, path, state);
  70. utils.append(']=', state);
  71. }
  72. // concise methods
  73. if (property.method === true) {
  74. utils.catchupWhiteSpace(property.key.range[1], state);
  75. es6ObjectConciseMethods.renderConciseMethod(traverse, property, path, state);
  76. }
  77. process(traverse, property.value, path, state);
  78. }
  79. utils.catchupWhiteSpace(node.range[1], state);
  80. utils.append(',' + obj + ')', state);
  81. return false;
  82. }
  83. es6ObjectComputedProperties.test = function(node, path, state) {
  84. if (node.type !== Syntax.ObjectExpression) {
  85. return false;
  86. }
  87. for (var ii = 0; ii < node.properties.length; ++ii) {
  88. if (node.properties[ii].computed) {
  89. return true;
  90. }
  91. }
  92. return false;
  93. };
  94. exports.visitorList = [
  95. es6ObjectComputedProperties,
  96. ];