es7-trailing-comma-visitors.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. var Syntax = require('esprima-fb').Syntax;
  10. var utils = require('../src/utils');
  11. /**
  12. * Strips trailing commas from function calls. Transforms:
  13. *
  14. * foo('bar',)
  15. *
  16. * into:
  17. *
  18. * foo('bar')
  19. */
  20. function visitFunctionCallArguments(traverse, node, path, state) {
  21. utils.catchup(node.callee.range[0], state);
  22. traverse(node.callee, [node].concat(path), state);
  23. var args = node['arguments'];
  24. for (var index = 0; index < args.length; ++index) {
  25. utils.catchup(args[index].range[0], state);
  26. traverse(args[index], [node].concat(path), state);
  27. utils.catchup(args[index].range[1], state);
  28. }
  29. // delete first comma between the last argument and the closing parenthesis
  30. utils.catchup(node.range[1], state, function(value) {
  31. return value.replace(",", '');
  32. });
  33. return false;
  34. }
  35. visitFunctionCallArguments.test = function(node, path, state) {
  36. return (
  37. node.type === Syntax.CallExpression ||
  38. node.type === Syntax.NewExpression
  39. ) && (
  40. node['arguments'].length > 0
  41. );
  42. };
  43. /**
  44. * Strips trailing commas from function expressions / function declarations /
  45. * method calls. Transforms:
  46. *
  47. * var fnExp = function(bar,) { ... };
  48. * function fnDec(bar,) { ... };
  49. * class Test { foo(bar, ) { ... } };
  50. *
  51. * into:
  52. *
  53. * var fnExp = function(bar) { ... };
  54. * function fnDec(bar) { ... };
  55. * class Test { foo(bar) { ... } };
  56. */
  57. function visitFunctionDefinitionArguments(traverse, node, path, state) {
  58. var end = node.range[1];
  59. if (node.type === Syntax.MethodDefinition) {
  60. node = node.value;
  61. }
  62. for (var index = 0; index < node.params.length; ++index) {
  63. utils.catchup(node.params[index].range[0], state);
  64. traverse(node.params[index], [node].concat(path), state);
  65. utils.catchup(node.params[index].range[1], state);
  66. }
  67. // delete first comma between the last argument and the closing parenthesis
  68. utils.catchup(node.body.range[0], state, function(value) {
  69. var commaIndex = value.substr(0, value.indexOf(")")).indexOf(",");
  70. return commaIndex > -1 ? value.replace(/,/, '') : value;
  71. });
  72. traverse(node.body, [node].concat(path), state);
  73. utils.catchup(end, state);
  74. return false;
  75. }
  76. visitFunctionDefinitionArguments.test = function(node, path, state) {
  77. return (
  78. node.type === Syntax.FunctionExpression ||
  79. node.type === Syntax.FunctionDeclaration ||
  80. node.type === Syntax.MethodDefinition
  81. ) && (
  82. node.params && node.params.length > 0 || // function expression/declaration
  83. node.value && node.value.params.length > 0 // method definition
  84. );
  85. };
  86. exports.visitorList = [
  87. visitFunctionCallArguments,
  88. visitFunctionDefinitionArguments,
  89. ];