arrowParens.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports["default"] = void 0;
  6. var getLocation = function getLocation(node) {
  7. return {
  8. end: node.params[node.params.length - 1].loc.end,
  9. start: node.params[0].loc.start
  10. };
  11. };
  12. var isOpeningParenToken = function isOpeningParenToken(token) {
  13. return token.value === '(' && token.type === 'Punctuator';
  14. };
  15. var isClosingParenToken = function isClosingParenToken(token) {
  16. return token.value === ')' && token.type === 'Punctuator';
  17. };
  18. var _default = {
  19. create: function create(context) {
  20. var asNeeded = context.options[0] === 'as-needed';
  21. var requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;
  22. var sourceCode = context.getSourceCode(); // Determines whether a arrow function argument end with `)`
  23. // eslint-disable-next-line complexity
  24. var parens = function parens(node) {
  25. var isAsync = node.async;
  26. var firstTokenOfParam = sourceCode.getFirstToken(node, isAsync ? 1 : 0); // Remove the parenthesis around a parameter
  27. var fixParamsWithParenthesis = function fixParamsWithParenthesis(fixer) {
  28. var paramToken = sourceCode.getTokenAfter(firstTokenOfParam);
  29. /*
  30. * ES8 allows Trailing commas in function parameter lists and calls
  31. * https://github.com/eslint/eslint/issues/8834
  32. */
  33. var closingParenToken = sourceCode.getTokenAfter(paramToken, isClosingParenToken);
  34. var asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null;
  35. var shouldAddSpaceForAsync = asyncToken && asyncToken.range[1] === firstTokenOfParam.range[0];
  36. return fixer.replaceTextRange([firstTokenOfParam.range[0], closingParenToken.range[1]], "".concat(shouldAddSpaceForAsync ? ' ' : '').concat(paramToken.value));
  37. }; // Type parameters without an opening paren is always a parse error, and
  38. // can therefore be safely ignored.
  39. if (node.typeParameters) {
  40. return;
  41. } // Similarly, a predicate always requires parens just like a return type
  42. // does, and therefore this case can also be safely ignored.
  43. if (node.predicate) {
  44. return;
  45. } // "as-needed", { "requireForBlockBody": true }: x => x
  46. if (requireForBlockBody && node.params.length === 1 && node.params[0].type === 'Identifier' && !node.params[0].typeAnnotation && node.body.type !== 'BlockStatement' && !node.returnType) {
  47. if (isOpeningParenToken(firstTokenOfParam)) {
  48. context.report({
  49. fix: fixParamsWithParenthesis,
  50. loc: getLocation(node),
  51. messageId: 'unexpectedParensInline',
  52. node: node
  53. });
  54. }
  55. return;
  56. }
  57. if (requireForBlockBody && node.body.type === 'BlockStatement') {
  58. if (!isOpeningParenToken(firstTokenOfParam)) {
  59. context.report({
  60. fix: function fix(fixer) {
  61. return fixer.replaceText(firstTokenOfParam, "(".concat(firstTokenOfParam.value, ")"));
  62. },
  63. loc: getLocation(node),
  64. messageId: 'expectedParensBlock',
  65. node: node
  66. });
  67. }
  68. return;
  69. } // "as-needed": x => x
  70. if (asNeeded && node.params.length === 1 && node.params[0].type === 'Identifier' && !node.params[0].typeAnnotation && !node.returnType) {
  71. if (isOpeningParenToken(firstTokenOfParam)) {
  72. context.report({
  73. fix: fixParamsWithParenthesis,
  74. loc: getLocation(node),
  75. messageId: 'unexpectedParens',
  76. node: node
  77. });
  78. }
  79. return;
  80. }
  81. if (firstTokenOfParam.type === 'Identifier') {
  82. var after = sourceCode.getTokenAfter(firstTokenOfParam); // (x) => x
  83. if (after.value !== ')') {
  84. context.report({
  85. fix: function fix(fixer) {
  86. return fixer.replaceText(firstTokenOfParam, "(".concat(firstTokenOfParam.value, ")"));
  87. },
  88. loc: getLocation(node),
  89. messageId: 'expectedParens',
  90. node: node
  91. });
  92. }
  93. }
  94. };
  95. return {
  96. ArrowFunctionExpression: parens
  97. };
  98. },
  99. meta: {
  100. docs: {
  101. category: 'ECMAScript 6',
  102. description: 'require parentheses around arrow function arguments',
  103. recommended: false,
  104. url: 'https://eslint.org/docs/rules/arrow-parens'
  105. },
  106. fixable: 'code',
  107. messages: {
  108. expectedParens: 'Expected parentheses around arrow function argument.',
  109. expectedParensBlock: 'Expected parentheses around arrow function argument having a body with curly braces.',
  110. unexpectedParens: 'Unexpected parentheses around single function argument.',
  111. unexpectedParensInline: 'Unexpected parentheses around single function argument having a body with no curly braces.'
  112. },
  113. type: 'layout'
  114. },
  115. schema: [{
  116. "enum": ['always', 'as-needed']
  117. }, {
  118. additionalProperties: false,
  119. properties: {
  120. requireForBlockBody: {
  121. "default": false,
  122. type: 'boolean'
  123. }
  124. },
  125. type: 'object'
  126. }]
  127. };
  128. exports["default"] = _default;
  129. module.exports = exports.default;