eslint-plugin-mpx 0.0.21 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/.DS_Store +0 -0
- package/lib/configs/base.js +10 -5
- package/lib/configs/mpx-essential.js +0 -30
- package/lib/index.js +1 -150
- package/lib/rules/comment-directive.js +2 -2
- package/lib/rules/component-tags-order.js +2 -2
- package/lib/rules/eqeqeq.js +4 -2
- package/lib/rules/html-end-tags.js +1 -1
- package/lib/rules/no-arrow-functions-in-watch.js +2 -2
- package/lib/rules/no-async-in-computed-properties.js +5 -5
- package/lib/rules/no-dupe-keys.js +3 -3
- package/lib/rules/no-dupe-wx-elif.js +8 -3
- package/lib/rules/no-duplicate-attributes.js +6 -16
- package/lib/rules/no-parsing-error.js +2 -2
- package/lib/rules/no-reserved-keys.js +3 -3
- package/lib/rules/no-side-effects-in-computed-properties.js +8 -9
- package/lib/rules/return-in-computed-property.js +3 -3
- package/lib/rules/syntaxes/dynamic-directive-arguments.js +2 -1
- package/lib/rules/syntaxes/scope-attribute.js +2 -1
- package/lib/rules/syntaxes/slot-attribute.js +2 -1
- package/lib/rules/syntaxes/v-bind-prop-modifier-shorthand.js +2 -1
- package/lib/rules/valid-wx-elif.js +1 -1
- package/lib/rules/valid-wx-else.js +1 -1
- package/lib/rules/valid-wx-for.js +2 -2
- package/lib/rules/valid-wx-if.js +1 -1
- package/lib/rules/valid-wx-model.js +2 -2
- package/lib/utils/index.js +504 -490
- package/lib/utils/keycode-to-key.js +60 -60
- package/lib/utils/{vue-reserved.json → mpx-reserved.json} +2 -2
- package/package.json +18 -15
- package/lib/configs/essential.js +0 -51
- package/lib/configs/no-layout-rules.js +0 -47
- package/lib/configs/recommended.js +0 -17
- package/lib/configs/strongly-recommended.js +0 -32
- package/lib/configs/vue3-essential.js +0 -71
- package/lib/configs/vue3-recommended.js +0 -17
- package/lib/configs/vue3-strongly-recommended.js +0 -33
- package/lib/rules/array-bracket-spacing.js +0 -12
- package/lib/rules/arrow-spacing.js +0 -9
- package/lib/rules/attribute-hyphenation.js +0 -121
- package/lib/rules/attributes-order.js +0 -281
- package/lib/rules/block-spacing.js +0 -11
- package/lib/rules/brace-style.js +0 -11
- package/lib/rules/camelcase.js +0 -9
- package/lib/rules/comma-dangle.js +0 -9
- package/lib/rules/comma-spacing.js +0 -12
- package/lib/rules/comma-style.js +0 -20
- package/lib/rules/component-definition-name-casing.js +0 -108
- package/lib/rules/component-name-in-template-casing.js +0 -164
- package/lib/rules/custom-event-name-casing.js +0 -214
- package/lib/rules/dot-location.js +0 -9
- package/lib/rules/dot-notation.js +0 -9
- package/lib/rules/func-call-spacing.js +0 -11
- package/lib/rules/html-closing-bracket-newline.js +0 -115
- package/lib/rules/html-closing-bracket-spacing.js +0 -137
- package/lib/rules/html-comment-content-newline.js +0 -215
- package/lib/rules/html-comment-content-spacing.js +0 -179
- package/lib/rules/html-comment-indent.js +0 -258
- package/lib/rules/html-indent.js +0 -81
- package/lib/rules/html-quotes.js +0 -107
- package/lib/rules/html-self-closing.js +0 -222
- package/lib/rules/jsx-uses-vars.js +0 -73
- package/lib/rules/key-spacing.js +0 -11
- package/lib/rules/keyword-spacing.js +0 -11
- package/lib/rules/match-component-file-name.js +0 -151
- package/lib/rules/max-attributes-per-line.js +0 -194
- package/lib/rules/max-len.js +0 -561
- package/lib/rules/multiline-html-element-content-newline.js +0 -246
- package/lib/rules/mustache-interpolation-spacing.js +0 -107
- package/lib/rules/name-property-casing.js +0 -71
- package/lib/rules/no-bare-strings-in-template.js +0 -275
- package/lib/rules/no-boolean-default.js +0 -114
- package/lib/rules/no-confusing-v-for-v-if.js +0 -69
- package/lib/rules/no-custom-modifiers-on-v-model.js +0 -59
- package/lib/rules/no-deprecated-data-object-declaration.js +0 -95
- package/lib/rules/no-deprecated-destroyed-lifecycle.js +0 -101
- package/lib/rules/no-deprecated-dollar-listeners-api.js +0 -72
- package/lib/rules/no-deprecated-dollar-scopedslots-api.js +0 -79
- package/lib/rules/no-deprecated-events-api.js +0 -69
- package/lib/rules/no-deprecated-filter.js +0 -44
- package/lib/rules/no-deprecated-functional-template.js +0 -56
- package/lib/rules/no-deprecated-html-element-is.js +0 -54
- package/lib/rules/no-deprecated-inline-template.js +0 -47
- package/lib/rules/no-deprecated-scope-attribute.js +0 -31
- package/lib/rules/no-deprecated-slot-attribute.js +0 -29
- package/lib/rules/no-deprecated-slot-scope-attribute.js +0 -34
- package/lib/rules/no-deprecated-v-bind-sync.js +0 -62
- package/lib/rules/no-deprecated-v-on-native-modifier.js +0 -50
- package/lib/rules/no-deprecated-v-on-number-modifiers.js +0 -61
- package/lib/rules/no-deprecated-vue-config-keycodes.js +0 -53
- package/lib/rules/no-duplicate-attr-inheritance.js +0 -67
- package/lib/rules/no-empty-component-block.js +0 -109
- package/lib/rules/no-empty-pattern.js +0 -9
- package/lib/rules/no-extra-parens.js +0 -182
- package/lib/rules/no-irregular-whitespace.js +0 -251
- package/lib/rules/no-lifecycle-after-await.js +0 -133
- package/lib/rules/no-lone-template.js +0 -129
- package/lib/rules/no-multi-spaces.js +0 -107
- package/lib/rules/no-multiple-objects-in-class.js +0 -59
- package/lib/rules/no-multiple-slot-args.js +0 -118
- package/lib/rules/no-multiple-template-root.js +0 -101
- package/lib/rules/no-mutating-props.js +0 -323
- package/lib/rules/no-potential-component-option-typo.js +0 -125
- package/lib/rules/no-ref-as-operand.js +0 -189
- package/lib/rules/no-reserved-component-names.js +0 -187
- package/lib/rules/no-restricted-component-options.js +0 -215
- package/lib/rules/no-restricted-static-attribute.js +0 -164
- package/lib/rules/no-restricted-syntax.js +0 -9
- package/lib/rules/no-restricted-v-bind.js +0 -184
- package/lib/rules/no-setup-props-destructure.js +0 -149
- package/lib/rules/no-spaces-around-equal-signs-in-attribute.js +0 -57
- package/lib/rules/no-sparse-arrays.js +0 -9
- package/lib/rules/no-static-inline-styles.js +0 -141
- package/lib/rules/no-template-key.js +0 -48
- package/lib/rules/no-template-shadow.js +0 -101
- package/lib/rules/no-template-target-blank.js +0 -138
- package/lib/rules/no-textarea-mustache.js +0 -46
- package/lib/rules/no-unregistered-components.js +0 -187
- package/lib/rules/no-unsupported-features.js +0 -157
- package/lib/rules/no-unused-components.js +0 -143
- package/lib/rules/no-unused-properties.js +0 -742
- package/lib/rules/no-unused-vars.js +0 -147
- package/lib/rules/no-use-v-if-with-v-for.js +0 -119
- package/lib/rules/no-useless-concat.js +0 -9
- package/lib/rules/no-useless-mustaches.js +0 -154
- package/lib/rules/no-useless-v-bind.js +0 -150
- package/lib/rules/no-v-html.js +0 -36
- package/lib/rules/no-v-model-argument.js +0 -49
- package/lib/rules/no-watch-after-await.js +0 -142
- package/lib/rules/object-curly-newline.js +0 -12
- package/lib/rules/object-curly-spacing.js +0 -12
- package/lib/rules/object-property-newline.js +0 -12
- package/lib/rules/one-component-per-file.js +0 -50
- package/lib/rules/operator-linebreak.js +0 -9
- package/lib/rules/order-in-components.js +0 -341
- package/lib/rules/padding-line-between-blocks.js +0 -220
- package/lib/rules/prefer-template.js +0 -9
- package/lib/rules/prop-name-casing.js +0 -66
- package/lib/rules/require-component-is.js +0 -45
- package/lib/rules/require-default-prop.js +0 -190
- package/lib/rules/require-direct-export.js +0 -128
- package/lib/rules/require-explicit-emits.js +0 -511
- package/lib/rules/require-name-property.js +0 -43
- package/lib/rules/require-prop-type-constructor.js +0 -99
- package/lib/rules/require-prop-types.js +0 -103
- package/lib/rules/require-render-return.js +0 -50
- package/lib/rules/require-slots-as-functions.js +0 -120
- package/lib/rules/require-toggle-inside-transition.js +0 -89
- package/lib/rules/require-v-for-key.js +0 -62
- package/lib/rules/require-valid-default-prop.js +0 -338
- package/lib/rules/return-in-emits-validator.js +0 -141
- package/lib/rules/script-indent.js +0 -56
- package/lib/rules/singleline-html-element-content-newline.js +0 -215
- package/lib/rules/sort-keys.js +0 -282
- package/lib/rules/space-in-parens.js +0 -12
- package/lib/rules/space-infix-ops.js +0 -11
- package/lib/rules/space-unary-ops.js +0 -11
- package/lib/rules/static-class-names-order.js +0 -61
- package/lib/rules/template-curly-spacing.js +0 -12
- package/lib/rules/this-in-template.js +0 -128
- package/lib/rules/use-v-on-exact.js +0 -228
- package/lib/rules/v-bind-style.js +0 -76
- package/lib/rules/v-for-delimiter-style.js +0 -69
- package/lib/rules/v-on-function-call.js +0 -172
- package/lib/rules/v-on-style.js +0 -58
- package/lib/rules/v-slot-style.js +0 -155
- package/lib/rules/valid-template-root.js +0 -69
- package/lib/rules/valid-v-bind-sync.js +0 -179
- package/lib/rules/valid-v-bind.js +0 -62
- package/lib/rules/valid-v-cloak.js +0 -58
- package/lib/rules/valid-v-html.js +0 -58
- package/lib/rules/valid-v-is.js +0 -95
- package/lib/rules/valid-v-on.js +0 -153
- package/lib/rules/valid-v-once.js +0 -58
- package/lib/rules/valid-v-pre.js +0 -58
- package/lib/rules/valid-v-show.js +0 -58
- package/lib/rules/valid-v-slot.js +0 -290
- package/lib/rules/valid-v-text.js +0 -58
- package/lib/utils/indent-common.js +0 -2085
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author tyankatsu <https://github.com/tyankatsu0105>
|
|
3
|
-
* See LICENSE file in root directory for full license.
|
|
4
|
-
*/
|
|
5
|
-
'use strict'
|
|
6
|
-
|
|
7
|
-
// ------------------------------------------------------------------------------
|
|
8
|
-
// Requirements
|
|
9
|
-
// ------------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
const { isVElement } = require('../utils')
|
|
12
|
-
|
|
13
|
-
// ------------------------------------------------------------------------------
|
|
14
|
-
// Rule Definition
|
|
15
|
-
// ------------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* check whether has attribute `src`
|
|
19
|
-
* @param {VElement} componentBlock
|
|
20
|
-
*/
|
|
21
|
-
function hasAttributeSrc(componentBlock) {
|
|
22
|
-
const hasAttribute = componentBlock.startTag.attributes.length > 0
|
|
23
|
-
|
|
24
|
-
const hasSrc =
|
|
25
|
-
componentBlock.startTag.attributes.filter(
|
|
26
|
-
(attribute) =>
|
|
27
|
-
!attribute.directive &&
|
|
28
|
-
attribute.key.name === 'src' &&
|
|
29
|
-
attribute.value &&
|
|
30
|
-
attribute.value.value !== ''
|
|
31
|
-
).length > 0
|
|
32
|
-
|
|
33
|
-
return hasAttribute && hasSrc
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* check whether value under the component block is only whitespaces or break lines
|
|
38
|
-
* @param {VElement} componentBlock
|
|
39
|
-
*/
|
|
40
|
-
function isValueOnlyWhiteSpacesOrLineBreaks(componentBlock) {
|
|
41
|
-
return (
|
|
42
|
-
componentBlock.children.length === 1 &&
|
|
43
|
-
componentBlock.children[0].type === 'VText' &&
|
|
44
|
-
!componentBlock.children[0].value.trim()
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = {
|
|
49
|
-
meta: {
|
|
50
|
-
type: 'suggestion',
|
|
51
|
-
docs: {
|
|
52
|
-
description:
|
|
53
|
-
'disallow the `<template>` `<script>` `<style>` block to be empty',
|
|
54
|
-
categories: undefined,
|
|
55
|
-
url: 'https://eslint.vuejs.org/rules/no-empty-component-block.html'
|
|
56
|
-
},
|
|
57
|
-
fixable: null,
|
|
58
|
-
schema: [],
|
|
59
|
-
messages: {
|
|
60
|
-
unexpected: '`<{{ blockName }}>` is empty. Empty block is not allowed.'
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @param {RuleContext} context - The rule context.
|
|
66
|
-
* @returns {RuleListener} AST event handlers.
|
|
67
|
-
*/
|
|
68
|
-
create(context) {
|
|
69
|
-
if (!context.parserServices.getDocumentFragment) {
|
|
70
|
-
return {}
|
|
71
|
-
}
|
|
72
|
-
const documentFragment = context.parserServices.getDocumentFragment()
|
|
73
|
-
if (!documentFragment) {
|
|
74
|
-
return {}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const componentBlocks = documentFragment.children.filter(isVElement)
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
Program() {
|
|
81
|
-
for (const componentBlock of componentBlocks) {
|
|
82
|
-
if (
|
|
83
|
-
componentBlock.name !== 'template' &&
|
|
84
|
-
componentBlock.name !== 'script' &&
|
|
85
|
-
componentBlock.name !== 'style'
|
|
86
|
-
)
|
|
87
|
-
continue
|
|
88
|
-
|
|
89
|
-
// https://vue-loader.vuejs.org/spec.html#src-imports
|
|
90
|
-
if (hasAttributeSrc(componentBlock)) continue
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
isValueOnlyWhiteSpacesOrLineBreaks(componentBlock) ||
|
|
94
|
-
componentBlock.children.length === 0
|
|
95
|
-
) {
|
|
96
|
-
context.report({
|
|
97
|
-
node: componentBlock,
|
|
98
|
-
loc: componentBlock.loc,
|
|
99
|
-
messageId: 'unexpected',
|
|
100
|
-
data: {
|
|
101
|
-
blockName: componentBlock.name
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Yosuke Ota
|
|
3
|
-
*/
|
|
4
|
-
'use strict'
|
|
5
|
-
|
|
6
|
-
const { isParenthesized } = require('eslint-utils')
|
|
7
|
-
const { wrapCoreRule } = require('../utils')
|
|
8
|
-
|
|
9
|
-
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
|
|
10
|
-
module.exports = wrapCoreRule(require('eslint/lib/rules/no-extra-parens'), {
|
|
11
|
-
skipDynamicArguments: true,
|
|
12
|
-
create: createForVueSyntax
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Check whether the given token is a left parenthesis.
|
|
17
|
-
* @param {Token} token The token to check.
|
|
18
|
-
* @returns {boolean} `true` if the token is a left parenthesis.
|
|
19
|
-
*/
|
|
20
|
-
function isLeftParen(token) {
|
|
21
|
-
return token.type === 'Punctuator' && token.value === '('
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Check whether the given token is a right parenthesis.
|
|
26
|
-
* @param {Token} token The token to check.
|
|
27
|
-
* @returns {boolean} `true` if the token is a right parenthesis.
|
|
28
|
-
*/
|
|
29
|
-
function isRightParen(token) {
|
|
30
|
-
return token.type === 'Punctuator' && token.value === ')'
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Check whether the given token is a left brace.
|
|
35
|
-
* @param {Token} token The token to check.
|
|
36
|
-
* @returns {boolean} `true` if the token is a left brace.
|
|
37
|
-
*/
|
|
38
|
-
function isLeftBrace(token) {
|
|
39
|
-
return token.type === 'Punctuator' && token.value === '{'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Check whether the given token is a right brace.
|
|
44
|
-
* @param {Token} token The token to check.
|
|
45
|
-
* @returns {boolean} `true` if the token is a right brace.
|
|
46
|
-
*/
|
|
47
|
-
function isRightBrace(token) {
|
|
48
|
-
return token.type === 'Punctuator' && token.value === '}'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Check whether the given token is a left bracket.
|
|
53
|
-
* @param {Token} token The token to check.
|
|
54
|
-
* @returns {boolean} `true` if the token is a left bracket.
|
|
55
|
-
*/
|
|
56
|
-
function isLeftBracket(token) {
|
|
57
|
-
return token.type === 'Punctuator' && token.value === '['
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Check whether the given token is a right bracket.
|
|
62
|
-
* @param {Token} token The token to check.
|
|
63
|
-
* @returns {boolean} `true` if the token is a right bracket.
|
|
64
|
-
*/
|
|
65
|
-
function isRightBracket(token) {
|
|
66
|
-
return token.type === 'Punctuator' && token.value === ']'
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Determines if a given expression node is an IIFE
|
|
71
|
-
* @param {Expression} node The node to check
|
|
72
|
-
* @returns {node is CallExpression & { callee: FunctionExpression } } `true` if the given node is an IIFE
|
|
73
|
-
*/
|
|
74
|
-
function isIIFE(node) {
|
|
75
|
-
return (
|
|
76
|
-
node.type === 'CallExpression' && node.callee.type === 'FunctionExpression'
|
|
77
|
-
)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* @param {RuleContext} context - The rule context.
|
|
82
|
-
* @returns {TemplateListener} AST event handlers.
|
|
83
|
-
*/
|
|
84
|
-
function createForVueSyntax(context) {
|
|
85
|
-
if (!context.parserServices.getTemplateBodyTokenStore) {
|
|
86
|
-
return {}
|
|
87
|
-
}
|
|
88
|
-
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Checks if the given node turns into a filter when unwraped.
|
|
92
|
-
* @param {Expression} expression node to evaluate
|
|
93
|
-
* @returns {boolean} `true` if the given node turns into a filter when unwraped.
|
|
94
|
-
*/
|
|
95
|
-
function isUnwrapChangeToFilter(expression) {
|
|
96
|
-
let parenStack = null
|
|
97
|
-
for (const token of tokenStore.getTokens(expression)) {
|
|
98
|
-
if (!parenStack) {
|
|
99
|
-
if (token.value === '|') {
|
|
100
|
-
return true
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
if (parenStack.isUpToken(token)) {
|
|
104
|
-
parenStack = parenStack.upper
|
|
105
|
-
continue
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (isLeftParen(token)) {
|
|
109
|
-
parenStack = { isUpToken: isRightParen, upper: parenStack }
|
|
110
|
-
} else if (isLeftBracket(token)) {
|
|
111
|
-
parenStack = { isUpToken: isRightBracket, upper: parenStack }
|
|
112
|
-
} else if (isLeftBrace(token)) {
|
|
113
|
-
parenStack = { isUpToken: isRightBrace, upper: parenStack }
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return false
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* @param {VExpressionContainer & { expression: Expression | VFilterSequenceExpression | null }} node
|
|
120
|
-
*/
|
|
121
|
-
function verify(node) {
|
|
122
|
-
if (!node.expression) {
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const expression =
|
|
127
|
-
node.expression.type === 'VFilterSequenceExpression'
|
|
128
|
-
? node.expression.expression
|
|
129
|
-
: node.expression
|
|
130
|
-
|
|
131
|
-
if (!isParenthesized(expression, tokenStore)) {
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (!isParenthesized(2, expression, tokenStore)) {
|
|
136
|
-
if (
|
|
137
|
-
isIIFE(expression) &&
|
|
138
|
-
!isParenthesized(expression.callee, tokenStore)
|
|
139
|
-
) {
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
if (isUnwrapChangeToFilter(expression)) {
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
report(expression)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Report the node
|
|
151
|
-
* @param {Expression} node node to evaluate
|
|
152
|
-
* @returns {void}
|
|
153
|
-
* @private
|
|
154
|
-
*/
|
|
155
|
-
function report(node) {
|
|
156
|
-
const sourceCode = context.getSourceCode()
|
|
157
|
-
const leftParenToken = tokenStore.getTokenBefore(node)
|
|
158
|
-
const rightParenToken = tokenStore.getTokenAfter(node)
|
|
159
|
-
|
|
160
|
-
context.report({
|
|
161
|
-
node,
|
|
162
|
-
loc: leftParenToken.loc,
|
|
163
|
-
messageId: 'unexpected',
|
|
164
|
-
fix(fixer) {
|
|
165
|
-
const parenthesizedSource = sourceCode.text.slice(
|
|
166
|
-
leftParenToken.range[1],
|
|
167
|
-
rightParenToken.range[0]
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
return fixer.replaceTextRange(
|
|
171
|
-
[leftParenToken.range[0], rightParenToken.range[1]],
|
|
172
|
-
parenthesizedSource
|
|
173
|
-
)
|
|
174
|
-
}
|
|
175
|
-
})
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
"VAttribute[directive=true][key.name.name='bind'] > VExpressionContainer": verify,
|
|
180
|
-
'VElement > VExpressionContainer': verify
|
|
181
|
-
}
|
|
182
|
-
}
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Yosuke Ota
|
|
3
|
-
* @fileoverview Rule to disalow whitespace that is not a tab or space, whitespace inside strings and comments are allowed
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use strict'
|
|
7
|
-
|
|
8
|
-
// ------------------------------------------------------------------------------
|
|
9
|
-
// Requirements
|
|
10
|
-
// ------------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
const utils = require('../utils')
|
|
13
|
-
|
|
14
|
-
// ------------------------------------------------------------------------------
|
|
15
|
-
// Constants
|
|
16
|
-
// ------------------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
const ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/u
|
|
19
|
-
const IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/gmu
|
|
20
|
-
const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/gmu
|
|
21
|
-
|
|
22
|
-
// ------------------------------------------------------------------------------
|
|
23
|
-
// Rule Definition
|
|
24
|
-
// ------------------------------------------------------------------------------
|
|
25
|
-
|
|
26
|
-
module.exports = {
|
|
27
|
-
meta: {
|
|
28
|
-
type: 'problem',
|
|
29
|
-
|
|
30
|
-
docs: {
|
|
31
|
-
description: 'disallow irregular whitespace',
|
|
32
|
-
categories: undefined,
|
|
33
|
-
url: 'https://eslint.vuejs.org/rules/no-irregular-whitespace.html',
|
|
34
|
-
extensionRule: true,
|
|
35
|
-
coreRuleUrl: 'https://eslint.org/docs/rules/no-irregular-whitespace'
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
schema: [
|
|
39
|
-
{
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: {
|
|
42
|
-
skipComments: {
|
|
43
|
-
type: 'boolean',
|
|
44
|
-
default: false
|
|
45
|
-
},
|
|
46
|
-
skipStrings: {
|
|
47
|
-
type: 'boolean',
|
|
48
|
-
default: true
|
|
49
|
-
},
|
|
50
|
-
skipTemplates: {
|
|
51
|
-
type: 'boolean',
|
|
52
|
-
default: false
|
|
53
|
-
},
|
|
54
|
-
skipRegExps: {
|
|
55
|
-
type: 'boolean',
|
|
56
|
-
default: false
|
|
57
|
-
},
|
|
58
|
-
skipHTMLAttributeValues: {
|
|
59
|
-
type: 'boolean',
|
|
60
|
-
default: false
|
|
61
|
-
},
|
|
62
|
-
skipHTMLTextContents: {
|
|
63
|
-
type: 'boolean',
|
|
64
|
-
default: false
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
additionalProperties: false
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
messages: {
|
|
71
|
-
disallow: 'Irregular whitespace not allowed.'
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* @param {RuleContext} context - The rule context.
|
|
76
|
-
* @returns {RuleListener} AST event handlers.
|
|
77
|
-
*/
|
|
78
|
-
create(context) {
|
|
79
|
-
// Module store of error indexes that we have found
|
|
80
|
-
/** @type {number[]} */
|
|
81
|
-
let errorIndexes = []
|
|
82
|
-
|
|
83
|
-
// Lookup the `skipComments` option, which defaults to `false`.
|
|
84
|
-
const options = context.options[0] || {}
|
|
85
|
-
const skipComments = !!options.skipComments
|
|
86
|
-
const skipStrings = options.skipStrings !== false
|
|
87
|
-
const skipRegExps = !!options.skipRegExps
|
|
88
|
-
const skipTemplates = !!options.skipTemplates
|
|
89
|
-
const skipHTMLAttributeValues = !!options.skipHTMLAttributeValues
|
|
90
|
-
const skipHTMLTextContents = !!options.skipHTMLTextContents
|
|
91
|
-
|
|
92
|
-
const sourceCode = context.getSourceCode()
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Removes errors that occur inside a string node
|
|
96
|
-
* @param {ASTNode | Token} node to check for matching errors.
|
|
97
|
-
* @returns {void}
|
|
98
|
-
* @private
|
|
99
|
-
*/
|
|
100
|
-
function removeWhitespaceError(node) {
|
|
101
|
-
const [startIndex, endIndex] = node.range
|
|
102
|
-
|
|
103
|
-
errorIndexes = errorIndexes.filter(
|
|
104
|
-
(errorIndex) => errorIndex < startIndex || endIndex <= errorIndex
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Checks literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
|
110
|
-
* @param {Literal} node to check for matching errors.
|
|
111
|
-
* @returns {void}
|
|
112
|
-
* @private
|
|
113
|
-
*/
|
|
114
|
-
function removeInvalidNodeErrorsInLiteral(node) {
|
|
115
|
-
const shouldCheckStrings = skipStrings && typeof node.value === 'string'
|
|
116
|
-
const shouldCheckRegExps = skipRegExps && Boolean(node.regex)
|
|
117
|
-
|
|
118
|
-
if (shouldCheckStrings || shouldCheckRegExps) {
|
|
119
|
-
// If we have irregular characters remove them from the errors list
|
|
120
|
-
if (ALL_IRREGULARS.test(sourceCode.getText(node))) {
|
|
121
|
-
removeWhitespaceError(node)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Checks template string literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
|
128
|
-
* @param {TemplateElement} node to check for matching errors.
|
|
129
|
-
* @returns {void}
|
|
130
|
-
* @private
|
|
131
|
-
*/
|
|
132
|
-
function removeInvalidNodeErrorsInTemplateLiteral(node) {
|
|
133
|
-
if (ALL_IRREGULARS.test(node.value.raw)) {
|
|
134
|
-
removeWhitespaceError(node)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Checks HTML attribute value nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
|
140
|
-
* @param {VLiteral} node to check for matching errors.
|
|
141
|
-
* @returns {void}
|
|
142
|
-
* @private
|
|
143
|
-
*/
|
|
144
|
-
function removeInvalidNodeErrorsInHTMLAttributeValue(node) {
|
|
145
|
-
if (ALL_IRREGULARS.test(sourceCode.getText(node))) {
|
|
146
|
-
removeWhitespaceError(node)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Checks HTML text content nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
|
152
|
-
* @param {VText} node to check for matching errors.
|
|
153
|
-
* @returns {void}
|
|
154
|
-
* @private
|
|
155
|
-
*/
|
|
156
|
-
function removeInvalidNodeErrorsInHTMLTextContent(node) {
|
|
157
|
-
if (ALL_IRREGULARS.test(sourceCode.getText(node))) {
|
|
158
|
-
removeWhitespaceError(node)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Checks comment nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
|
164
|
-
* @param {Comment | HTMLComment | HTMLBogusComment} node to check for matching errors.
|
|
165
|
-
* @returns {void}
|
|
166
|
-
* @private
|
|
167
|
-
*/
|
|
168
|
-
function removeInvalidNodeErrorsInComment(node) {
|
|
169
|
-
if (ALL_IRREGULARS.test(node.value)) {
|
|
170
|
-
removeWhitespaceError(node)
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Checks the program source for irregular whitespaces and irregular line terminators
|
|
176
|
-
* @returns {void}
|
|
177
|
-
* @private
|
|
178
|
-
*/
|
|
179
|
-
function checkForIrregularWhitespace() {
|
|
180
|
-
const source = sourceCode.getText()
|
|
181
|
-
let match
|
|
182
|
-
while ((match = IRREGULAR_WHITESPACE.exec(source)) !== null) {
|
|
183
|
-
errorIndexes.push(match.index)
|
|
184
|
-
}
|
|
185
|
-
while ((match = IRREGULAR_LINE_TERMINATORS.exec(source)) !== null) {
|
|
186
|
-
errorIndexes.push(match.index)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
checkForIrregularWhitespace()
|
|
191
|
-
|
|
192
|
-
if (!errorIndexes.length) {
|
|
193
|
-
return {}
|
|
194
|
-
}
|
|
195
|
-
const bodyVisitor = utils.defineTemplateBodyVisitor(context, {
|
|
196
|
-
...(skipHTMLAttributeValues
|
|
197
|
-
? {
|
|
198
|
-
'VAttribute[directive=false] > VLiteral': removeInvalidNodeErrorsInHTMLAttributeValue
|
|
199
|
-
}
|
|
200
|
-
: {}),
|
|
201
|
-
...(skipHTMLTextContents
|
|
202
|
-
? { VText: removeInvalidNodeErrorsInHTMLTextContent }
|
|
203
|
-
: {}),
|
|
204
|
-
|
|
205
|
-
// inline scripts
|
|
206
|
-
Literal: removeInvalidNodeErrorsInLiteral,
|
|
207
|
-
...(skipTemplates
|
|
208
|
-
? { TemplateElement: removeInvalidNodeErrorsInTemplateLiteral }
|
|
209
|
-
: {})
|
|
210
|
-
})
|
|
211
|
-
return {
|
|
212
|
-
...bodyVisitor,
|
|
213
|
-
Literal: removeInvalidNodeErrorsInLiteral,
|
|
214
|
-
...(skipTemplates
|
|
215
|
-
? { TemplateElement: removeInvalidNodeErrorsInTemplateLiteral }
|
|
216
|
-
: {}),
|
|
217
|
-
'Program:exit'(node) {
|
|
218
|
-
if (bodyVisitor['Program:exit']) {
|
|
219
|
-
bodyVisitor['Program:exit'](node)
|
|
220
|
-
}
|
|
221
|
-
const templateBody = node.templateBody
|
|
222
|
-
if (skipComments) {
|
|
223
|
-
// First strip errors occurring in comment nodes.
|
|
224
|
-
sourceCode.getAllComments().forEach(removeInvalidNodeErrorsInComment)
|
|
225
|
-
if (templateBody) {
|
|
226
|
-
templateBody.comments.forEach(removeInvalidNodeErrorsInComment)
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Removes errors that occur outside script and template
|
|
231
|
-
const [scriptStart, scriptEnd] = node.range
|
|
232
|
-
const [templateStart, templateEnd] = templateBody
|
|
233
|
-
? templateBody.range
|
|
234
|
-
: [0, 0]
|
|
235
|
-
errorIndexes = errorIndexes.filter(
|
|
236
|
-
(errorIndex) =>
|
|
237
|
-
(scriptStart <= errorIndex && errorIndex < scriptEnd) ||
|
|
238
|
-
(templateStart <= errorIndex && errorIndex < templateEnd)
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
// If we have any errors remaining report on them
|
|
242
|
-
errorIndexes.forEach((errorIndex) => {
|
|
243
|
-
context.report({
|
|
244
|
-
loc: sourceCode.getLocFromIndex(errorIndex),
|
|
245
|
-
messageId: 'disallow'
|
|
246
|
-
})
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Yosuke Ota
|
|
3
|
-
* See LICENSE file in root directory for full license.
|
|
4
|
-
*/
|
|
5
|
-
'use strict'
|
|
6
|
-
const { ReferenceTracker } = require('eslint-utils')
|
|
7
|
-
const utils = require('../utils')
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {import('eslint-utils').TYPES.TraceMap} TraceMap
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const LIFECYCLE_HOOKS = [
|
|
14
|
-
'onBeforeMount',
|
|
15
|
-
'onBeforeUnmount',
|
|
16
|
-
'onBeforeUpdate',
|
|
17
|
-
'onErrorCaptured',
|
|
18
|
-
'onMounted',
|
|
19
|
-
'onRenderTracked',
|
|
20
|
-
'onRenderTriggered',
|
|
21
|
-
'onUnmounted',
|
|
22
|
-
'onUpdated',
|
|
23
|
-
'onActivated',
|
|
24
|
-
'onDeactivated'
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
meta: {
|
|
29
|
-
type: 'suggestion',
|
|
30
|
-
docs: {
|
|
31
|
-
description: 'disallow asynchronously registered lifecycle hooks',
|
|
32
|
-
categories: ['vue3-essential'],
|
|
33
|
-
url: 'https://eslint.vuejs.org/rules/no-lifecycle-after-await.html'
|
|
34
|
-
},
|
|
35
|
-
fixable: null,
|
|
36
|
-
schema: [],
|
|
37
|
-
messages: {
|
|
38
|
-
forbidden: 'The lifecycle hooks after `await` expression are forbidden.'
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
/** @param {RuleContext} context */
|
|
42
|
-
create(context) {
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {object} SetupFunctionData
|
|
45
|
-
* @property {Property} setupProperty
|
|
46
|
-
* @property {boolean} afterAwait
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* @typedef {object} ScopeStack
|
|
50
|
-
* @property {ScopeStack | null} upper
|
|
51
|
-
* @property {FunctionDeclaration | FunctionExpression | ArrowFunctionExpression} functionNode
|
|
52
|
-
*/
|
|
53
|
-
/** @type {Set<ESNode>} */
|
|
54
|
-
const lifecycleHookCallNodes = new Set()
|
|
55
|
-
/** @type {Map<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression, SetupFunctionData>} */
|
|
56
|
-
const setupFunctions = new Map()
|
|
57
|
-
|
|
58
|
-
/** @type {ScopeStack | null} */
|
|
59
|
-
let scopeStack = null
|
|
60
|
-
|
|
61
|
-
return Object.assign(
|
|
62
|
-
{
|
|
63
|
-
Program() {
|
|
64
|
-
const tracker = new ReferenceTracker(context.getScope())
|
|
65
|
-
const traceMap = {
|
|
66
|
-
/** @type {TraceMap} */
|
|
67
|
-
vue: {
|
|
68
|
-
[ReferenceTracker.ESM]: true
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
for (const lifecycleHook of LIFECYCLE_HOOKS) {
|
|
72
|
-
traceMap.vue[lifecycleHook] = {
|
|
73
|
-
[ReferenceTracker.CALL]: true
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
for (const { node } of tracker.iterateEsmReferences(traceMap)) {
|
|
78
|
-
lifecycleHookCallNodes.add(node)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
utils.defineVueVisitor(context, {
|
|
83
|
-
':function'(node) {
|
|
84
|
-
scopeStack = {
|
|
85
|
-
upper: scopeStack,
|
|
86
|
-
functionNode: node
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
onSetupFunctionEnter(node) {
|
|
90
|
-
setupFunctions.set(node, {
|
|
91
|
-
setupProperty: node.parent,
|
|
92
|
-
afterAwait: false
|
|
93
|
-
})
|
|
94
|
-
},
|
|
95
|
-
AwaitExpression() {
|
|
96
|
-
if (!scopeStack) {
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
|
|
100
|
-
if (!setupFunctionData) {
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
setupFunctionData.afterAwait = true
|
|
104
|
-
},
|
|
105
|
-
CallExpression(node) {
|
|
106
|
-
if (!scopeStack) {
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
|
|
110
|
-
if (!setupFunctionData || !setupFunctionData.afterAwait) {
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (lifecycleHookCallNodes.has(node)) {
|
|
115
|
-
if (node.arguments.length >= 2) {
|
|
116
|
-
// Has target instance. e.g. `onMounted(() => {}, instance)`
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
context.report({
|
|
120
|
-
node,
|
|
121
|
-
messageId: 'forbidden'
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
':function:exit'(node) {
|
|
126
|
-
scopeStack = scopeStack && scopeStack.upper
|
|
127
|
-
|
|
128
|
-
setupFunctions.delete(node)
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
)
|
|
132
|
-
}
|
|
133
|
-
}
|