Skip to content

Commit 49c4acf

Browse files
authored
prefer-spread: Insert semicolon if needed (#578)
1 parent ae983e2 commit 49c4acf

File tree

3 files changed

+76
-5
lines changed

3 files changed

+76
-5
lines changed

rules/prefer-spread.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,32 @@ const selector = [
1414
].join('');
1515

1616
const create = context => {
17-
const getSource = node => context.getSourceCode().getText(node);
17+
const sourceCode = context.getSourceCode();
18+
const getSource = node => sourceCode.getText(node);
19+
20+
const needsSemicolon = node => {
21+
const tokenBefore = sourceCode.getTokenBefore(node);
22+
23+
if (tokenBefore) {
24+
const {type, value} = tokenBefore;
25+
if (type === 'Punctuator') {
26+
if (value === ';') {
27+
return false;
28+
}
29+
30+
if (value === ']' || value === ')') {
31+
return true;
32+
}
33+
}
34+
35+
const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]);
36+
if (lastBlockNode && lastBlockNode.type === 'ObjectExpression') {
37+
return true;
38+
}
39+
}
40+
41+
return false;
42+
};
1843

1944
return {
2045
[selector](node) {
@@ -23,7 +48,7 @@ const create = context => {
2348
message: 'Prefer the spread operator over `Array.from()`.',
2449
fix: fixer => {
2550
const [arrayLikeArgument, mapFn, thisArgument] = node.arguments.map(getSource);
26-
let replacement = `[...${arrayLikeArgument}]`;
51+
let replacement = `${needsSemicolon(node) ? ';' : ''}[...${arrayLikeArgument}]`;
2752

2853
if (mapFn) {
2954
const mapArguments = [mapFn, thisArgument].filter(Boolean);

test/integration/test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ const projects = [
100100
'https://github.com/sindresorhus/capture-website',
101101
'https://github.com/sindresorhus/file-type',
102102
'https://github.com/sindresorhus/slugify',
103-
// TODO: add this project when #254 got fixed
104-
// https://github.com/gatsbyjs/gatsby/blob/e720d8efe58eba0f6fae9f26ec8879128967d0b5/packages/gatsby/src/bootstrap/page-hot-reloader.js#L30
105-
// 'https://github.com/gatsbyjs/gatsby',
103+
'https://github.com/gatsbyjs/gatsby',
106104
{
107105
repository: 'https://github.com/puppeteer/puppeteer',
108106
path: 'lib'

test/prefer-spread.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,54 @@ ruleTester.run('prefer-spread', rule, {
123123
}
124124
],
125125
output: '[...document.querySelectorAll("*")].map(() => {});'
126+
},
127+
// #254
128+
{
129+
code: `
130+
const foo = []
131+
Array.from(arrayLike).forEach(doSomething)
132+
`,
133+
errors: [
134+
{
135+
message: 'Prefer the spread operator over `Array.from()`.'
136+
}
137+
],
138+
output: `
139+
const foo = []
140+
;[...arrayLike].forEach(doSomething)
141+
`
142+
},
143+
// https://github.com/gatsbyjs/gatsby/blob/e720d8efe58eba0f6fae9f26ec8879128967d0b5/packages/gatsby/src/bootstrap/page-hot-reloader.js#L30
144+
{
145+
code: `
146+
foo()
147+
Array.from(arrayLike).forEach(doSomething)
148+
`,
149+
errors: [
150+
{
151+
message: 'Prefer the spread operator over `Array.from()`.'
152+
}
153+
],
154+
output: `
155+
foo()
156+
;[...arrayLike].forEach(doSomething)
157+
`
158+
},
159+
// https://github.com/gatsbyjs/gatsby/blob/4ab3f194cf5d6dcafcb2a75d9604aac79d963554/packages/gatsby/src/redux/__tests__/nodes.js#L277
160+
{
161+
code: `
162+
const foo = {}
163+
Array.from(arrayLike).forEach(doSomething)
164+
`,
165+
errors: [
166+
{
167+
message: 'Prefer the spread operator over `Array.from()`.'
168+
}
169+
],
170+
output: `
171+
const foo = {}
172+
;[...arrayLike].forEach(doSomething)
173+
`
126174
}
127175
]
128176
});

0 commit comments

Comments
 (0)