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