From cc9578cca5ef2203b2a076130528eb75d4ae9444 Mon Sep 17 00:00:00 2001 From: Ross <52366381+ROSSROSALES@users.noreply.github.com> Date: Fri, 7 Oct 2022 01:58:56 +0000 Subject: [PATCH] [Fix] `sort-prop-types`: avoid crash when autofixing Fixes #3470. --- CHANGELOG.md | 3 +- docs/rules/sort-prop-types.md | 2 ++ lib/util/propTypesSort.js | 34 ++++++++++---------- tests/lib/rules/sort-prop-types.js | 50 ++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a8f732dc3..4aad7555d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Fixed * configs: avoid legacy config system error ([#3461][] @ljharb) -* [`sort-prop-types`]: restore autofixing ([#3452][] @ROSSROSALES) +* [`sort-prop-types`]: restore autofixing ([#3452][], [#3471][] @ROSSROSALES) * [`no-unknown-property`]: do not check `fbs` elements ([#3494][] @brianogilvie) * [`jsx-newline`]: No newline between comments and jsx elements ([#3493][] @justmejulian) * [`jsx-no-leaked-render`]: Don't report errors on empty strings if React >= v18 ([#3488][] @himanshu007-creator) @@ -24,6 +24,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange [#3494]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3494 [#3493]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3493 [#3488]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3488 +[#3471]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3471 [#3468]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3468 [#3461]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3461 [#3452]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3452 diff --git a/docs/rules/sort-prop-types.md b/docs/rules/sort-prop-types.md index 3f973fad50..ec3d9f2d71 100644 --- a/docs/rules/sort-prop-types.md +++ b/docs/rules/sort-prop-types.md @@ -4,6 +4,8 @@ +🔧 This rule is automatically fixable using the `--fix` [flag](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + Some developers prefer to sort prop type declarations alphabetically to be able to find necessary declaration easier at the later time. Others feel that it adds complexity and becomes burden to maintain. ## Rule Details diff --git a/lib/util/propTypesSort.js b/lib/util/propTypesSort.js index 0bf8998128..d5c7a3e44b 100644 --- a/lib/util/propTypesSort.js +++ b/lib/util/propTypesSort.js @@ -127,29 +127,27 @@ function fixPropTypesSort(fixer, context, declarations, ignoreCase, requiredFirs const node = allNodes[i]; let commentAfter = []; let commentBefore = []; + let newStart = 0; + let newEnd = 0; try { commentBefore = sourceCode.getCommentsBefore(node); commentAfter = sourceCode.getCommentsAfter(node); } catch (e) { /**/ } - if (commentAfter.length === 0 && commentBefore.length === 0) { - commentnodeMap.set(node, { start: node.range[0], end: node.range[1], hasComment: false }); - } else { - const firstCommentBefore = commentBefore[0]; - if (commentBefore.length === 1) { - commentnodeMap.set(node, { start: firstCommentBefore.range[0], end: node.range[1], hasComment: true }); - } - const firstCommentAfter = commentAfter[0]; - if (commentAfter.length === 1) { - commentnodeMap.set(node, { start: node.range[0], end: firstCommentAfter.range[1], hasComment: true }); - } - if (commentBefore.length === 1 && commentAfter.length === 1) { - commentnodeMap.set(node, { - start: firstCommentBefore.range[0], - end: firstCommentAfter.range[1], - hasComment: true, - }); - } + + if (commentAfter.length === 0 || commentBefore.length === 0) { + newStart = node.range[0]; + newEnd = node.range[1]; + } + + const firstCommentBefore = commentBefore[0]; + if (commentBefore.length >= 1) { + newStart = firstCommentBefore.range[0]; + } + const lastCommentAfter = commentAfter[commentAfter.length - 1]; + if (commentAfter.length >= 1) { + newEnd = lastCommentAfter.range[1]; } + commentnodeMap.set(node, { start: newStart, end: newEnd, hasComment: true }); } const nodeGroups = allNodes.reduce((acc, curr) => { if (curr.type === 'ExperimentalSpreadProperty' || curr.type === 'SpreadElement') { diff --git a/tests/lib/rules/sort-prop-types.js b/tests/lib/rules/sort-prop-types.js index 8b3ca36442..c0382f45b0 100644 --- a/tests/lib/rules/sort-prop-types.js +++ b/tests/lib/rules/sort-prop-types.js @@ -2098,6 +2098,56 @@ ruleTester.run('sort-prop-types', rule, { type: 'Property', }, ], + } : [], + semver.satisfies(eslintPkg.version, '> 3') ? { + code: ` + var First = createReactClass({ + propTypes: { + /* z */ + /* z */ + z: PropTypes.string /* z */, + /* a */ + a: PropTypes.any /* a */ + /* a */ + /* a */, + b: PropTypes.any + }, + render: function() { + return
; + } + }); + `, + output: ` + var First = createReactClass({ + propTypes: { + /* a */ + a: PropTypes.any /* a */ + /* a */ + /* a */, + b: PropTypes.any, + /* z */ + /* z */ + z: PropTypes.string /* z */ + }, + render: function() { + return
; + } + }); + `, + errors: [ + { + messageId: 'propsNotSorted', + line: 8, + column: 13, + type: 'Property', + }, + { + messageId: 'propsNotSorted', + line: 11, + column: 13, + type: 'Property', + }, + ], } : [] )), });