Skip to content

Commit c178ce7

Browse files
authored
fix: extend the autofix range in comma-dangle to ensure the last element (#15669)
Fixes #15660
1 parent edb12e5 commit c178ce7

File tree

2 files changed

+108
-4
lines changed

2 files changed

+108
-4
lines changed

lib/rules/comma-dangle.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,18 @@ module.exports = {
243243
node: lastItem,
244244
loc: trailingToken.loc,
245245
messageId: "unexpected",
246-
fix(fixer) {
247-
return fixer.remove(trailingToken);
246+
*fix(fixer) {
247+
yield fixer.remove(trailingToken);
248+
249+
/*
250+
* Extend the range of the fix to include surrounding tokens to ensure
251+
* that the element after which the comma is removed stays _last_.
252+
* This intentionally makes conflicts in fix ranges with rules that may be
253+
* adding or removing elements in the same autofix pass.
254+
* https://github.com/eslint/eslint/issues/15660
255+
*/
256+
yield fixer.insertTextBefore(sourceCode.getTokenBefore(trailingToken), "");
257+
yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
248258
}
249259
});
250260
}
@@ -282,8 +292,18 @@ module.exports = {
282292
end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end)
283293
},
284294
messageId: "missing",
285-
fix(fixer) {
286-
return fixer.insertTextAfter(trailingToken, ",");
295+
*fix(fixer) {
296+
yield fixer.insertTextAfter(trailingToken, ",");
297+
298+
/*
299+
* Extend the range of the fix to include surrounding tokens to ensure
300+
* that the element after which the comma is inserted stays _last_.
301+
* This intentionally makes conflicts in fix ranges with rules that may be
302+
* adding or removing elements in the same autofix pass.
303+
* https://github.com/eslint/eslint/issues/15660
304+
*/
305+
yield fixer.insertTextBefore(trailingToken, "");
306+
yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
287307
}
288308
});
289309
}

tests/lib/rules/comma-dangle.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//------------------------------------------------------------------------------
1111

1212
const path = require("path"),
13+
{ unIndent } = require("../../_utils"),
1314
rule = require("../../../lib/rules/comma-dangle"),
1415
{ RuleTester } = require("../../../lib/rule-tester");
1516

@@ -35,6 +36,29 @@ function parser(name) {
3536

3637
const ruleTester = new RuleTester();
3738

39+
ruleTester.defineRule("add-named-import", {
40+
meta: {
41+
fixable: "code"
42+
},
43+
create(context) {
44+
return {
45+
ImportDeclaration(node) {
46+
const sourceCode = context.getSourceCode();
47+
const closingBrace = sourceCode.getLastToken(node, token => token.value === "}");
48+
const addComma = sourceCode.getTokenBefore(closingBrace).value !== ",";
49+
50+
context.report({
51+
message: "Add I18nManager.",
52+
node,
53+
fix(fixer) {
54+
return fixer.insertTextBefore(closingBrace, `${addComma ? "," : ""}I18nManager`);
55+
}
56+
});
57+
}
58+
};
59+
}
60+
});
61+
3862
ruleTester.run("comma-dangle", rule, {
3963
valid: [
4064
"var foo = { bar: 'baz' }",
@@ -1766,6 +1790,66 @@ let d = 0;export {d,};
17661790
output: "foo(a)",
17671791
parserOptions: { ecmaVersion: 8 },
17681792
errors: [{ messageId: "unexpected" }]
1793+
},
1794+
1795+
// https://github.com/eslint/eslint/issues/15660
1796+
{
1797+
code: unIndent`
1798+
/*eslint add-named-import:1*/
1799+
import {
1800+
StyleSheet,
1801+
View,
1802+
TextInput,
1803+
ImageBackground,
1804+
Image,
1805+
TouchableOpacity,
1806+
SafeAreaView
1807+
} from 'react-native';
1808+
`,
1809+
output: unIndent`
1810+
/*eslint add-named-import:1*/
1811+
import {
1812+
StyleSheet,
1813+
View,
1814+
TextInput,
1815+
ImageBackground,
1816+
Image,
1817+
TouchableOpacity,
1818+
SafeAreaView,
1819+
} from 'react-native';
1820+
`,
1821+
options: [{ imports: "always-multiline" }],
1822+
parserOptions: { ecmaVersion: 6, sourceType: "module" },
1823+
errors: 2
1824+
},
1825+
{
1826+
code: unIndent`
1827+
/*eslint add-named-import:1*/
1828+
import {
1829+
StyleSheet,
1830+
View,
1831+
TextInput,
1832+
ImageBackground,
1833+
Image,
1834+
TouchableOpacity,
1835+
SafeAreaView,
1836+
} from 'react-native';
1837+
`,
1838+
output: unIndent`
1839+
/*eslint add-named-import:1*/
1840+
import {
1841+
StyleSheet,
1842+
View,
1843+
TextInput,
1844+
ImageBackground,
1845+
Image,
1846+
TouchableOpacity,
1847+
SafeAreaView
1848+
} from 'react-native';
1849+
`,
1850+
options: [{ imports: "never" }],
1851+
parserOptions: { ecmaVersion: 6, sourceType: "module" },
1852+
errors: 2
17691853
}
17701854
]
17711855
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy