@@ -3,7 +3,7 @@ import type * as ts from 'typescript';
3
3
import type { Code , VueCodeInformation } from '../../types' ;
4
4
import { getNodeText , getStartEnd } from '../../utils/shared' ;
5
5
import type { ScriptCodegenOptions } from '../script' ;
6
- import { collectVars , createTsAst , identifierRegex } from '../utils' ;
6
+ import { collectBindingNames , createTsAst , identifierRegex } from '../utils' ;
7
7
import type { TemplateCodegenContext } from './context' ;
8
8
import type { TemplateCodegenOptions } from './index' ;
9
9
@@ -126,7 +126,7 @@ function* forEachInterpolationSegment(
126
126
} ) ;
127
127
}
128
128
} ;
129
- ts . forEachChild ( ast , node => walkIdentifiers ( ts , node , ast , varCb , ctx ) ) ;
129
+ ts . forEachChild ( ast , node => walkIdentifiers ( ts , node , ast , varCb , ctx , [ ] , true ) ) ;
130
130
}
131
131
132
132
ctxVars = ctxVars . sort ( ( a , b ) => a . offset - b . offset ) ;
@@ -198,8 +198,8 @@ function walkIdentifiers(
198
198
ast : ts . SourceFile ,
199
199
cb : ( varNode : ts . Identifier , isShorthand : boolean ) => void ,
200
200
ctx : TemplateCodegenContext ,
201
- blockVars : string [ ] = [ ] ,
202
- isRoot : boolean = true ,
201
+ blockVars : string [ ] ,
202
+ isRoot : boolean = false ,
203
203
) {
204
204
if ( ts . isIdentifier ( node ) ) {
205
205
cb ( node , false ) ;
@@ -208,56 +208,57 @@ function walkIdentifiers(
208
208
cb ( node . name , true ) ;
209
209
}
210
210
else if ( ts . isPropertyAccessExpression ( node ) ) {
211
- walkIdentifiers ( ts , node . expression , ast , cb , ctx , blockVars , false ) ;
211
+ walkIdentifiers ( ts , node . expression , ast , cb , ctx , blockVars ) ;
212
212
}
213
213
else if ( ts . isVariableDeclaration ( node ) ) {
214
- collectVars ( ts , node . name , ast , blockVars ) ;
214
+ const bindingNames = collectBindingNames ( ts , node . name , ast ) ;
215
215
216
- for ( const varName of blockVars ) {
217
- ctx . addLocalVariable ( varName ) ;
216
+ for ( const name of bindingNames ) {
217
+ ctx . addLocalVariable ( name ) ;
218
+ blockVars . push ( name ) ;
218
219
}
219
220
220
221
if ( node . initializer ) {
221
- walkIdentifiers ( ts , node . initializer , ast , cb , ctx , blockVars , false ) ;
222
+ walkIdentifiers ( ts , node . initializer , ast , cb , ctx , blockVars ) ;
222
223
}
223
224
}
224
225
else if ( ts . isArrowFunction ( node ) || ts . isFunctionExpression ( node ) ) {
225
- processFunction ( ts , node , ast , cb , ctx ) ;
226
+ walkIdentifiersInFunction ( ts , node , ast , cb , ctx ) ;
226
227
}
227
228
else if ( ts . isObjectLiteralExpression ( node ) ) {
228
229
for ( const prop of node . properties ) {
229
230
if ( ts . isPropertyAssignment ( prop ) ) {
230
231
// fix https://github.com/vuejs/language-tools/issues/1176
231
232
if ( ts . isComputedPropertyName ( prop . name ) ) {
232
- walkIdentifiers ( ts , prop . name . expression , ast , cb , ctx , blockVars , false ) ;
233
+ walkIdentifiers ( ts , prop . name . expression , ast , cb , ctx , blockVars ) ;
233
234
}
234
- walkIdentifiers ( ts , prop . initializer , ast , cb , ctx , blockVars , false ) ;
235
+ walkIdentifiers ( ts , prop . initializer , ast , cb , ctx , blockVars ) ;
235
236
}
236
237
// fix https://github.com/vuejs/language-tools/issues/1156
237
238
else if ( ts . isShorthandPropertyAssignment ( prop ) ) {
238
- walkIdentifiers ( ts , prop , ast , cb , ctx , blockVars , false ) ;
239
+ walkIdentifiers ( ts , prop , ast , cb , ctx , blockVars ) ;
239
240
}
240
241
// fix https://github.com/vuejs/language-tools/issues/1148#issuecomment-1094378126
241
242
else if ( ts . isSpreadAssignment ( prop ) ) {
242
243
// TODO: cannot report "Spread types may only be created from object types.ts(2698)"
243
- walkIdentifiers ( ts , prop . expression , ast , cb , ctx , blockVars , false ) ;
244
+ walkIdentifiers ( ts , prop . expression , ast , cb , ctx , blockVars ) ;
244
245
}
245
246
// fix https://github.com/vuejs/language-tools/issues/4604
246
247
else if ( ts . isFunctionLike ( prop ) && prop . body ) {
247
- processFunction ( ts , prop , ast , cb , ctx ) ;
248
+ walkIdentifiersInFunction ( ts , prop , ast , cb , ctx ) ;
248
249
}
249
250
}
250
251
}
252
+ // fix https://github.com/vuejs/language-tools/issues/1422
251
253
else if ( ts . isTypeNode ( node ) ) {
252
- // fix https://github.com/vuejs/language-tools/issues/1422
253
254
walkIdentifiersInTypeNode ( ts , node , cb ) ;
254
255
}
255
256
else {
256
257
const _blockVars = blockVars ;
257
258
if ( ts . isBlock ( node ) ) {
258
259
blockVars = [ ] ;
259
260
}
260
- ts . forEachChild ( node , node => walkIdentifiers ( ts , node , ast , cb , ctx , blockVars , false ) ) ;
261
+ ts . forEachChild ( node , node => walkIdentifiers ( ts , node , ast , cb , ctx , blockVars ) ) ;
261
262
if ( ts . isBlock ( node ) ) {
262
263
for ( const varName of blockVars ) {
263
264
ctx . removeLocalVariable ( varName ) ;
@@ -273,7 +274,7 @@ function walkIdentifiers(
273
274
}
274
275
}
275
276
276
- function processFunction (
277
+ function walkIdentifiersInFunction (
277
278
ts : typeof import ( 'typescript' ) ,
278
279
node : ts . ArrowFunction | ts . FunctionExpression | ts . AccessorDeclaration | ts . MethodDeclaration ,
279
280
ast : ts . SourceFile ,
@@ -282,16 +283,16 @@ function processFunction(
282
283
) {
283
284
const functionArgs : string [ ] = [ ] ;
284
285
for ( const param of node . parameters ) {
285
- collectVars ( ts , param . name , ast , functionArgs ) ;
286
+ functionArgs . push ( ... collectBindingNames ( ts , param . name , ast ) ) ;
286
287
if ( param . type ) {
287
- walkIdentifiers ( ts , param . type , ast , cb , ctx ) ;
288
+ walkIdentifiersInTypeNode ( ts , param . type , cb ) ;
288
289
}
289
290
}
290
291
for ( const varName of functionArgs ) {
291
292
ctx . addLocalVariable ( varName ) ;
292
293
}
293
294
if ( node . body ) {
294
- walkIdentifiers ( ts , node . body , ast , cb , ctx ) ;
295
+ walkIdentifiers ( ts , node . body , ast , cb , ctx , [ ] , true ) ;
295
296
}
296
297
for ( const varName of functionArgs ) {
297
298
ctx . removeLocalVariable ( varName ) ;
0 commit comments