@@ -96,11 +96,11 @@ export default createRule('no-navigation-without-resolve', {
96
96
}
97
97
if (
98
98
( node . value [ 0 ] . type === 'SvelteLiteral' &&
99
- ! expressionIsAbsolute ( node . value [ 0 ] ) &&
100
- ! expressionIsFragment ( node . value [ 0 ] ) ) ||
99
+ ! expressionIsAbsolute ( node . value [ 0 ] , context ) &&
100
+ ! expressionIsFragment ( node . value [ 0 ] , context ) ) ||
101
101
( node . value [ 0 ] . type === 'SvelteMustacheTag' &&
102
- ! expressionIsAbsolute ( node . value [ 0 ] . expression ) &&
103
- ! expressionIsFragment ( node . value [ 0 ] . expression ) &&
102
+ ! expressionIsAbsolute ( node . value [ 0 ] . expression , context ) &&
103
+ ! expressionIsFragment ( node . value [ 0 ] . expression , context ) &&
104
104
! isResolveCall ( context , node . value [ 0 ] . expression , resolveReferences ) )
105
105
) {
106
106
context . report ( { loc : node . value [ 0 ] . loc , messageId : 'linkWithoutResolve' } ) ;
@@ -252,31 +252,49 @@ function expressionIsEmpty(url: TSESTree.CallExpressionArgument): boolean {
252
252
) ;
253
253
}
254
254
255
- function expressionIsAbsolute ( url : AST . SvelteLiteral | TSESTree . Expression ) : boolean {
255
+ function expressionIsAbsolute (
256
+ url : AST . SvelteLiteral | TSESTree . Expression ,
257
+ context : RuleContext
258
+ ) : boolean {
256
259
switch ( url . type ) {
257
260
case 'BinaryExpression' :
258
- return binaryExpressionIsAbsolute ( url ) ;
261
+ return binaryExpressionIsAbsolute ( url , context ) ;
262
+ case 'Identifier' :
263
+ return identifierIsAbsolute ( url , context ) ;
259
264
case 'Literal' :
260
265
return typeof url . value === 'string' && urlValueIsAbsolute ( url . value ) ;
261
266
case 'SvelteLiteral' :
262
267
return urlValueIsAbsolute ( url . value ) ;
263
268
case 'TemplateLiteral' :
264
- return templateLiteralIsAbsolute ( url ) ;
269
+ return templateLiteralIsAbsolute ( url , context ) ;
265
270
default :
266
271
return false ;
267
272
}
268
273
}
269
274
270
- function binaryExpressionIsAbsolute ( url : TSESTree . BinaryExpression ) : boolean {
275
+ function binaryExpressionIsAbsolute ( url : TSESTree . BinaryExpression , context : RuleContext ) : boolean {
271
276
return (
272
- ( url . left . type !== 'PrivateIdentifier' && expressionIsAbsolute ( url . left ) ) ||
273
- expressionIsAbsolute ( url . right )
277
+ ( url . left . type !== 'PrivateIdentifier' && expressionIsAbsolute ( url . left , context ) ) ||
278
+ expressionIsAbsolute ( url . right , context )
274
279
) ;
275
280
}
276
281
277
- function templateLiteralIsAbsolute ( url : TSESTree . TemplateLiteral ) : boolean {
282
+ function identifierIsAbsolute ( url : TSESTree . Identifier , context : RuleContext ) : boolean {
283
+ const variable = findVariable ( context , url ) ;
284
+ if (
285
+ variable === null ||
286
+ variable . identifiers . length === 0 ||
287
+ variable . identifiers [ 0 ] . parent . type !== 'VariableDeclarator' ||
288
+ variable . identifiers [ 0 ] . parent . init === null
289
+ ) {
290
+ return false ;
291
+ }
292
+ return expressionIsAbsolute ( variable . identifiers [ 0 ] . parent . init , context ) ;
293
+ }
294
+
295
+ function templateLiteralIsAbsolute ( url : TSESTree . TemplateLiteral , context : RuleContext ) : boolean {
278
296
return (
279
- url . expressions . some ( expressionIsAbsolute ) ||
297
+ url . expressions . some ( ( expression ) => expressionIsAbsolute ( expression , context ) ) ||
280
298
url . quasis . some ( ( quasi ) => urlValueIsAbsolute ( quasi . value . raw ) )
281
299
) ;
282
300
}
@@ -285,28 +303,46 @@ function urlValueIsAbsolute(url: string): boolean {
285
303
return / ^ [ + a - z ] * : / i. test ( url ) ;
286
304
}
287
305
288
- function expressionIsFragment ( url : AST . SvelteLiteral | TSESTree . Expression ) : boolean {
306
+ function expressionIsFragment (
307
+ url : AST . SvelteLiteral | TSESTree . Expression ,
308
+ context : RuleContext
309
+ ) : boolean {
289
310
switch ( url . type ) {
290
311
case 'BinaryExpression' :
291
- return binaryExpressionIsFragment ( url ) ;
312
+ return binaryExpressionIsFragment ( url , context ) ;
313
+ case 'Identifier' :
314
+ return identifierIsFragment ( url , context ) ;
292
315
case 'Literal' :
293
316
return typeof url . value === 'string' && urlValueIsFragment ( url . value ) ;
294
317
case 'SvelteLiteral' :
295
318
return urlValueIsFragment ( url . value ) ;
296
319
case 'TemplateLiteral' :
297
- return templateLiteralIsFragment ( url ) ;
320
+ return templateLiteralIsFragment ( url , context ) ;
298
321
default :
299
322
return false ;
300
323
}
301
324
}
302
325
303
- function binaryExpressionIsFragment ( url : TSESTree . BinaryExpression ) : boolean {
304
- return url . left . type !== 'PrivateIdentifier' && expressionIsFragment ( url . left ) ;
326
+ function binaryExpressionIsFragment ( url : TSESTree . BinaryExpression , context : RuleContext ) : boolean {
327
+ return url . left . type !== 'PrivateIdentifier' && expressionIsFragment ( url . left , context ) ;
328
+ }
329
+
330
+ function identifierIsFragment ( url : TSESTree . Identifier , context : RuleContext ) : boolean {
331
+ const variable = findVariable ( context , url ) ;
332
+ if (
333
+ variable === null ||
334
+ variable . identifiers . length === 0 ||
335
+ variable . identifiers [ 0 ] . parent . type !== 'VariableDeclarator' ||
336
+ variable . identifiers [ 0 ] . parent . init === null
337
+ ) {
338
+ return false ;
339
+ }
340
+ return expressionIsFragment ( variable . identifiers [ 0 ] . parent . init , context ) ;
305
341
}
306
342
307
- function templateLiteralIsFragment ( url : TSESTree . TemplateLiteral ) : boolean {
343
+ function templateLiteralIsFragment ( url : TSESTree . TemplateLiteral , context : RuleContext ) : boolean {
308
344
return (
309
- ( url . expressions . length >= 1 && expressionIsFragment ( url . expressions [ 0 ] ) ) ||
345
+ ( url . expressions . length >= 1 && expressionIsFragment ( url . expressions [ 0 ] , context ) ) ||
310
346
( url . quasis . length >= 1 && urlValueIsFragment ( url . quasis [ 0 ] . value . raw ) )
311
347
) ;
312
348
}
0 commit comments