@@ -4,11 +4,12 @@ use crate::generated::{self};
4
4
use crate :: trap:: { DiagnosticSeverity , TrapFile , TrapId } ;
5
5
use crate :: trap:: { Label , TrapClass } ;
6
6
use codeql_extractor:: trap:: { self } ;
7
+ use itertools:: Either ;
7
8
use log:: Level ;
8
9
use ra_ap_base_db:: salsa:: InternKey ;
9
10
use ra_ap_base_db:: CrateOrigin ;
10
11
use ra_ap_hir:: db:: ExpandDatabase ;
11
- use ra_ap_hir:: { Adt , ItemContainer , Module , Semantics , Type } ;
12
+ use ra_ap_hir:: { Adt , Crate , ItemContainer , Module , ModuleDef , PathResolution , Semantics , Type } ;
12
13
use ra_ap_hir_def:: type_ref:: Mutability ;
13
14
use ra_ap_hir_def:: ModuleId ;
14
15
use ra_ap_hir_expand:: ExpandTo ;
@@ -46,6 +47,12 @@ macro_rules! emit_detached {
46
47
$self. extract_canonical_origin( & $node, $label. into( ) ) ;
47
48
} ;
48
49
// TODO canonical origin of other items
50
+ ( Path , $self: ident, $node: ident, $label: ident) => {
51
+ $self. extract_canonical_destination( & $node, $label) ;
52
+ } ;
53
+ ( MethodCallExpr , $self: ident, $node: ident, $label: ident) => {
54
+ $self. extract_method_canonical_destination( & $node, $label) ;
55
+ } ;
49
56
( $( $_: tt) * ) => { } ;
50
57
}
51
58
@@ -276,13 +283,13 @@ impl<'a> Translator<'a> {
276
283
} else {
277
284
let range = self . text_range_for_node ( mcall) ;
278
285
self . emit_parse_error ( mcall, & SyntaxError :: new (
279
- format ! (
280
- "macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected" ,
281
- mcall. path( ) . map( |p| p. to_string( ) ) . unwrap_or_default( ) ,
282
- kind, expand_to
283
- ) ,
284
- range. unwrap_or_else ( || TextRange :: empty ( TextSize :: from ( 0 ) ) ) ,
285
- ) ) ;
286
+ format ! (
287
+ "macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected" ,
288
+ mcall. path( ) . map( |p| p. to_string( ) ) . unwrap_or_default( ) ,
289
+ kind, expand_to
290
+ ) ,
291
+ range. unwrap_or_else ( || TextRange :: empty ( TextSize :: from ( 0 ) ) ) ,
292
+ ) ) ;
286
293
}
287
294
} else {
288
295
let range = self . text_range_for_node ( mcall) ;
@@ -380,10 +387,34 @@ impl<'a> Translator<'a> {
380
387
Some ( format ! ( "{prefix}::{name}" ) )
381
388
}
382
389
390
+ fn canonical_path_from_module_def ( & self , item : ModuleDef ) -> Option < String > {
391
+ match item {
392
+ ModuleDef :: Module ( it) => self . canonical_path_from_hir ( it) ,
393
+ ModuleDef :: Function ( it) => self . canonical_path_from_hir ( it) ,
394
+ ModuleDef :: Adt ( Adt :: Enum ( it) ) => self . canonical_path_from_hir ( it) ,
395
+ ModuleDef :: Adt ( Adt :: Struct ( it) ) => self . canonical_path_from_hir ( it) ,
396
+ ModuleDef :: Adt ( Adt :: Union ( it) ) => self . canonical_path_from_hir ( it) ,
397
+ ModuleDef :: Trait ( it) => self . canonical_path_from_hir ( it) ,
398
+ ModuleDef :: Static ( _) => None ,
399
+ ModuleDef :: TraitAlias ( _) => None ,
400
+ ModuleDef :: TypeAlias ( _) => None ,
401
+ ModuleDef :: BuiltinType ( _) => None ,
402
+ ModuleDef :: Macro ( _) => None ,
403
+ ModuleDef :: Variant ( _) => None ,
404
+ ModuleDef :: Const ( _) => None ,
405
+ }
406
+ }
407
+
383
408
fn origin_from_hir < T : AstNode > ( & self , item : impl AddressableHir < T > ) -> String {
384
409
// if we have a Hir entity, it means we have semantics
385
410
let sema = self . semantics . as_ref ( ) . unwrap ( ) ;
386
- match item. module ( sema) . krate ( ) . origin ( sema. db ) {
411
+ self . origin_from_crate ( item. module ( sema) . krate ( ) )
412
+ }
413
+
414
+ fn origin_from_crate ( & self , item : Crate ) -> String {
415
+ // if we have a Hir entity, it means we have semantics
416
+ let sema = self . semantics . as_ref ( ) . unwrap ( ) ;
417
+ match item. origin ( sema. db ) {
387
418
CrateOrigin :: Rustc { name } => format ! ( "rustc:{}" , name) ,
388
419
CrateOrigin :: Local { repo, name } => format ! (
389
420
"repo:{}:{}" ,
@@ -397,6 +428,24 @@ impl<'a> Translator<'a> {
397
428
}
398
429
}
399
430
431
+ fn origin_from_module_def ( & self , item : ModuleDef ) -> Option < String > {
432
+ match item {
433
+ ModuleDef :: Module ( it) => Some ( self . origin_from_hir ( it) ) ,
434
+ ModuleDef :: Function ( it) => Some ( self . origin_from_hir ( it) ) ,
435
+ ModuleDef :: Adt ( Adt :: Enum ( it) ) => Some ( self . origin_from_hir ( it) ) ,
436
+ ModuleDef :: Adt ( Adt :: Struct ( it) ) => Some ( self . origin_from_hir ( it) ) ,
437
+ ModuleDef :: Adt ( Adt :: Union ( it) ) => Some ( self . origin_from_hir ( it) ) ,
438
+ ModuleDef :: Trait ( it) => Some ( self . origin_from_hir ( it) ) ,
439
+ ModuleDef :: Static ( _) => None ,
440
+ ModuleDef :: TraitAlias ( _) => None ,
441
+ ModuleDef :: TypeAlias ( _) => None ,
442
+ ModuleDef :: BuiltinType ( _) => None ,
443
+ ModuleDef :: Macro ( _) => None ,
444
+ ModuleDef :: Variant ( _) => None ,
445
+ ModuleDef :: Const ( _) => None ,
446
+ }
447
+ }
448
+
400
449
pub ( crate ) fn extract_canonical_origin < T : AddressableAst + HasName > (
401
450
& mut self ,
402
451
item : & T ,
@@ -412,4 +461,50 @@ impl<'a> Translator<'a> {
412
461
Some ( ( ) )
413
462
} ) ( ) ;
414
463
}
464
+
465
+ pub ( crate ) fn extract_canonical_destination (
466
+ & mut self ,
467
+ item : & ast:: Path ,
468
+ label : Label < generated:: Path > ,
469
+ ) {
470
+ ( || {
471
+ let sema = self . semantics . as_ref ( ) ?;
472
+ let resolution = sema. resolve_path ( item) ?;
473
+ let PathResolution :: Def ( def) = resolution else {
474
+ return None ;
475
+ } ;
476
+ let origin = self . origin_from_module_def ( def) ?;
477
+ let path = self . canonical_path_from_module_def ( def) ?;
478
+ generated:: Resolvable :: emit_resolved_crate_origin (
479
+ label. into ( ) ,
480
+ origin,
481
+ & mut self . trap . writer ,
482
+ ) ;
483
+ generated:: Resolvable :: emit_resolved_path ( label. into ( ) , path, & mut self . trap . writer ) ;
484
+ Some ( ( ) )
485
+ } ) ( ) ;
486
+ }
487
+
488
+ pub ( crate ) fn extract_method_canonical_destination (
489
+ & mut self ,
490
+ item : & ast:: MethodCallExpr ,
491
+ label : Label < generated:: MethodCallExpr > ,
492
+ ) {
493
+ ( || {
494
+ let sema = self . semantics . as_ref ( ) ?;
495
+ let resolved = sema. resolve_method_call_fallback ( item) ?;
496
+ let Either :: Left ( function) = resolved else {
497
+ return None ;
498
+ } ;
499
+ let origin = self . origin_from_hir ( function) ;
500
+ let path = self . canonical_path_from_hir ( function) ?;
501
+ generated:: Resolvable :: emit_resolved_crate_origin (
502
+ label. into ( ) ,
503
+ origin,
504
+ & mut self . trap . writer ,
505
+ ) ;
506
+ generated:: Resolvable :: emit_resolved_path ( label. into ( ) , path, & mut self . trap . writer ) ;
507
+ Some ( ( ) )
508
+ } ) ( ) ;
509
+ }
415
510
}
0 commit comments