@@ -26,6 +26,82 @@ function defineTemplateBodyVisitor (context, templateBodyVisitor, scriptVisitor)
2626 return context . parserServices . defineTemplateBodyVisitor ( templateBodyVisitor , scriptVisitor )
2727}
2828
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+
29105function findExistLocaleMessage ( fullpath , localeMessages ) {
30106 return localeMessages . find ( message => message . fullpath === fullpath )
31107}
@@ -109,6 +185,7 @@ function generateJsonAst (context, json, filename) {
109185module . exports = {
110186 UNEXPECTED_ERROR_LOCATION ,
111187 defineTemplateBodyVisitor,
188+ executeOnVueComponent,
112189 getLocaleMessages,
113190 findMissingsFromLocaleMessages,
114191 findExistLocaleMessage,
0 commit comments