Skip to content

Commit e2dc84b

Browse files
authored
feat(order-in-components): add side effects suggestions (#2423)
1 parent 3abc04c commit e2dc84b

File tree

4 files changed

+295
-53
lines changed

4 files changed

+295
-53
lines changed

Diff for: docs/rules/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Rules in this category are enabled for all presets provided by eslint-plugin-vue
181181
| [vue/no-lone-template](./no-lone-template.md) | disallow unnecessary `<template>` | | :three::two::warning: |
182182
| [vue/no-multiple-slot-args](./no-multiple-slot-args.md) | disallow to pass multiple arguments to scoped slots | | :three::two::warning: |
183183
| [vue/no-v-html](./no-v-html.md) | disallow use of v-html to prevent XSS attack | | :three::two::hammer: |
184-
| [vue/order-in-components](./order-in-components.md) | enforce order of properties in components | :wrench: | :three::two::hammer: |
184+
| [vue/order-in-components](./order-in-components.md) | enforce order of properties in components | :wrench::bulb: | :three::two::hammer: |
185185
| [vue/this-in-template](./this-in-template.md) | disallow usage of `this` in template | :wrench: | :three::two::hammer: |
186186

187187
</rules-table>

Diff for: docs/rules/order-in-components.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ since: v3.2.0
1212
1313
- :gear: This rule is included in `"plugin:vue/vue3-recommended"` and `"plugin:vue/recommended"`.
1414
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
15+
- :bulb: Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
1516

1617
## :book: Rule Details
1718

Diff for: lib/rules/order-in-components.js

+58-39
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ module.exports = {
218218
url: 'https://eslint.vuejs.org/rules/order-in-components.html'
219219
},
220220
fixable: 'code', // null or "code" or "whitespace"
221+
hasSuggestions: true,
221222
schema: [
222223
{
223224
type: 'object',
@@ -231,7 +232,9 @@ module.exports = {
231232
],
232233
messages: {
233234
order:
234-
'The "{{name}}" property should be above the "{{firstUnorderedPropertyName}}" property on line {{line}}.'
235+
'The "{{name}}" property should be above the "{{firstUnorderedPropertyName}}" property on line {{line}}.',
236+
reorderWithSideEffects:
237+
'Manually move "{{name}}" property above "{{firstUnorderedPropertyName}}" property on line {{line}} (might break side effects).'
235238
}
236239
},
237240
/** @param {RuleContext} context */
@@ -255,6 +258,30 @@ module.exports = {
255258
return num == null ? -1 : num
256259
}
257260

261+
/**
262+
* @param {Property} propertyNode
263+
* @param {Property} unorderedPropertyNode
264+
*/
265+
function* handleFix(fixer, propertyNode, unorderedPropertyNode) {
266+
const afterComma = sourceCode.getTokenAfter(propertyNode)
267+
const hasAfterComma = isComma(afterComma)
268+
269+
const beforeComma = sourceCode.getTokenBefore(propertyNode)
270+
const codeStart = beforeComma.range[1] // to include comments
271+
const codeEnd = hasAfterComma
272+
? afterComma.range[1]
273+
: propertyNode.range[1]
274+
275+
const removeStart = hasAfterComma ? codeStart : beforeComma.range[0]
276+
yield fixer.removeRange([removeStart, codeEnd])
277+
278+
const propertyCode =
279+
sourceCode.text.slice(codeStart, codeEnd) + (hasAfterComma ? '' : ',')
280+
const insertTarget = sourceCode.getTokenBefore(unorderedPropertyNode)
281+
282+
yield fixer.insertTextAfter(insertTarget, propertyCode)
283+
}
284+
258285
/**
259286
* @param {(Property | SpreadElement)[]} propertiesNodes
260287
*/
@@ -287,6 +314,18 @@ module.exports = {
287314

288315
if (firstUnorderedProperty) {
289316
const line = firstUnorderedProperty.node.loc.start.line
317+
const propertyNode = property.node
318+
const firstUnorderedPropertyNode = firstUnorderedProperty.node
319+
const hasSideEffectsPossibility = propertiesNodes
320+
.slice(
321+
propertiesNodes.indexOf(firstUnorderedPropertyNode),
322+
propertiesNodes.indexOf(propertyNode) + 1
323+
)
324+
.some(
325+
(property) =>
326+
!isNotSideEffectsNode(property, sourceCode.visitorKeys)
327+
)
328+
290329
context.report({
291330
node: property.node,
292331
messageId: 'order',
@@ -295,44 +334,24 @@ module.exports = {
295334
firstUnorderedPropertyName: firstUnorderedProperty.name,
296335
line
297336
},
298-
*fix(fixer) {
299-
const propertyNode = property.node
300-
const firstUnorderedPropertyNode = firstUnorderedProperty.node
301-
const hasSideEffectsPossibility = propertiesNodes
302-
.slice(
303-
propertiesNodes.indexOf(firstUnorderedPropertyNode),
304-
propertiesNodes.indexOf(propertyNode) + 1
305-
)
306-
.some(
307-
(property) =>
308-
!isNotSideEffectsNode(property, sourceCode.visitorKeys)
309-
)
310-
if (hasSideEffectsPossibility) {
311-
return
312-
}
313-
const afterComma = sourceCode.getTokenAfter(propertyNode)
314-
const hasAfterComma = isComma(afterComma)
315-
316-
const beforeComma = sourceCode.getTokenBefore(propertyNode)
317-
const codeStart = beforeComma.range[1] // to include comments
318-
const codeEnd = hasAfterComma
319-
? afterComma.range[1]
320-
: propertyNode.range[1]
321-
322-
const removeStart = hasAfterComma
323-
? codeStart
324-
: beforeComma.range[0]
325-
yield fixer.removeRange([removeStart, codeEnd])
326-
327-
const propertyCode =
328-
sourceCode.text.slice(codeStart, codeEnd) +
329-
(hasAfterComma ? '' : ',')
330-
const insertTarget = sourceCode.getTokenBefore(
331-
firstUnorderedPropertyNode
332-
)
333-
334-
yield fixer.insertTextAfter(insertTarget, propertyCode)
335-
}
337+
fix: hasSideEffectsPossibility
338+
? undefined
339+
: (fixer) =>
340+
handleFix(fixer, propertyNode, firstUnorderedPropertyNode),
341+
suggest: hasSideEffectsPossibility
342+
? [
343+
{
344+
messageId: 'reorderWithSideEffects',
345+
data: {
346+
name: property.name,
347+
firstUnorderedPropertyName: firstUnorderedProperty.name,
348+
line
349+
},
350+
fix: (fixer) =>
351+
handleFix(fixer, propertyNode, firstUnorderedPropertyNode)
352+
}
353+
]
354+
: undefined
336355
})
337356
}
338357
}

0 commit comments

Comments
 (0)