11import { Parser as HTMLParser } from 'htmlparser2'
2- import { parse , ParserOptions } from '@babel/parser'
2+ import { parse } from '@babel/parser'
3+ import { PrivateName , Expression , Statement } from '@babel/types'
34import { camelize , capitalize , isHTMLTag , isSVGTag , isVoidTag } from '@vue/shared'
4- import traverse from '@babel/traverse'
55import { ParseResult , TagMeta } from './types'
66
77export function parseVueSFC ( code : string , id ?: string ) : ParseResult {
@@ -43,8 +43,12 @@ export function parseVueSFC(code: string, id?: string): ParseResult {
4343 Object . entries ( attributes ) . forEach ( ( [ key , value ] ) => {
4444 if ( ! value )
4545 return
46- if ( key . startsWith ( 'v-' ) || key . startsWith ( '@' ) || key . startsWith ( ':' ) )
47- expressions . add ( value )
46+ if ( key . startsWith ( 'v-' ) || key . startsWith ( '@' ) || key . startsWith ( ':' ) ) {
47+ if ( key === 'v-if' )
48+ expressions . add ( `for (let ${ value } ) {}` )
49+ else
50+ expressions . add ( `(${ value } )` )
51+ }
4852 if ( key === 'ref' )
4953 identifiers . add ( value )
5054 } )
@@ -71,7 +75,7 @@ export function parseVueSFC(code: string, id?: string): ParseResult {
7175 ontext ( text ) {
7276 if ( templateLevel > 0 ) {
7377 Array . from ( text . matchAll ( / \{ \{ ( .* ?) \} \} / g) ) . forEach ( ( [ , expression ] ) => {
74- expressions . add ( expression )
78+ expressions . add ( `( ${ expression } )` )
7579 } )
7680 }
7781 } ,
@@ -102,7 +106,10 @@ export function parseVueSFC(code: string, id?: string): ParseResult {
102106 parser . write ( code )
103107 parser . end ( )
104108
105- expressions . forEach ( exp => getIdentifiersFromCode ( exp , identifiers ) )
109+ expressions . forEach ( ( exp ) => {
110+ const nodes = parse ( exp ) . program . body
111+ nodes . forEach ( node => getIdentifiersUsage ( node , identifiers ) )
112+ } )
106113
107114 return {
108115 id,
@@ -115,12 +122,70 @@ export function parseVueSFC(code: string, id?: string): ParseResult {
115122 }
116123}
117124
118- export function getIdentifiersFromCode ( code : string , identifiers = new Set < string > ( ) , options : ParserOptions = { } ) {
119- const ast = parse ( code , options ) as any
120- traverse ( ast , {
121- Identifier ( path ) {
122- identifiers . add ( path . node . name )
123- } ,
124- } )
125+ export function getIdentifiersDeclaration ( nodes : Statement [ ] , identifiers = new Set < string > ( ) ) {
126+ for ( const node of nodes ) {
127+ if ( node . type === 'ImportDeclaration' ) {
128+ for ( const specifier of node . specifiers )
129+ identifiers . add ( specifier . local . name )
130+ }
131+ else if ( node . type === 'VariableDeclaration' ) {
132+ for ( const declarator of node . declarations ) {
133+ // @ts -expect-error
134+ identifiers . add ( declarator . id . name )
135+ }
136+ }
137+ else if ( node . type === 'FunctionDeclaration' ) {
138+ if ( node . id )
139+ identifiers . add ( node . id . name )
140+ }
141+ // else {
142+ // console.log(node)
143+ // }
144+ }
145+ return identifiers
146+ }
147+
148+ export function getIdentifiersUsage ( node ?: Expression | PrivateName | Statement , identifiers = new Set < string > ( ) ) {
149+ if ( ! node )
150+ return identifiers
151+
152+ if ( node . type === 'ExpressionStatement' ) {
153+ getIdentifiersUsage ( node . expression , identifiers )
154+ }
155+ else if ( node . type === 'Identifier' ) {
156+ identifiers . add ( node . name )
157+ }
158+ else if ( node . type === 'MemberExpression' ) {
159+ getIdentifiersUsage ( node . object , identifiers )
160+ }
161+ else if ( node . type === 'CallExpression' ) {
162+ // @ts -expect-error
163+ getIdentifiersUsage ( node . callee , identifiers )
164+ node . arguments . forEach ( ( arg ) => {
165+ // @ts -expect-error
166+ getIdentifiersUsage ( arg , identifiers )
167+ } )
168+ }
169+ else if ( node . type === 'BinaryExpression' || node . type === 'LogicalExpression' ) {
170+ getIdentifiersUsage ( node . left , identifiers )
171+ getIdentifiersUsage ( node . right , identifiers )
172+ }
173+ else if ( node . type === 'ForOfStatement' || node . type === 'ForInStatement' ) {
174+ getIdentifiersUsage ( node . right , identifiers )
175+ }
176+ else if ( node . type === 'ConditionalExpression' ) {
177+ getIdentifiersUsage ( node . test , identifiers )
178+ getIdentifiersUsage ( node . consequent , identifiers )
179+ getIdentifiersUsage ( node . alternate , identifiers )
180+ }
181+ else if ( node . type === 'ObjectExpression' ) {
182+ node . properties . forEach ( ( prop ) => {
183+ // @ts -expect-error
184+ getIdentifiersUsage ( prop . value , identifiers )
185+ } )
186+ }
187+ // else {
188+ // console.log(node)
189+ // }
125190 return identifiers
126191}
0 commit comments