@@ -13,6 +13,10 @@ const utils = require('../utils')
1313const casing = require ( '../utils/casing' )
1414const { toRegExp } = require ( '../utils/regexp' )
1515
16+ /**
17+ * @typedef {import('../utils').VueObjectData } VueObjectData
18+ */
19+
1620// ------------------------------------------------------------------------------
1721// Helpers
1822// ------------------------------------------------------------------------------
@@ -103,7 +107,7 @@ module.exports = {
103107 } ,
104108 /** @param {RuleContext } context */
105109 create ( context ) {
106- /** @type {Map<ObjectExpression, {contextReferenceIds:Set<Identifier>,emitReferenceIds:Set<Identifier>}> } */
110+ /** @type {Map<ObjectExpression|Program , {contextReferenceIds:Set<Identifier>,emitReferenceIds:Set<Identifier>}> } */
107111 const setupContexts = new Map ( )
108112 const options =
109113 context . options . length === 1 && typeof context . options [ 0 ] !== 'string'
@@ -143,6 +147,46 @@ module.exports = {
143147 } )
144148 }
145149
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+
146190 return utils . defineTemplateBodyVisitor (
147191 context ,
148192 {
@@ -159,6 +203,36 @@ module.exports = {
159203 }
160204 } ,
161205 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+ } ) ,
162236 utils . defineVueVisitor ( context , {
163237 onSetupFunctionEnter ( node , { node : vueNode } ) {
164238 const contextParam = utils . skipDefaultParamValue ( node . params [ 1 ] )
@@ -207,37 +281,7 @@ module.exports = {
207281 emitReferenceIds
208282 } )
209283 } ,
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 ,
241285 onVueObjectExit ( node ) {
242286 setupContexts . delete ( node )
243287 }
0 commit comments