Skip to content

Commit 4243dcc

Browse files
ROSSROSALESljharb
authored andcommitted
[Fix] sort-prop-types: avoid crash when autofixing
Fixes #3470.
1 parent dfd64ae commit 4243dcc

File tree

3 files changed

+68
-18
lines changed

3 files changed

+68
-18
lines changed

docs/rules/sort-prop-types.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
<!-- end auto-generated rule header -->
66

7+
🔧 This rule is automatically fixable using the `--fix` [flag](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line.
8+
79
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.
810

911
## Rule Details

lib/util/propTypesSort.js

+16-18
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,27 @@ function fixPropTypesSort(fixer, context, declarations, ignoreCase, requiredFirs
127127
const node = allNodes[i];
128128
let commentAfter = [];
129129
let commentBefore = [];
130+
let newStart = 0;
131+
let newEnd = 0;
130132
try {
131133
commentBefore = sourceCode.getCommentsBefore(node);
132134
commentAfter = sourceCode.getCommentsAfter(node);
133135
} catch (e) { /**/ }
134-
if (commentAfter.length === 0 && commentBefore.length === 0) {
135-
commentnodeMap.set(node, { start: node.range[0], end: node.range[1], hasComment: false });
136-
} else {
137-
const firstCommentBefore = commentBefore[0];
138-
if (commentBefore.length === 1) {
139-
commentnodeMap.set(node, { start: firstCommentBefore.range[0], end: node.range[1], hasComment: true });
140-
}
141-
const firstCommentAfter = commentAfter[0];
142-
if (commentAfter.length === 1) {
143-
commentnodeMap.set(node, { start: node.range[0], end: firstCommentAfter.range[1], hasComment: true });
144-
}
145-
if (commentBefore.length === 1 && commentAfter.length === 1) {
146-
commentnodeMap.set(node, {
147-
start: firstCommentBefore.range[0],
148-
end: firstCommentAfter.range[1],
149-
hasComment: true,
150-
});
151-
}
136+
137+
if (commentAfter.length === 0 || commentBefore.length === 0) {
138+
newStart = node.range[0];
139+
newEnd = node.range[1];
140+
}
141+
142+
const firstCommentBefore = commentBefore[0];
143+
if (commentBefore.length >= 1) {
144+
newStart = firstCommentBefore.range[0];
145+
}
146+
const lastCommentAfter = commentAfter[commentAfter.length - 1];
147+
if (commentAfter.length >= 1) {
148+
newEnd = lastCommentAfter.range[1];
152149
}
150+
commentnodeMap.set(node, { start: newStart, end: newEnd, hasComment: true });
153151
}
154152
const nodeGroups = allNodes.reduce((acc, curr) => {
155153
if (curr.type === 'ExperimentalSpreadProperty' || curr.type === 'SpreadElement') {

tests/lib/rules/sort-prop-types.js

+50
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,56 @@ ruleTester.run('sort-prop-types', rule, {
20982098
type: 'Property',
20992099
},
21002100
],
2101+
} : [],
2102+
semver.satisfies(eslintPkg.version, '> 3') ? {
2103+
code: `
2104+
var First = createReactClass({
2105+
propTypes: {
2106+
/* z */
2107+
/* z */
2108+
z: PropTypes.string /* z */,
2109+
/* a */
2110+
a: PropTypes.any /* a */
2111+
/* a */
2112+
/* a */,
2113+
b: PropTypes.any
2114+
},
2115+
render: function() {
2116+
return <div />;
2117+
}
2118+
});
2119+
`,
2120+
output: `
2121+
var First = createReactClass({
2122+
propTypes: {
2123+
/* a */
2124+
a: PropTypes.any /* a */
2125+
/* a */
2126+
/* a */,
2127+
b: PropTypes.any,
2128+
/* z */
2129+
/* z */
2130+
z: PropTypes.string /* z */
2131+
},
2132+
render: function() {
2133+
return <div />;
2134+
}
2135+
});
2136+
`,
2137+
errors: [
2138+
{
2139+
messageId: 'propsNotSorted',
2140+
line: 8,
2141+
column: 13,
2142+
type: 'Property',
2143+
},
2144+
{
2145+
messageId: 'propsNotSorted',
2146+
line: 11,
2147+
column: 13,
2148+
type: 'Property',
2149+
},
2150+
],
21012151
} : []
21022152
)),
21032153
});

0 commit comments

Comments
 (0)