@@ -4,11 +4,12 @@ use crate::generated::{self};
44use crate :: trap:: { DiagnosticSeverity , TrapFile , TrapId } ;
55use crate :: trap:: { Label , TrapClass } ;
66use codeql_extractor:: trap:: { self } ;
7+ use itertools:: Either ;
78use log:: Level ;
89use ra_ap_base_db:: salsa:: InternKey ;
910use ra_ap_base_db:: CrateOrigin ;
1011use 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 } ;
1213use ra_ap_hir_def:: type_ref:: Mutability ;
1314use ra_ap_hir_def:: ModuleId ;
1415use ra_ap_hir_expand:: ExpandTo ;
@@ -46,6 +47,12 @@ macro_rules! emit_detached {
4647 $self. extract_canonical_origin( & $node, $label. into( ) ) ;
4748 } ;
4849 // 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+ } ;
4956 ( $( $_: tt) * ) => { } ;
5057}
5158
@@ -276,13 +283,13 @@ impl<'a> Translator<'a> {
276283 } else {
277284 let range = self . text_range_for_node ( mcall) ;
278285 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+ ) ) ;
286293 }
287294 } else {
288295 let range = self . text_range_for_node ( mcall) ;
@@ -380,10 +387,34 @@ impl<'a> Translator<'a> {
380387 Some ( format ! ( "{prefix}::{name}" ) )
381388 }
382389
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+
383408 fn origin_from_hir < T : AstNode > ( & self , item : impl AddressableHir < T > ) -> String {
384409 // if we have a Hir entity, it means we have semantics
385410 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 ) {
387418 CrateOrigin :: Rustc { name } => format ! ( "rustc:{}" , name) ,
388419 CrateOrigin :: Local { repo, name } => format ! (
389420 "repo:{}:{}" ,
@@ -397,6 +428,24 @@ impl<'a> Translator<'a> {
397428 }
398429 }
399430
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+
400449 pub ( crate ) fn extract_canonical_origin < T : AddressableAst + HasName > (
401450 & mut self ,
402451 item : & T ,
@@ -412,4 +461,50 @@ impl<'a> Translator<'a> {
412461 Some ( ( ) )
413462 } ) ( ) ;
414463 }
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+ }
415510}
0 commit comments