v-for-delimiter-style.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /**
  2. * @fileoverview enforce `v-for` directive's delimiter style
  3. * @author Flo Edelmann
  4. * @copyright 2020 Flo Edelmann. All rights reserved.
  5. * See LICENSE file in root directory for full license.
  6. */
  7. 'use strict'
  8. const utils = require('../utils')
  9. module.exports = {
  10. meta: {
  11. type: 'layout',
  12. docs: {
  13. description: "enforce `v-for` directive's delimiter style",
  14. categories: undefined,
  15. recommended: false,
  16. url: 'https://eslint.vuejs.org/rules/v-for-delimiter-style.html'
  17. },
  18. fixable: 'code',
  19. schema: [{ enum: ['in', 'of'] }],
  20. messages: {
  21. expected:
  22. "Expected '{{preferredDelimiter}}' instead of '{{usedDelimiter}}' in 'v-for'."
  23. }
  24. },
  25. /** @param {RuleContext} context */
  26. create(context) {
  27. const preferredDelimiter =
  28. /** @type {string|undefined} */ (context.options[0]) || 'in'
  29. return utils.defineTemplateBodyVisitor(context, {
  30. /** @param {VForExpression} node */
  31. VForExpression(node) {
  32. const sourceCode = context.getSourceCode()
  33. const tokenStore =
  34. sourceCode.parserServices.getTemplateBodyTokenStore &&
  35. sourceCode.parserServices.getTemplateBodyTokenStore()
  36. const delimiterToken = /** @type {Token} */ (
  37. tokenStore.getTokenAfter(
  38. node.left.length > 0
  39. ? node.left[node.left.length - 1]
  40. : tokenStore.getFirstToken(node),
  41. (token) => token.type !== 'Punctuator'
  42. )
  43. )
  44. if (delimiterToken.value === preferredDelimiter) {
  45. return
  46. }
  47. context.report({
  48. node,
  49. loc: node.loc,
  50. messageId: 'expected',
  51. data: {
  52. preferredDelimiter,
  53. usedDelimiter: delimiterToken.value
  54. },
  55. *fix(fixer) {
  56. yield fixer.replaceText(delimiterToken, preferredDelimiter)
  57. }
  58. })
  59. }
  60. })
  61. }
  62. }