Skip to content

Commit 834411e

Browse files
authored
Fix false positive for unknown emits definition in vue/require-explicit-emits rule (#1756)
* Fix false positive for unknown emits definition in `vue/require-explicit-emits` rule * Rename method
1 parent a475176 commit 834411e

18 files changed

+499
-330
lines changed

lib/rules/no-boolean-default.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
const utils = require('../utils')
88

99
/**
10-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
11-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
12-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
10+
* @typedef {import('../utils').ComponentProp} ComponentProp
1311
*/
1412

1513
// ------------------------------------------------------------------------------
@@ -55,7 +53,7 @@ module.exports = {
5553
create(context) {
5654
const booleanType = context.options[0] || 'no-default'
5755
/**
58-
* @param {ComponentArrayProp | ComponentObjectProp | ComponentTypeProp} prop
56+
* @param {ComponentProp} prop
5957
* @param { { [key: string]: Expression | undefined } } [withDefaultsExpressions]
6058
*/
6159
function processProp(prop, withDefaultsExpressions) {
@@ -84,7 +82,7 @@ module.exports = {
8482
}
8583
}
8684
/**
87-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
85+
* @param {ComponentProp[]} props
8886
* @param { { [key: string]: Expression | undefined } } [withDefaultsExpressions]
8987
*/
9088
function processProps(props, withDefaultsExpressions) {
@@ -118,7 +116,7 @@ module.exports = {
118116
}
119117
return utils.compositingVisitors(
120118
utils.executeOnVueComponent(context, (obj) => {
121-
processProps(utils.getComponentProps(obj))
119+
processProps(utils.getComponentPropsFromOptions(obj))
122120
}),
123121
utils.defineScriptSetupVisitor(context, {
124122
onDefinePropsEnter(node, props) {

lib/rules/no-deprecated-props-default-this.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ module.exports = {
9696
}
9797
return utils.defineVueVisitor(context, {
9898
onVueObjectEnter(node) {
99-
for (const prop of utils.getComponentProps(node)) {
99+
for (const prop of utils.getComponentPropsFromOptions(node)) {
100100
if (prop.type !== 'object') {
101101
continue
102102
}

lib/rules/no-mutating-props.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ module.exports = {
297297
node,
298298
new Set(
299299
utils
300-
.getComponentProps(node)
300+
.getComponentPropsFromOptions(node)
301301
.map((p) => p.propName)
302302
.filter(utils.isDef)
303303
)

lib/rules/no-reserved-keys.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ module.exports = {
6767
return utils.compositingVisitors(
6868
utils.defineScriptSetupVisitor(context, {
6969
onDefinePropsEnter(_node, props) {
70-
for (const { propName, node } of props) {
71-
if (propName && reservedKeys.has(propName)) {
70+
for (const prop of props) {
71+
if (prop.propName && reservedKeys.has(prop.propName)) {
72+
const { propName, node } = prop
7273
context.report({
7374
node,
7475
messageId: 'reserved',

lib/rules/no-reserved-props.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ const utils = require('../utils')
1212
const casing = require('../utils/casing')
1313

1414
/**
15-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
16-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
17-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
15+
* @typedef {import('../utils').ComponentProp} ComponentProp
1816
*/
1917

2018
// ------------------------------------------------------------------------------
@@ -67,7 +65,7 @@ module.exports = {
6765
const reserved = new Set(RESERVED[vueVersion])
6866

6967
/**
70-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
68+
* @param {ComponentProp[]} props
7169
*/
7270
function processProps(props) {
7371
for (const prop of props) {
@@ -90,7 +88,7 @@ module.exports = {
9088
}
9189
}),
9290
utils.executeOnVue(context, (obj) => {
93-
processProps(utils.getComponentProps(obj))
91+
processProps(utils.getComponentPropsFromOptions(obj))
9492
})
9593
)
9694
}

lib/rules/no-restricted-props.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ const utils = require('../utils')
88
const regexp = require('../utils/regexp')
99

1010
/**
11-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
12-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
13-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
11+
* @typedef {import('../utils').ComponentProp} ComponentProp
1412
*/
1513

1614
/**
@@ -96,7 +94,7 @@ module.exports = {
9694
const options = context.options.map(parseOption)
9795

9896
/**
99-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
97+
* @param {ComponentProp[]} props
10098
* @param { { [key: string]: Property | undefined } } [withDefaultsProps]
10199
*/
102100
function processProps(props, withDefaultsProps) {
@@ -133,7 +131,7 @@ module.exports = {
133131
}),
134132
utils.defineVueVisitor(context, {
135133
onVueObjectEnter(node) {
136-
processProps(utils.getComponentProps(node))
134+
processProps(utils.getComponentPropsFromOptions(node))
137135
}
138136
})
139137
)

lib/rules/prop-name-casing.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ const casing = require('../utils/casing')
99
const allowedCaseOptions = ['camelCase', 'snake_case']
1010

1111
/**
12-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
13-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
14-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
12+
* @typedef {import('../utils').ComponentProp} ComponentProp
1513
*/
1614

1715
// ------------------------------------------------------------------------------
@@ -29,7 +27,7 @@ function create(context) {
2927
// ----------------------------------------------------------------------
3028

3129
/**
32-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
30+
* @param {ComponentProp[]} props
3331
*/
3432
function processProps(props) {
3533
for (const item of props) {
@@ -56,7 +54,7 @@ function create(context) {
5654
}
5755
}),
5856
utils.executeOnVue(context, (obj) => {
59-
processProps(utils.getComponentProps(obj))
57+
processProps(utils.getComponentPropsFromOptions(obj))
6058
})
6159
)
6260
}

lib/rules/require-default-prop.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
'use strict'
66

77
/**
8-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
8+
* @typedef {import('../utils').ComponentProp} ComponentProp
99
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
10-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
1110
* @typedef {ComponentObjectProp & { value: ObjectExpression} } ComponentObjectPropObject
1211
*/
1312

@@ -145,7 +144,7 @@ module.exports = {
145144
}
146145

147146
/**
148-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
147+
* @param {ComponentProp[]} props
149148
* @param {boolean} [withDefaults]
150149
* @param { { [key: string]: Expression | undefined } } [withDefaultsExpressions]
151150
*/
@@ -209,7 +208,7 @@ module.exports = {
209208
}
210209
}),
211210
utils.executeOnVue(context, (obj) => {
212-
processProps(utils.getComponentProps(obj))
211+
processProps(utils.getComponentPropsFromOptions(obj))
213212
})
214213
)
215214
}

lib/rules/require-emit-validator.js

+9-12
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
const utils = require('../utils')
88

99
/**
10-
* @typedef {import('../utils').ComponentArrayEmit} ComponentArrayEmit
11-
* @typedef {import('../utils').ComponentObjectEmit} ComponentObjectEmit
12-
* @typedef {import('../utils').ComponentTypeEmit} ComponentTypeEmit
10+
* @typedef {import('../utils').ComponentEmit} ComponentEmit
1311
*/
1412

1513
// ------------------------------------------------------------------------------
@@ -41,9 +39,13 @@ module.exports = {
4139
// ----------------------------------------------------------------------
4240

4341
/**
44-
* @param {ComponentArrayEmit|ComponentObjectEmit} emit
42+
* @param {ComponentEmit} emit
4543
*/
46-
function checker({ value, node, emitName }) {
44+
function checker(emit) {
45+
if (emit.type !== 'object' && emit.type !== 'array') {
46+
return
47+
}
48+
const { value, node, emitName } = emit
4749
const hasType =
4850
!!value &&
4951
(value.type === 'ArrowFunctionExpression' ||
@@ -87,16 +89,11 @@ module.exports = {
8789

8890
return utils.compositingVisitors(
8991
utils.executeOnVue(context, (obj) => {
90-
utils.getComponentEmits(obj).forEach(checker)
92+
utils.getComponentEmitsFromOptions(obj).forEach(checker)
9193
}),
9294
utils.defineScriptSetupVisitor(context, {
9395
onDefineEmitsEnter(_node, emits) {
94-
for (const emit of emits) {
95-
if (emit.type === 'type') {
96-
continue
97-
}
98-
checker(emit)
99-
}
96+
emits.forEach(checker)
10097
}
10198
})
10299
)

lib/rules/require-explicit-emits.js

+19-17
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@
55
'use strict'
66

77
/**
8-
* @typedef {import('../utils').ComponentArrayEmit} ComponentArrayEmit
9-
* @typedef {import('../utils').ComponentObjectEmit} ComponentObjectEmit
10-
* @typedef {import('../utils').ComponentTypeEmit} ComponentTypeEmit
11-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
12-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
13-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
8+
* @typedef {import('../utils').ComponentEmit} ComponentEmit
9+
* @typedef {import('../utils').ComponentProp} ComponentProp
1410
* @typedef {import('../utils').VueObjectData} VueObjectData
1511
*/
1612

@@ -99,36 +95,36 @@ module.exports = {
9995
const allowProps = !!options.allowProps
10096
/** @type {Map<ObjectExpression | Program, { contextReferenceIds: Set<Identifier>, emitReferenceIds: Set<Identifier> }>} */
10197
const setupContexts = new Map()
102-
/** @type {Map<ObjectExpression | Program, (ComponentArrayEmit | ComponentObjectEmit | ComponentTypeEmit)[]>} */
98+
/** @type {Map<ObjectExpression | Program, ComponentEmit[]>} */
10399
const vueEmitsDeclarations = new Map()
104-
/** @type {Map<ObjectExpression | Program, (ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]>} */
100+
/** @type {Map<ObjectExpression | Program, ComponentProp[]>} */
105101
const vuePropsDeclarations = new Map()
106102

107103
/**
108104
* @typedef {object} VueTemplateDefineData
109105
* @property {'export' | 'mark' | 'definition' | 'setup'} type
110106
* @property {ObjectExpression | Program} define
111-
* @property {(ComponentArrayEmit | ComponentObjectEmit | ComponentTypeEmit)[]} emits
112-
* @property {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
107+
* @property {ComponentEmit[]} emits
108+
* @property {ComponentProp[]} props
113109
* @property {CallExpression} [defineEmits]
114110
*/
115111
/** @type {VueTemplateDefineData | null} */
116112
let vueTemplateDefineData = null
117113

118114
/**
119-
* @param {(ComponentArrayEmit | ComponentObjectEmit | ComponentTypeEmit)[]} emits
120-
* @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props
115+
* @param {ComponentEmit[]} emits
116+
* @param {ComponentProp[]} props
121117
* @param {Literal} nameLiteralNode
122118
* @param {ObjectExpression | Program} vueDefineNode
123119
*/
124120
function verifyEmit(emits, props, nameLiteralNode, vueDefineNode) {
125121
const name = `${nameLiteralNode.value}`
126-
if (emits.some((e) => e.emitName === name)) {
122+
if (emits.some((e) => e.emitName === name || e.emitName == null)) {
127123
return
128124
}
129125
if (allowProps) {
130126
const key = `on${capitalize(name)}`
131-
if (props.some((e) => e.propName === key)) {
127+
if (props.some((e) => e.propName === key || e.propName == null)) {
132128
return
133129
}
134130
}
@@ -311,9 +307,15 @@ module.exports = {
311307
}),
312308
utils.defineVueVisitor(context, {
313309
onVueObjectEnter(node) {
314-
vueEmitsDeclarations.set(node, utils.getComponentEmits(node))
310+
vueEmitsDeclarations.set(
311+
node,
312+
utils.getComponentEmitsFromOptions(node)
313+
)
315314
if (allowProps) {
316-
vuePropsDeclarations.set(node, utils.getComponentProps(node))
315+
vuePropsDeclarations.set(
316+
node,
317+
utils.getComponentPropsFromOptions(node)
318+
)
317319
}
318320
},
319321
onSetupFunctionEnter(node, { node: vueNode }) {
@@ -409,7 +411,7 @@ module.exports = {
409411

410412
/**
411413
* @param {ObjectExpression|Program} define
412-
* @param {(ComponentArrayEmit | ComponentObjectEmit | ComponentTypeEmit)[]} emits
414+
* @param {ComponentEmit[]} emits
413415
* @param {Literal} nameNode
414416
* @param {RuleContext} context
415417
* @returns {Rule.SuggestionReportDescriptor[]}

lib/rules/require-prop-type-constructor.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ const utils = require('../utils')
88
const { isDef } = require('../utils')
99

1010
/**
11-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
12-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
13-
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
11+
* @typedef {import('../utils').ComponentProp} ComponentProp
1412
*/
1513

1614
// ------------------------------------------------------------------------------
@@ -82,7 +80,7 @@ module.exports = {
8280
)
8381
}
8482

85-
/** @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props */
83+
/** @param {ComponentProp[]} props */
8684
function verifyProps(props) {
8785
for (const prop of props) {
8886
if (!prop.value || prop.propName == null) {
@@ -110,7 +108,7 @@ module.exports = {
110108
}
111109
}),
112110
utils.executeOnVueComponent(context, (obj) => {
113-
verifyProps(utils.getComponentProps(obj))
111+
verifyProps(utils.getComponentPropsFromOptions(obj))
114112
})
115113
)
116114
}

lib/rules/require-prop-types.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
const utils = require('../utils')
88

99
/**
10-
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
11-
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
10+
* @typedef {import('../utils').ComponentProp} ComponentProp
1211
*/
1312

1413
// ------------------------------------------------------------------------------
@@ -54,9 +53,13 @@ module.exports = {
5453
}
5554

5655
/**
57-
* @param { ComponentArrayProp | ComponentObjectProp } prop
56+
* @param {ComponentProp} prop
5857
*/
59-
function checkProperty({ value, node, propName }) {
58+
function checkProperty(prop) {
59+
if (prop.type !== 'object' && prop.type !== 'array') {
60+
return
61+
}
62+
const { value, node, propName } = prop
6063
let hasType = true
6164

6265
if (!value) {
@@ -96,15 +99,12 @@ module.exports = {
9699
utils.defineScriptSetupVisitor(context, {
97100
onDefinePropsEnter(_node, props) {
98101
for (const prop of props) {
99-
if (prop.type === 'type') {
100-
continue
101-
}
102102
checkProperty(prop)
103103
}
104104
}
105105
}),
106106
utils.executeOnVue(context, (obj) => {
107-
const props = utils.getComponentProps(obj)
107+
const props = utils.getComponentPropsFromOptions(obj)
108108

109109
for (const prop of props) {
110110
checkProperty(prop)

0 commit comments

Comments
 (0)