@@ -26,6 +26,82 @@ function defineTemplateBodyVisitor (context, templateBodyVisitor, scriptVisitor)
26
26
return context . parserServices . defineTemplateBodyVisitor ( templateBodyVisitor , scriptVisitor )
27
27
}
28
28
29
+ function unwrapTypes ( node ) {
30
+ return node . type === 'TSAsExpression' ? node . expression : node
31
+ }
32
+
33
+ function isVueFile ( path ) {
34
+ return path . endsWith ( '.vue' ) || path . endsWith ( '.jsx' )
35
+ }
36
+
37
+ function isVueComponentFile ( node , path ) {
38
+ return isVueFile ( path ) &&
39
+ node . type === 'ExportDefaultDeclaration' &&
40
+ node . declaration . type === 'ObjectExpression'
41
+ }
42
+
43
+ function isVueComponent ( node ) {
44
+ if ( node . type === 'CallExpression' ) {
45
+ const callee = node . callee
46
+
47
+ if ( callee . type === 'MemberExpression' ) {
48
+ const calleeObject = unwrapTypes ( callee . object )
49
+
50
+ const isFullVueComponent = calleeObject . type === 'Identifier' &&
51
+ calleeObject . name === 'Vue' &&
52
+ callee . property . type === 'Identifier' &&
53
+ [ 'component' , 'mixin' , 'extend' ] . indexOf ( callee . property . name ) > - 1 &&
54
+ node . arguments . length >= 1 &&
55
+ node . arguments . slice ( - 1 ) [ 0 ] . type === 'ObjectExpression'
56
+
57
+ return isFullVueComponent
58
+ }
59
+
60
+ if ( callee . type === 'Identifier' ) {
61
+ const isDestructedVueComponent = callee . name === 'component' &&
62
+ node . arguments . length >= 1 &&
63
+ node . arguments . slice ( - 1 ) [ 0 ] . type === 'ObjectExpression'
64
+
65
+ return isDestructedVueComponent
66
+ }
67
+ }
68
+
69
+ return false
70
+ }
71
+
72
+ function executeOnVueComponent ( context , cb ) {
73
+ const filePath = context . getFilename ( )
74
+ const sourceCode = context . getSourceCode ( )
75
+ const componentComments = sourceCode . getAllComments ( ) . filter ( comment => / @ v u e \/ c o m p o n e n t / g. test ( comment . value ) )
76
+ const foundNodes = [ ]
77
+
78
+ const isDuplicateNode = node => {
79
+ if ( foundNodes . some ( el => el . loc . start . line === node . loc . start . line ) ) { return true }
80
+ foundNodes . push ( node )
81
+ return false
82
+ }
83
+
84
+ return {
85
+ 'ObjectExpression:exit' ( node ) {
86
+ console . log ( 'ObjectExpression' , filePath , node )
87
+ if ( ! componentComments . some ( el => el . loc . end . line === node . loc . start . line - 1 ) || isDuplicateNode ( node ) ) { return }
88
+ cb ( node )
89
+ } ,
90
+ 'ExportDefaultDeclaration:exit' ( node ) {
91
+ console . log ( 'ExportDefaultDeclaration' , filePath , node )
92
+ // export default {} in .vue || .js(x)
93
+ if ( isDuplicateNode ( node . declaration ) ) { return }
94
+ cb ( node . declaration )
95
+ } ,
96
+ 'CallExpression:exit' ( node ) {
97
+ console . log ( 'CallExpression:exit' )
98
+ // Vue.component('xxx', {}) || component('xxx', {})
99
+ if ( ! isVueComponent ( node ) || isDuplicateNode ( node . arguments . slice ( - 1 ) [ 0 ] ) ) { return }
100
+ cb ( node . arguments . slice ( - 1 ) [ 0 ] )
101
+ }
102
+ }
103
+ }
104
+
29
105
function findExistLocaleMessage ( fullpath , localeMessages ) {
30
106
return localeMessages . find ( message => message . fullpath === fullpath )
31
107
}
@@ -109,6 +185,7 @@ function generateJsonAst (context, json, filename) {
109
185
module . exports = {
110
186
UNEXPECTED_ERROR_LOCATION ,
111
187
defineTemplateBodyVisitor,
188
+ executeOnVueComponent,
112
189
getLocaleMessages,
113
190
findMissingsFromLocaleMessages,
114
191
findExistLocaleMessage,
0 commit comments