@@ -264,7 +264,7 @@ module.exports = {
264
264
return componentsNode . value . properties
265
265
. filter ( p => p . type === 'Property' )
266
266
. map ( node => {
267
- const name = this . getStaticPropertyName ( node )
267
+ const name = getStaticPropertyName ( node )
268
268
return name ? { node, name } : null
269
269
} )
270
270
. filter ( comp => comp != null )
@@ -402,42 +402,7 @@ module.exports = {
402
402
* @param {Property|MethodDefinition|MemberExpression|Literal|TemplateLiteral|Identifier } node - The node to get.
403
403
* @return {string|null } The property name if static. Otherwise, null.
404
404
*/
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,
441
406
442
407
/**
443
408
* Get all props by looking at all component's properties
@@ -464,8 +429,8 @@ module.exports = {
464
429
. filter ( prop => prop . type === 'Property' )
465
430
. map ( prop => {
466
431
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 )
469
434
}
470
435
} )
471
436
} else {
@@ -548,28 +513,52 @@ module.exports = {
548
513
const callee = node . callee
549
514
550
515
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
+ }
552
529
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 )
559
535
560
- return isFullVueComponent
536
+ return isFullVueComponent
537
+ }
561
538
}
562
539
563
540
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
+ }
569
553
}
570
554
}
571
555
572
556
return false
557
+
558
+ function isObjectArgument ( node ) {
559
+ return node . arguments . length > 0 &&
560
+ unwrapTypes ( node . arguments . slice ( - 1 ) [ 0 ] ) . type === 'ObjectExpression'
561
+ }
573
562
} ,
574
563
575
564
/**
@@ -584,7 +573,7 @@ module.exports = {
584
573
callee . type === 'Identifier' &&
585
574
callee . name === 'Vue' &&
586
575
node . arguments . length &&
587
- node . arguments [ 0 ] . type === 'ObjectExpression'
576
+ unwrapTypes ( node . arguments [ 0 ] ) . type === 'ObjectExpression'
588
577
} ,
589
578
590
579
/**
@@ -647,7 +636,7 @@ module.exports = {
647
636
'CallExpression:exit' ( node ) {
648
637
// Vue.component('xxx', {}) || component('xxx', {})
649
638
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 ] ) )
651
640
}
652
641
}
653
642
} ,
@@ -664,10 +653,10 @@ module.exports = {
664
653
const callee = callExpr . callee
665
654
666
655
if ( callee . type === 'MemberExpression' ) {
667
- const calleeObject = this . unwrapTypes ( callee . object )
656
+ const calleeObject = unwrapTypes ( callee . object )
668
657
669
658
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()
671
660
callee . property === node &&
672
661
callExpr . arguments . length >= 1 ) {
673
662
cb ( callExpr )
@@ -682,9 +671,9 @@ module.exports = {
682
671
* @param {Set } groups Name of parent group
683
672
*/
684
673
* 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 ) ) )
686
675
for ( const item of nodes ) {
687
- const name = this . getStaticPropertyName ( item . key )
676
+ const name = getStaticPropertyName ( item . key )
688
677
if ( ! name ) continue
689
678
690
679
if ( item . value . type === 'ArrayExpression' ) {
@@ -705,7 +694,7 @@ module.exports = {
705
694
* iterateArrayExpression ( node , groupName ) {
706
695
assert ( node . type === 'ArrayExpression' )
707
696
for ( const item of node . elements ) {
708
- const name = this . getStaticPropertyName ( item )
697
+ const name = getStaticPropertyName ( item )
709
698
if ( name ) {
710
699
const obj = { name, groupName, node : item }
711
700
yield obj
@@ -721,7 +710,7 @@ module.exports = {
721
710
* iterateObjectExpression ( node , groupName ) {
722
711
assert ( node . type === 'ObjectExpression' )
723
712
for ( const item of node . properties ) {
724
- const name = this . getStaticPropertyName ( item )
713
+ const name = getStaticPropertyName ( item )
725
714
if ( name ) {
726
715
const obj = { name, groupName, node : item . key }
727
716
yield obj
@@ -865,7 +854,56 @@ module.exports = {
865
854
* @param {T } node
866
855
* @return {T }
867
856
*/
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
870
890
}
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
871
909
}
0 commit comments