@@ -2,84 +2,64 @@ use hir::{
22 base_db:: source_db:: SourceDb ,
33 container:: InFile ,
44 file:: HirFileId ,
5- preproc:: {
6- IncludeDirective , IncludeTarget , MacroDefinition , MacroParamDefinition ,
7- MacroParamReferenceDefinitions , MacroReferenceDefinitions , include_directives_at,
8- macro_definition_at, macro_param_definition_at, macro_param_reference_definitions_at,
9- macro_reference_definitions_at,
10- } ,
5+ preproc:: { IncludeDirective , IncludeTarget , MacroDefinition , MacroParamDefinition } ,
116 semantics:: Semantics ,
127} ;
138use itertools:: Itertools ;
149use syntax:: {
15- SyntaxNode , SyntaxTokenWithParent , TokenKind ,
10+ SyntaxTokenWithParent , TokenKind ,
1611 token:: { TokenKindExt , pair_token} ,
1712} ;
18- use utils:: line_index:: { TextRange , TextSize } ;
13+ use utils:: line_index:: { TextRange , TextSize , covering_range } ;
1914use vfs:: FileId ;
2015
2116use crate :: {
2217 FilePosition , RangeInfo ,
2318 db:: root_db:: RootDb ,
2419 definitions:: DefinitionClass ,
2520 navigation_target:: { NavTarget , ToNav } ,
26- source_targets:: { SourceTarget , source_target_at_offset} ,
21+ semantic_target:: {
22+ PreprocMacroTarget , SemanticTarget , TargetIntent , TargetResolution , resolve_semantic_target,
23+ } ,
24+ source_targets:: SourceTarget ,
2725} ;
2826
29- enum DefinitionTarget < ' tree > {
30- Preproc ( Box < PreprocDefinitionTarget > ) ,
31- Include ( Vec < IncludeDirective > ) ,
32- Source ( SourceTarget < ' tree > ) ,
33- }
34-
35- enum PreprocDefinitionTarget {
36- ParamDefinition ( MacroParamDefinition ) ,
37- ParamReference ( MacroParamReferenceDefinitions ) ,
38- Definition ( MacroDefinition ) ,
39- Reference ( MacroReferenceDefinitions ) ,
40- }
41-
4227pub ( crate ) fn goto_definition (
4328 db : & RootDb ,
4429 FilePosition { file_id, offset } : FilePosition ,
4530) -> Option < RangeInfo < Vec < NavTarget > > > {
4631 let sema = Semantics :: new ( db) ;
4732 let parsed_file = sema. parse_file ( file_id) ;
48- let target = dispatch_definition_target ( db, file_id, offset, parsed_file. root ( ) ) ? ;
33+ let target = resolve_semantic_target ( db, file_id, offset, parsed_file. root ( ) , token_precedence ) ;
4934 render_definition_target ( db, file_id, & sema, target)
5035}
5136
52- fn dispatch_definition_target < ' tree > (
53- db : & RootDb ,
54- file_id : FileId ,
55- offset : TextSize ,
56- root : Option < SyntaxNode < ' tree > > ,
57- ) -> Option < DefinitionTarget < ' tree > > {
58- if let Some ( target) = dispatch_preproc_definition_target ( db, file_id, offset) {
59- return Some ( DefinitionTarget :: Preproc ( Box :: new ( target) ) ) ;
60- }
61- if let Some ( includes) = dispatch_include_definition_target ( db, file_id, offset) {
62- return Some ( DefinitionTarget :: Include ( includes) ) ;
63- }
64- let root = root?;
65- let target =
66- source_target_at_offset ( db, file_id, root, offset, token_precedence) ?. resolved ( ) ?;
67- Some ( DefinitionTarget :: Source ( target) )
68- }
69-
7037fn render_definition_target (
7138 db : & RootDb ,
7239 file_id : FileId ,
7340 sema : & Semantics < RootDb > ,
74- target : DefinitionTarget < ' _ > ,
41+ target : TargetResolution < ' _ > ,
7542) -> Option < RangeInfo < Vec < NavTarget > > > {
76- match target {
77- DefinitionTarget :: Preproc ( target) => render_preproc_definition_target ( * target) ,
78- DefinitionTarget :: Include ( includes) => render_include_definition_target ( db, includes) ,
79- DefinitionTarget :: Source ( target) => {
80- render_source_definition_target ( db, file_id, sema, target)
81- }
43+ let mut ranges = Vec :: new ( ) ;
44+ let mut navs = Vec :: new ( ) ;
45+ for target in target. targets_for_intent ( TargetIntent :: Navigate ) {
46+ let target = match target {
47+ SemanticTarget :: PreprocMacro ( target) => render_preproc_definition_target ( target) ,
48+ SemanticTarget :: Include ( includes) => render_include_definition_target ( db, includes) ,
49+ SemanticTarget :: Source ( target) => {
50+ render_source_definition_target ( db, file_id, sema, target)
51+ }
52+ } ?;
53+ ranges. push ( target. range ) ;
54+ navs. extend ( target. info ) ;
55+ }
56+
57+ if navs. is_empty ( ) {
58+ return None ;
8259 }
60+
61+ let range = covering_range ( & ranges) ?;
62+ Some ( RangeInfo :: new ( range, navs. into_iter ( ) . unique ( ) . collect ( ) ) )
8363}
8464
8565fn render_source_definition_target (
@@ -120,47 +100,23 @@ fn nav_targets_for_token(
120100 } )
121101}
122102
123- fn dispatch_preproc_definition_target (
124- db : & RootDb ,
125- file_id : FileId ,
126- offset : TextSize ,
127- ) -> Option < PreprocDefinitionTarget > {
128- if let Ok ( Some ( definition) ) = macro_param_definition_at ( db, file_id, offset) {
129- return Some ( PreprocDefinitionTarget :: ParamDefinition ( definition) ) ;
130- }
131-
132- if let Ok ( Some ( resolution) ) = macro_param_reference_definitions_at ( db, file_id, offset) {
133- return Some ( PreprocDefinitionTarget :: ParamReference ( resolution) ) ;
134- }
135-
136- if let Ok ( Some ( definition) ) = macro_definition_at ( db, file_id, offset) {
137- return Some ( PreprocDefinitionTarget :: Definition ( definition) ) ;
138- }
139-
140- if let Ok ( Some ( resolution) ) = macro_reference_definitions_at ( db, file_id, offset) {
141- return Some ( PreprocDefinitionTarget :: Reference ( resolution) ) ;
142- }
143-
144- None
145- }
146-
147103fn render_preproc_definition_target (
148- target : PreprocDefinitionTarget ,
104+ target : PreprocMacroTarget ,
149105) -> Option < RangeInfo < Vec < NavTarget > > > {
150106 match target {
151- PreprocDefinitionTarget :: ParamDefinition ( definition) => {
107+ PreprocMacroTarget :: ParamDefinition ( definition) => {
152108 Some ( RangeInfo :: new ( definition. range , vec ! [ macro_param_nav_target( definition) ] ) )
153109 }
154- PreprocDefinitionTarget :: ParamReference ( resolution) => {
110+ PreprocMacroTarget :: ParamReference ( resolution) => {
155111 let reference_range = resolution. range ;
156112 let targets =
157113 resolution. definitions . into_iter ( ) . map ( macro_param_nav_target) . collect_vec ( ) ;
158114 ( !targets. is_empty ( ) ) . then_some ( RangeInfo :: new ( reference_range, targets) )
159115 }
160- PreprocDefinitionTarget :: Definition ( definition) => {
116+ PreprocMacroTarget :: Definition ( definition) => {
161117 Some ( RangeInfo :: new ( definition. name_range , vec ! [ macro_nav_target( definition) ] ) )
162118 }
163- PreprocDefinitionTarget :: Reference ( resolution) => {
119+ PreprocMacroTarget :: Reference ( resolution) => {
164120 let reference_range = resolution. range ;
165121 let targets = resolution. definitions . into_iter ( ) . map ( macro_nav_target) . collect_vec ( ) ;
166122 ( !targets. is_empty ( ) ) . then_some ( RangeInfo :: new ( reference_range, targets) )
@@ -192,15 +148,6 @@ fn macro_nav_target(definition: MacroDefinition) -> NavTarget {
192148 }
193149}
194150
195- fn dispatch_include_definition_target (
196- db : & RootDb ,
197- file_id : FileId ,
198- offset : TextSize ,
199- ) -> Option < Vec < IncludeDirective > > {
200- let includes = include_directives_at ( db, file_id, offset) . ok ( ) ?;
201- ( !includes. is_empty ( ) ) . then_some ( includes)
202- }
203-
204151fn render_include_definition_target (
205152 db : & RootDb ,
206153 includes : Vec < IncludeDirective > ,
0 commit comments