@@ -24,11 +24,11 @@ use hir_expand::{
24
24
attrs:: collect_attrs,
25
25
builtin:: { BuiltinFnLikeExpander , EagerExpander } ,
26
26
db:: ExpandDatabase ,
27
- files:: InRealFile ,
27
+ files:: { HirFileRange , InRealFile } ,
28
28
hygiene:: SyntaxContextExt as _,
29
29
inert_attr_macro:: find_builtin_attr_idx,
30
30
name:: AsName ,
31
- ExpandResult , FileRange , InMacroFile , MacroCallId , MacroFileId , MacroFileIdExt ,
31
+ ExpandResult , FileRange , HirFileIdExt , InMacroFile , MacroCallId , MacroFileId , MacroFileIdExt ,
32
32
} ;
33
33
use intern:: { sym, Symbol } ;
34
34
use itertools:: Itertools ;
@@ -239,10 +239,21 @@ impl<DB: HirDatabase> Semantics<'_, DB> {
239
239
self . imp . file_to_module_defs ( file. into ( ) ) . next ( )
240
240
}
241
241
242
+ pub fn hir_file_to_module_def ( & self , file : impl Into < HirFileId > ) -> Option < Module > {
243
+ self . imp . hir_file_to_module_defs ( file. into ( ) ) . next ( )
244
+ }
245
+
242
246
pub fn file_to_module_defs ( & self , file : impl Into < FileId > ) -> impl Iterator < Item = Module > {
243
247
self . imp . file_to_module_defs ( file. into ( ) )
244
248
}
245
249
250
+ pub fn hir_file_to_module_defs (
251
+ & self ,
252
+ file : impl Into < HirFileId > ,
253
+ ) -> impl Iterator < Item = Module > {
254
+ self . imp . hir_file_to_module_defs ( file. into ( ) )
255
+ }
256
+
246
257
pub fn to_adt_def ( & self , a : & ast:: Adt ) -> Option < Adt > {
247
258
self . imp . to_def ( a)
248
259
}
@@ -327,6 +338,14 @@ impl<'db> SemanticsImpl<'db> {
327
338
tree
328
339
}
329
340
341
+ pub fn adjust_edition ( & self , file_id : HirFileId ) -> HirFileId {
342
+ if let Some ( editioned_file_id) = file_id. file_id ( ) {
343
+ self . attach_first_edition ( editioned_file_id. file_id ( ) ) . map_or ( file_id, Into :: into)
344
+ } else {
345
+ file_id
346
+ }
347
+ }
348
+
330
349
pub fn find_parent_file ( & self , file_id : HirFileId ) -> Option < InFile < SyntaxNode > > {
331
350
match file_id. repr ( ) {
332
351
HirFileIdRepr :: FileId ( file_id) => {
@@ -697,6 +716,28 @@ impl<'db> SemanticsImpl<'db> {
697
716
} )
698
717
}
699
718
719
+ /// Retrieves the formatting part of the format_args! template string at the given offset.
720
+ pub fn check_for_format_args_template_with_file (
721
+ & self ,
722
+ original_token : SyntaxToken ,
723
+ offset : TextSize ,
724
+ ) -> Option < ( HirFileRange , Option < Either < PathResolution , InlineAsmOperand > > ) > {
725
+ let string_start = original_token. text_range ( ) . start ( ) ;
726
+ let original_token = self . wrap_token_infile ( original_token) ;
727
+ self . descend_into_macros_breakable2 ( original_token, |token, _| {
728
+ ( || {
729
+ self . resolve_offset_in_format_args (
730
+ ast:: String :: cast ( token. value ) ?,
731
+ offset. checked_sub ( string_start) ?,
732
+ )
733
+ . map ( |( range, res) | {
734
+ ( HirFileRange { file_id : token. file_id , range : range + string_start } , res)
735
+ } )
736
+ } ) ( )
737
+ . map_or ( ControlFlow :: Continue ( ( ) ) , ControlFlow :: Break )
738
+ } )
739
+ }
740
+
700
741
fn resolve_offset_in_format_args (
701
742
& self ,
702
743
string : ast:: String ,
@@ -891,6 +932,14 @@ impl<'db> SemanticsImpl<'db> {
891
932
self . descend_into_macros_impl ( token. clone ( ) , & mut cb)
892
933
}
893
934
935
+ pub fn descend_into_macros_breakable2 < T > (
936
+ & self ,
937
+ token : InFile < SyntaxToken > ,
938
+ mut cb : impl FnMut ( InFile < SyntaxToken > , SyntaxContextId ) -> ControlFlow < T > ,
939
+ ) -> Option < T > {
940
+ self . descend_into_macros_impl_ ( token. clone ( ) , & mut cb)
941
+ }
942
+
894
943
/// Descends the token into expansions, returning the tokens that matches the input
895
944
/// token's [`SyntaxKind`] and text.
896
945
pub fn descend_into_macros_exact ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
@@ -914,6 +963,32 @@ impl<'db> SemanticsImpl<'db> {
914
963
r
915
964
}
916
965
966
+ /// Descends the token into expansions, returning the tokens that matches the input
967
+ /// token's [`SyntaxKind`] and text.
968
+ pub fn descend_into_macros_exact_with_file (
969
+ & self ,
970
+ token : SyntaxToken ,
971
+ ) -> SmallVec < [ InFile < SyntaxToken > ; 1 ] > {
972
+ let mut r = smallvec ! [ ] ;
973
+ let text = token. text ( ) ;
974
+ let kind = token. kind ( ) ;
975
+
976
+ self . descend_into_macros_cb ( token. clone ( ) , |InFile { value, file_id } , ctx| {
977
+ let mapped_kind = value. kind ( ) ;
978
+ let any_ident_match = || kind. is_any_identifier ( ) && value. kind ( ) . is_any_identifier ( ) ;
979
+ let matches = ( kind == mapped_kind || any_ident_match ( ) )
980
+ && text == value. text ( )
981
+ && !ctx. is_opaque ( self . db . upcast ( ) ) ;
982
+ if matches {
983
+ r. push ( InFile { value, file_id } ) ;
984
+ }
985
+ } ) ;
986
+ if r. is_empty ( ) {
987
+ r. push ( self . wrap_token_infile ( token) ) ;
988
+ }
989
+ r
990
+ }
991
+
917
992
/// Descends the token into expansions, returning the first token that matches the input
918
993
/// token's [`SyntaxKind`] and text.
919
994
pub fn descend_into_macros_single_exact ( & self , token : SyntaxToken ) -> SyntaxToken {
@@ -945,10 +1020,18 @@ impl<'db> SemanticsImpl<'db> {
945
1020
& self ,
946
1021
InRealFile { value : token, file_id } : InRealFile < SyntaxToken > ,
947
1022
f : & mut dyn FnMut ( InFile < SyntaxToken > , SyntaxContextId ) -> ControlFlow < T > ,
1023
+ ) -> Option < T > {
1024
+ self . descend_into_macros_impl_ ( InFile :: new ( file_id. into ( ) , token) , f)
1025
+ }
1026
+
1027
+ fn descend_into_macros_impl_ < T > (
1028
+ & self ,
1029
+ InFile { value : token, file_id } : InFile < SyntaxToken > ,
1030
+ f : & mut dyn FnMut ( InFile < SyntaxToken > , SyntaxContextId ) -> ControlFlow < T > ,
948
1031
) -> Option < T > {
949
1032
let _p = tracing:: info_span!( "descend_into_macros_impl" ) . entered ( ) ;
950
1033
951
- let span = self . db . real_span_map ( file_id) . span_for_range ( token. text_range ( ) ) ;
1034
+ let span = self . db . span_map ( file_id) . span_for_range ( token. text_range ( ) ) ;
952
1035
953
1036
// Process the expansion of a call, pushing all tokens with our span in the expansion back onto our stack
954
1037
let process_expansion_for_token = |stack : & mut Vec < _ > , macro_file| {
@@ -972,17 +1055,16 @@ impl<'db> SemanticsImpl<'db> {
972
1055
// the tokens themselves aren't that interesting as the span that is being used to map
973
1056
// things down never changes.
974
1057
let mut stack: Vec < ( _ , SmallVec < [ _ ; 2 ] > ) > = vec ! [ ] ;
975
- let include = self . s2d_cache . borrow_mut ( ) . get_or_insert_include_for ( self . db , file_id) ;
1058
+ let include = file_id. file_id ( ) . and_then ( |file_id| {
1059
+ self . s2d_cache . borrow_mut ( ) . get_or_insert_include_for ( self . db , file_id)
1060
+ } ) ;
976
1061
match include {
977
1062
Some ( include) => {
978
1063
// include! inputs are always from real files, so they only need to be handled once upfront
979
1064
process_expansion_for_token ( & mut stack, include) ?;
980
1065
}
981
1066
None => {
982
- stack. push ( (
983
- file_id. into ( ) ,
984
- smallvec ! [ ( token, SyntaxContextId :: root( file_id. edition( ) ) ) ] ,
985
- ) ) ;
1067
+ stack. push ( ( file_id, smallvec ! [ ( token, span. ctx) ] ) ) ;
986
1068
}
987
1069
}
988
1070
@@ -1648,6 +1730,16 @@ impl<'db> SemanticsImpl<'db> {
1648
1730
self . with_ctx ( |ctx| ctx. file_to_def ( file) . to_owned ( ) ) . into_iter ( ) . map ( Module :: from)
1649
1731
}
1650
1732
1733
+ fn hir_file_to_module_defs ( & self , file : HirFileId ) -> impl Iterator < Item = Module > {
1734
+ self . with_ctx ( |ctx| {
1735
+ // FIXME: Do this properly
1736
+ ctx. file_to_def ( file. original_file_respecting_includes ( ctx. db . upcast ( ) ) . file_id ( ) )
1737
+ . to_owned ( )
1738
+ } )
1739
+ . into_iter ( )
1740
+ . map ( Module :: from)
1741
+ }
1742
+
1651
1743
pub fn scope ( & self , node : & SyntaxNode ) -> Option < SemanticsScope < ' db > > {
1652
1744
self . analyze_no_infer ( node) . map ( |SourceAnalyzer { file_id, resolver, .. } | SemanticsScope {
1653
1745
db : self . db ,
0 commit comments