@@ -13,6 +13,10 @@ const utils = require('../utils')
13
13
const casing = require ( '../utils/casing' )
14
14
const { toRegExp } = require ( '../utils/regexp' )
15
15
16
+ /**
17
+ * @typedef {import('../utils').VueObjectData } VueObjectData
18
+ */
19
+
16
20
// ------------------------------------------------------------------------------
17
21
// Helpers
18
22
// ------------------------------------------------------------------------------
@@ -103,7 +107,7 @@ module.exports = {
103
107
} ,
104
108
/** @param {RuleContext } context */
105
109
create ( context ) {
106
- /** @type {Map<ObjectExpression, {contextReferenceIds:Set<Identifier>,emitReferenceIds:Set<Identifier>}> } */
110
+ /** @type {Map<ObjectExpression|Program , {contextReferenceIds:Set<Identifier>,emitReferenceIds:Set<Identifier>}> } */
107
111
const setupContexts = new Map ( )
108
112
const options =
109
113
context . options . length === 1 && typeof context . options [ 0 ] !== 'string'
@@ -143,6 +147,46 @@ module.exports = {
143
147
} )
144
148
}
145
149
150
+ const programNode = context . getSourceCode ( ) . ast
151
+
152
+ const callVisitor = {
153
+ /**
154
+ * @param {CallExpression } node
155
+ * @param {VueObjectData } [info]
156
+ */
157
+ CallExpression ( node , info ) {
158
+ const nameLiteralNode = getNameParamNode ( node )
159
+ if ( ! nameLiteralNode ) {
160
+ // cannot check
161
+ return
162
+ }
163
+
164
+ // verify setup context
165
+ const setupContext = setupContexts . get ( info ? info . node : programNode )
166
+ if ( setupContext ) {
167
+ const { contextReferenceIds, emitReferenceIds } = setupContext
168
+ if (
169
+ node . callee . type === 'Identifier' &&
170
+ emitReferenceIds . has ( node . callee )
171
+ ) {
172
+ // verify setup(props,{emit}) {emit()}
173
+ verify ( nameLiteralNode )
174
+ } else {
175
+ const emit = getCalleeMemberNode ( node )
176
+ if (
177
+ emit &&
178
+ emit . name === 'emit' &&
179
+ emit . member . object . type === 'Identifier' &&
180
+ contextReferenceIds . has ( emit . member . object )
181
+ ) {
182
+ // verify setup(props,context) {context.emit()}
183
+ verify ( nameLiteralNode )
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+
146
190
return utils . defineTemplateBodyVisitor (
147
191
context ,
148
192
{
@@ -159,6 +203,36 @@ module.exports = {
159
203
}
160
204
} ,
161
205
utils . compositingVisitors (
206
+ utils . defineScriptSetupVisitor ( context , {
207
+ onDefineEmitsEnter ( node ) {
208
+ if (
209
+ ! node . parent ||
210
+ node . parent . type !== 'VariableDeclarator' ||
211
+ node . parent . init !== node
212
+ ) {
213
+ return
214
+ }
215
+
216
+ const emitParam = node . parent . id
217
+ if ( emitParam . type !== 'Identifier' ) {
218
+ return
219
+ }
220
+ // const emit = defineEmits()
221
+ const variable = findVariable ( context . getScope ( ) , emitParam )
222
+ if ( ! variable ) {
223
+ return
224
+ }
225
+ const emitReferenceIds = new Set ( )
226
+ for ( const reference of variable . references ) {
227
+ emitReferenceIds . add ( reference . identifier )
228
+ }
229
+ setupContexts . set ( programNode , {
230
+ contextReferenceIds : new Set ( ) ,
231
+ emitReferenceIds
232
+ } )
233
+ } ,
234
+ ...callVisitor
235
+ } ) ,
162
236
utils . defineVueVisitor ( context , {
163
237
onSetupFunctionEnter ( node , { node : vueNode } ) {
164
238
const contextParam = utils . skipDefaultParamValue ( node . params [ 1 ] )
@@ -207,37 +281,7 @@ module.exports = {
207
281
emitReferenceIds
208
282
} )
209
283
} ,
210
- CallExpression ( node , { node : vueNode } ) {
211
- const nameLiteralNode = getNameParamNode ( node )
212
- if ( ! nameLiteralNode ) {
213
- // cannot check
214
- return
215
- }
216
-
217
- // verify setup context
218
- const setupContext = setupContexts . get ( vueNode )
219
- if ( setupContext ) {
220
- const { contextReferenceIds, emitReferenceIds } = setupContext
221
- if (
222
- node . callee . type === 'Identifier' &&
223
- emitReferenceIds . has ( node . callee )
224
- ) {
225
- // verify setup(props,{emit}) {emit()}
226
- verify ( nameLiteralNode )
227
- } else {
228
- const emit = getCalleeMemberNode ( node )
229
- if (
230
- emit &&
231
- emit . name === 'emit' &&
232
- emit . member . object . type === 'Identifier' &&
233
- contextReferenceIds . has ( emit . member . object )
234
- ) {
235
- // verify setup(props,context) {context.emit()}
236
- verify ( nameLiteralNode )
237
- }
238
- }
239
- }
240
- } ,
284
+ ...callVisitor ,
241
285
onVueObjectExit ( node ) {
242
286
setupContexts . delete ( node )
243
287
}
0 commit comments