‘liusuyi’
2023-10-21 94023628bd9c5e6bf724c37371a19b60d338b291
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
 * @fileoverview This rule warns about the usage of extra whitespaces between attributes
 * @author Armano
 */
'use strict'
 
const path = require('path')
 
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
 
/**
 * @param {RuleContext} context
 * @param {Token} node
 */
const isProperty = (context, node) => {
  const sourceCode = context.getSourceCode()
  return node.type === 'Punctuator' && sourceCode.getText(node) === ':'
}
 
module.exports = {
  meta: {
    type: 'layout',
    docs: {
      description: 'disallow multiple spaces',
      categories: ['vue3-strongly-recommended', 'strongly-recommended'],
      url: 'https://eslint.vuejs.org/rules/no-multi-spaces.html'
    },
    fixable: 'whitespace', // or "code" or "whitespace"
    schema: [
      {
        type: 'object',
        properties: {
          ignoreProperties: {
            type: 'boolean'
          }
        },
        additionalProperties: false
      }
    ]
  },
 
  /**
   * @param {RuleContext} context - The rule context.
   * @returns {RuleListener} AST event handlers.
   */
  create(context) {
    const options = context.options[0] || {}
    const ignoreProperties = options.ignoreProperties === true
 
    return {
      Program(node) {
        if (context.parserServices.getTemplateBodyTokenStore == null) {
          const filename = context.getFilename()
          if (path.extname(filename) === '.vue') {
            context.report({
              loc: { line: 1, column: 0 },
              message:
                'Use the latest vue-eslint-parser. See also https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error.'
            })
          }
          return
        }
        if (!node.templateBody) {
          return
        }
        const sourceCode = context.getSourceCode()
        const tokenStore = context.parserServices.getTemplateBodyTokenStore()
        const tokens = tokenStore.getTokens(node.templateBody, {
          includeComments: true
        })
 
        let prevToken = /** @type {Token} */ (tokens.shift())
        for (const token of tokens) {
          const spaces = token.range[0] - prevToken.range[1]
          const shouldIgnore =
            ignoreProperties &&
            (isProperty(context, token) || isProperty(context, prevToken))
          if (
            spaces > 1 &&
            token.loc.start.line === prevToken.loc.start.line &&
            !shouldIgnore
          ) {
            context.report({
              node: token,
              loc: {
                start: prevToken.loc.end,
                end: token.loc.start
              },
              message: "Multiple spaces found before '{{displayValue}}'.",
              fix: (fixer) =>
                fixer.replaceTextRange(
                  [prevToken.range[1], token.range[0]],
                  ' '
                ),
              data: {
                displayValue: sourceCode.getText(token)
              }
            })
          }
          prevToken = token
        }
      }
    }
  }
}