@@ -264,7 +264,7 @@ module.exports = {
264264 return componentsNode . value . properties
265265 . filter ( p => p . type === 'Property' )
266266 . map ( node => {
267- const name = this . getStaticPropertyName ( node )
267+ const name = getStaticPropertyName ( node )
268268 return name ? { node, name } : null
269269 } )
270270 . filter ( comp => comp != null )
@@ -402,42 +402,7 @@ module.exports = {
402402 * @param {Property|MethodDefinition|MemberExpression|Literal|TemplateLiteral|Identifier } node - The node to get.
403403 * @return {string|null } The property name if static. Otherwise, null.
404404 */
405- getStaticPropertyName ( node ) {
406- let prop
407- switch ( node && node . type ) {
408- case 'Property' :
409- case 'MethodDefinition' :
410- prop = node . key
411- break
412- case 'MemberExpression' :
413- prop = node . property
414- break
415- case 'Literal' :
416- case 'TemplateLiteral' :
417- case 'Identifier' :
418- prop = node
419- break
420- // no default
421- }
422-
423- switch ( prop && prop . type ) {
424- case 'Literal' :
425- return String ( prop . value )
426- case 'TemplateLiteral' :
427- if ( prop . expressions . length === 0 && prop . quasis . length === 1 ) {
428- return prop . quasis [ 0 ] . value . cooked
429- }
430- break
431- case 'Identifier' :
432- if ( ! node . computed ) {
433- return prop . name
434- }
435- break
436- // no default
437- }
438-
439- return null
440- } ,
405+ getStaticPropertyName,
441406
442407 /**
443408 * Get all props by looking at all component's properties
@@ -464,8 +429,8 @@ module.exports = {
464429 . filter ( prop => prop . type === 'Property' )
465430 . map ( prop => {
466431 return {
467- key : prop . key , value : this . unwrapTypes ( prop . value ) , node : prop ,
468- propName : this . getStaticPropertyName ( prop )
432+ key : prop . key , value : unwrapTypes ( prop . value ) , node : prop ,
433+ propName : getStaticPropertyName ( prop )
469434 }
470435 } )
471436 } else {
@@ -548,28 +513,52 @@ module.exports = {
548513 const callee = node . callee
549514
550515 if ( callee . type === 'MemberExpression' ) {
551- const calleeObject = this . unwrapTypes ( callee . object )
516+ const calleeObject = unwrapTypes ( callee . object )
517+
518+ if ( calleeObject . type === 'Identifier' ) {
519+ const propName = getStaticPropertyName ( callee . property )
520+ if ( calleeObject . name === 'Vue' ) {
521+ // for Vue.js 2.x
522+ // Vue.component('xxx', {}) || Vue.mixin({}) || Vue.extend('xxx', {})
523+ const isFullVueComponentForVue2 =
524+ [ 'component' , 'mixin' , 'extend' ] . includes ( propName ) &&
525+ isObjectArgument ( node )
526+
527+ return isFullVueComponentForVue2
528+ }
552529
553- const isFullVueComponent = calleeObject . type === 'Identifier' &&
554- calleeObject . name === 'Vue' &&
555- callee . property . type === 'Identifier' &&
556- [ 'component' , 'mixin' , 'extend' ] . indexOf ( callee . property . name ) > - 1 &&
557- node . arguments . length >= 1 &&
558- node . arguments . slice ( - 1 ) [ 0 ] . type === 'ObjectExpression'
530+ // for Vue.js 3.x
531+ // app.component('xxx', {}) || app.mixin({})
532+ const isFullVueComponent =
533+ [ 'component' , 'mixin' ] . includes ( propName ) &&
534+ isObjectArgument ( node )
559535
560- return isFullVueComponent
536+ return isFullVueComponent
537+ }
561538 }
562539
563540 if ( callee . type === 'Identifier' ) {
564- const isDestructedVueComponent = callee . name === 'component' &&
565- node . arguments . length >= 1 &&
566- node . arguments . slice ( - 1 ) [ 0 ] . type === 'ObjectExpression'
567-
568- return isDestructedVueComponent
541+ if ( callee . name === 'component' ) {
542+ // for Vue.js 2.x
543+ // component('xxx', {})
544+ const isDestructedVueComponent = isObjectArgument ( node )
545+ return isDestructedVueComponent
546+ }
547+ if ( callee . name === 'createApp' ) {
548+ // for Vue.js 3.x
549+ // createApp({})
550+ const isAppVueComponent = isObjectArgument ( node )
551+ return isAppVueComponent
552+ }
569553 }
570554 }
571555
572556 return false
557+
558+ function isObjectArgument ( node ) {
559+ return node . arguments . length > 0 &&
560+ unwrapTypes ( node . arguments . slice ( - 1 ) [ 0 ] ) . type === 'ObjectExpression'
561+ }
573562 } ,
574563
575564 /**
@@ -584,7 +573,7 @@ module.exports = {
584573 callee . type === 'Identifier' &&
585574 callee . name === 'Vue' &&
586575 node . arguments . length &&
587- node . arguments [ 0 ] . type === 'ObjectExpression'
576+ unwrapTypes ( node . arguments [ 0 ] ) . type === 'ObjectExpression'
588577 } ,
589578
590579 /**
@@ -647,7 +636,7 @@ module.exports = {
647636 'CallExpression:exit' ( node ) {
648637 // Vue.component('xxx', {}) || component('xxx', {})
649638 if ( ! _this . isVueComponent ( node ) || isDuplicateNode ( node . arguments . slice ( - 1 ) [ 0 ] ) ) return
650- cb ( node . arguments . slice ( - 1 ) [ 0 ] )
639+ cb ( unwrapTypes ( node . arguments . slice ( - 1 ) [ 0 ] ) )
651640 }
652641 }
653642 } ,
@@ -664,10 +653,10 @@ module.exports = {
664653 const callee = callExpr . callee
665654
666655 if ( callee . type === 'MemberExpression' ) {
667- const calleeObject = this . unwrapTypes ( callee . object )
656+ const calleeObject = unwrapTypes ( callee . object )
668657
669658 if ( calleeObject . type === 'Identifier' &&
670- calleeObject . name === 'Vue' &&
659+ // calleeObject.name === 'Vue' && // Any names can be used in Vue.js 3.x. e.g. app.component()
671660 callee . property === node &&
672661 callExpr . arguments . length >= 1 ) {
673662 cb ( callExpr )
@@ -682,9 +671,9 @@ module.exports = {
682671 * @param {Set } groups Name of parent group
683672 */
684673 * iterateProperties ( node , groups ) {
685- const nodes = node . properties . filter ( p => p . type === 'Property' && groups . has ( this . getStaticPropertyName ( p . key ) ) )
674+ const nodes = node . properties . filter ( p => p . type === 'Property' && groups . has ( getStaticPropertyName ( p . key ) ) )
686675 for ( const item of nodes ) {
687- const name = this . getStaticPropertyName ( item . key )
676+ const name = getStaticPropertyName ( item . key )
688677 if ( ! name ) continue
689678
690679 if ( item . value . type === 'ArrayExpression' ) {
@@ -705,7 +694,7 @@ module.exports = {
705694 * iterateArrayExpression ( node , groupName ) {
706695 assert ( node . type === 'ArrayExpression' )
707696 for ( const item of node . elements ) {
708- const name = this . getStaticPropertyName ( item )
697+ const name = getStaticPropertyName ( item )
709698 if ( name ) {
710699 const obj = { name, groupName, node : item }
711700 yield obj
@@ -721,7 +710,7 @@ module.exports = {
721710 * iterateObjectExpression ( node , groupName ) {
722711 assert ( node . type === 'ObjectExpression' )
723712 for ( const item of node . properties ) {
724- const name = this . getStaticPropertyName ( item )
713+ const name = getStaticPropertyName ( item )
725714 if ( name ) {
726715 const obj = { name, groupName, node : item . key }
727716 yield obj
@@ -865,7 +854,56 @@ module.exports = {
865854 * @param {T } node
866855 * @return {T }
867856 */
868- unwrapTypes ( node ) {
869- return node . type === 'TSAsExpression' ? node . expression : node
857+ unwrapTypes
858+ }
859+ /**
860+ * Unwrap typescript types like "X as F"
861+ * @template T
862+ * @param {T } node
863+ * @return {T }
864+ */
865+ function unwrapTypes ( node ) {
866+ return node . type === 'TSAsExpression' ? node . expression : node
867+ }
868+
869+ /**
870+ * Gets the property name of a given node.
871+ * @param {Property|MethodDefinition|MemberExpression|Literal|TemplateLiteral|Identifier } node - The node to get.
872+ * @return {string|null } The property name if static. Otherwise, null.
873+ */
874+ function getStaticPropertyName ( node ) {
875+ let prop
876+ switch ( node && node . type ) {
877+ case 'Property' :
878+ case 'MethodDefinition' :
879+ prop = node . key
880+ break
881+ case 'MemberExpression' :
882+ prop = node . property
883+ break
884+ case 'Literal' :
885+ case 'TemplateLiteral' :
886+ case 'Identifier' :
887+ prop = node
888+ break
889+ // no default
870890 }
891+
892+ switch ( prop && prop . type ) {
893+ case 'Literal' :
894+ return String ( prop . value )
895+ case 'TemplateLiteral' :
896+ if ( prop . expressions . length === 0 && prop . quasis . length === 1 ) {
897+ return prop . quasis [ 0 ] . value . cooked
898+ }
899+ break
900+ case 'Identifier' :
901+ if ( ! node . computed ) {
902+ return prop . name
903+ }
904+ break
905+ // no default
906+ }
907+
908+ return null
871909}
0 commit comments