@@ -83,6 +83,11 @@ impl PathResolution {
8383/// Primary API to get semantic information, like types, from syntax trees.
8484pub struct Semantics < ' db , DB > {
8585 pub db : & ' db DB ,
86+ impl_ : SemanticsImpl < ' db > ,
87+ }
88+
89+ pub struct SemanticsImpl < ' db > {
90+ pub db : & ' db dyn HirDatabase ,
8691 s2d_cache : RefCell < SourceToDefCache > ,
8792 cache : RefCell < FxHashMap < SyntaxNode , HirFileId > > ,
8893}
@@ -95,7 +100,166 @@ impl<DB> fmt::Debug for Semantics<'_, DB> {
95100
96101impl < ' db , DB : HirDatabase > Semantics < ' db , DB > {
97102 pub fn new ( db : & DB ) -> Semantics < DB > {
98- Semantics { db, s2d_cache : Default :: default ( ) , cache : Default :: default ( ) }
103+ let impl_ = SemanticsImpl :: new ( db) ;
104+ Semantics { db, impl_ }
105+ }
106+
107+ pub fn parse ( & self , file_id : FileId ) -> ast:: SourceFile {
108+ self . impl_ . parse ( file_id)
109+ }
110+
111+ pub fn ast < T : AstDiagnostic + Diagnostic > ( & self , d : & T ) -> <T as AstDiagnostic >:: AST {
112+ self . impl_ . ast ( d)
113+ }
114+
115+ pub fn expand ( & self , macro_call : & ast:: MacroCall ) -> Option < SyntaxNode > {
116+ self . impl_ . expand ( macro_call)
117+ }
118+
119+ pub fn expand_hypothetical (
120+ & self ,
121+ actual_macro_call : & ast:: MacroCall ,
122+ hypothetical_args : & ast:: TokenTree ,
123+ token_to_map : SyntaxToken ,
124+ ) -> Option < ( SyntaxNode , SyntaxToken ) > {
125+ self . impl_ . expand_hypothetical ( actual_macro_call, hypothetical_args, token_to_map)
126+ }
127+
128+ pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SyntaxToken {
129+ self . impl_ . descend_into_macros ( token)
130+ }
131+
132+ pub fn descend_node_at_offset < N : ast:: AstNode > (
133+ & self ,
134+ node : & SyntaxNode ,
135+ offset : TextSize ,
136+ ) -> Option < N > {
137+ self . impl_ . descend_node_at_offset ( node, offset)
138+ }
139+
140+ pub fn original_range ( & self , node : & SyntaxNode ) -> FileRange {
141+ self . impl_ . original_range ( node)
142+ }
143+
144+ pub fn diagnostics_range ( & self , diagnostics : & dyn Diagnostic ) -> FileRange {
145+ self . impl_ . diagnostics_range ( diagnostics)
146+ }
147+
148+ pub fn ancestors_with_macros ( & self , node : SyntaxNode ) -> impl Iterator < Item = SyntaxNode > + ' _ {
149+ self . impl_ . ancestors_with_macros ( node)
150+ }
151+
152+ pub fn ancestors_at_offset_with_macros (
153+ & self ,
154+ node : & SyntaxNode ,
155+ offset : TextSize ,
156+ ) -> impl Iterator < Item = SyntaxNode > + ' _ {
157+ self . impl_ . ancestors_at_offset_with_macros ( node, offset)
158+ }
159+
160+ /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
161+ /// search up until it is of the target AstNode type
162+ pub fn find_node_at_offset_with_macros < N : AstNode > (
163+ & self ,
164+ node : & SyntaxNode ,
165+ offset : TextSize ,
166+ ) -> Option < N > {
167+ self . impl_ . find_node_at_offset_with_macros ( node, offset)
168+ }
169+
170+ /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*,
171+ /// descend it and find again
172+ pub fn find_node_at_offset_with_descend < N : AstNode > (
173+ & self ,
174+ node : & SyntaxNode ,
175+ offset : TextSize ,
176+ ) -> Option < N > {
177+ self . impl_ . find_node_at_offset_with_descend ( node, offset)
178+ }
179+
180+ pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
181+ self . impl_ . type_of_expr ( expr)
182+ }
183+
184+ pub fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < Type > {
185+ self . impl_ . type_of_pat ( pat)
186+ }
187+
188+ pub fn resolve_method_call ( & self , call : & ast:: MethodCallExpr ) -> Option < Function > {
189+ self . impl_ . resolve_method_call ( call)
190+ }
191+
192+ pub fn resolve_field ( & self , field : & ast:: FieldExpr ) -> Option < Field > {
193+ self . impl_ . resolve_field ( field)
194+ }
195+
196+ pub fn resolve_record_field ( & self , field : & ast:: RecordField ) -> Option < ( Field , Option < Local > ) > {
197+ self . impl_ . resolve_record_field ( field)
198+ }
199+
200+ pub fn resolve_record_field_pat ( & self , field : & ast:: RecordFieldPat ) -> Option < Field > {
201+ self . impl_ . resolve_record_field_pat ( field)
202+ }
203+
204+ pub fn resolve_macro_call ( & self , macro_call : & ast:: MacroCall ) -> Option < MacroDef > {
205+ self . impl_ . resolve_macro_call ( macro_call)
206+ }
207+
208+ pub fn resolve_path ( & self , path : & ast:: Path ) -> Option < PathResolution > {
209+ self . impl_ . resolve_path ( path)
210+ }
211+
212+ pub fn resolve_variant ( & self , record_lit : ast:: RecordLit ) -> Option < VariantId > {
213+ self . impl_ . resolve_variant ( record_lit)
214+ }
215+
216+ pub fn lower_path ( & self , path : & ast:: Path ) -> Option < Path > {
217+ self . impl_ . lower_path ( path)
218+ }
219+
220+ pub fn resolve_bind_pat_to_const ( & self , pat : & ast:: BindPat ) -> Option < ModuleDef > {
221+ self . impl_ . resolve_bind_pat_to_const ( pat)
222+ }
223+
224+ // FIXME: use this instead?
225+ // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
226+
227+ pub fn record_literal_missing_fields ( & self , literal : & ast:: RecordLit ) -> Vec < ( Field , Type ) > {
228+ self . impl_ . record_literal_missing_fields ( literal)
229+ }
230+
231+ pub fn record_pattern_missing_fields ( & self , pattern : & ast:: RecordPat ) -> Vec < ( Field , Type ) > {
232+ self . impl_ . record_pattern_missing_fields ( pattern)
233+ }
234+
235+ pub fn to_def < T : ToDef > ( & self , src : & T ) -> Option < T :: Def > {
236+ self . impl_ . to_def ( src)
237+ }
238+
239+ pub fn to_module_def ( & self , file : FileId ) -> Option < Module > {
240+ self . impl_ . to_module_def ( file)
241+ }
242+
243+ pub fn scope ( & self , node : & SyntaxNode ) -> SemanticsScope < ' db > {
244+ self . impl_ . scope ( node)
245+ }
246+
247+ pub fn scope_at_offset ( & self , node : & SyntaxNode , offset : TextSize ) -> SemanticsScope < ' db > {
248+ self . impl_ . scope_at_offset ( node, offset)
249+ }
250+
251+ pub fn scope_for_def ( & self , def : Trait ) -> SemanticsScope < ' db > {
252+ self . impl_ . scope_for_def ( def)
253+ }
254+
255+ pub fn assert_contains_node ( & self , node : & SyntaxNode ) {
256+ self . impl_ . assert_contains_node ( node)
257+ }
258+ }
259+
260+ impl < ' db > SemanticsImpl < ' db > {
261+ pub fn new ( db : & ' db dyn HirDatabase ) -> Self {
262+ Self { db, s2d_cache : Default :: default ( ) , cache : Default :: default ( ) }
99263 }
100264
101265 pub fn parse ( & self , file_id : FileId ) -> ast:: SourceFile {
@@ -108,7 +272,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
108272 let file_id = d. source ( ) . file_id ;
109273 let root = self . db . parse_or_expand ( file_id) . unwrap ( ) ;
110274 self . cache ( root, file_id) ;
111- d. ast ( self . db )
275+ d. ast ( self . db . upcast ( ) )
112276 }
113277
114278 pub fn expand ( & self , macro_call : & ast:: MacroCall ) -> Option < SyntaxNode > {
@@ -130,9 +294,15 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
130294 self . find_file ( actual_macro_call. syntax ( ) . clone ( ) ) . with_value ( actual_macro_call) ;
131295 let sa = self . analyze2 ( macro_call. map ( |it| it. syntax ( ) ) , None ) ;
132296 let krate = sa. resolver . krate ( ) ?;
133- let macro_call_id = macro_call
134- . as_call_id ( self . db , krate, |path| sa. resolver . resolve_path_as_macro ( self . db , & path) ) ?;
135- hir_expand:: db:: expand_hypothetical ( self . db , macro_call_id, hypothetical_args, token_to_map)
297+ let macro_call_id = macro_call. as_call_id ( self . db . upcast ( ) , krate, |path| {
298+ sa. resolver . resolve_path_as_macro ( self . db . upcast ( ) , & path)
299+ } ) ?;
300+ hir_expand:: db:: expand_hypothetical (
301+ self . db . upcast ( ) ,
302+ macro_call_id,
303+ hypothetical_args,
304+ token_to_map,
305+ )
136306 }
137307
138308 pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SyntaxToken {
@@ -147,7 +317,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
147317 return None ;
148318 }
149319 let file_id = sa. expand ( self . db , token. with_value ( & macro_call) ) ?;
150- let token = file_id. expansion_info ( self . db ) ?. map_token_down ( token. as_ref ( ) ) ?;
320+ let token = file_id. expansion_info ( self . db . upcast ( ) ) ?. map_token_down ( token. as_ref ( ) ) ?;
151321
152322 self . cache ( find_root ( & token. value . parent ( ) ) , token. file_id ) ;
153323
@@ -184,7 +354,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
184354
185355 pub fn ancestors_with_macros ( & self , node : SyntaxNode ) -> impl Iterator < Item = SyntaxNode > + ' _ {
186356 let node = self . find_file ( node) ;
187- node. ancestors_with_macros ( self . db ) . map ( |it| it. value )
357+ node. ancestors_with_macros ( self . db . upcast ( ) ) . map ( |it| it. value )
188358 }
189359
190360 pub fn ancestors_at_offset_with_macros (
@@ -197,8 +367,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
197367 . kmerge_by ( |node1, node2| node1. text_range ( ) . len ( ) < node2. text_range ( ) . len ( ) )
198368 }
199369
200- /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
201- /// search up until it is of the target AstNode type
202370 pub fn find_node_at_offset_with_macros < N : AstNode > (
203371 & self ,
204372 node : & SyntaxNode ,
@@ -207,8 +375,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
207375 self . ancestors_at_offset_with_macros ( node, offset) . find_map ( N :: cast)
208376 }
209377
210- /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*,
211- /// descend it and find again
212378 pub fn find_node_at_offset_with_descend < N : AstNode > (
213379 & self ,
214380 node : & SyntaxNode ,
@@ -267,9 +433,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
267433 self . analyze ( pat. syntax ( ) ) . resolve_bind_pat_to_const ( self . db , pat)
268434 }
269435
270- // FIXME: use this instead?
271- // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
272-
273436 pub fn record_literal_missing_fields ( & self , literal : & ast:: RecordLit ) -> Vec < ( Field , Type ) > {
274437 self . analyze ( literal. syntax ( ) )
275438 . record_literal_missing_fields ( self . db , literal)
@@ -310,7 +473,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
310473 }
311474
312475 pub fn scope_for_def ( & self , def : Trait ) -> SemanticsScope < ' db > {
313- let resolver = def. id . resolver ( self . db ) ;
476+ let resolver = def. id . resolver ( self . db . upcast ( ) ) ;
314477 SemanticsScope { db : self . db , resolver }
315478 }
316479
@@ -331,12 +494,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
331494 ChildContainer :: DefWithBodyId ( def) => {
332495 return SourceAnalyzer :: new_for_body ( self . db , def, src, offset)
333496 }
334- ChildContainer :: TraitId ( it) => it. resolver ( self . db ) ,
335- ChildContainer :: ImplId ( it) => it. resolver ( self . db ) ,
336- ChildContainer :: ModuleId ( it) => it. resolver ( self . db ) ,
337- ChildContainer :: EnumId ( it) => it. resolver ( self . db ) ,
338- ChildContainer :: VariantId ( it) => it. resolver ( self . db ) ,
339- ChildContainer :: GenericDefId ( it) => it. resolver ( self . db ) ,
497+ ChildContainer :: TraitId ( it) => it. resolver ( self . db . upcast ( ) ) ,
498+ ChildContainer :: ImplId ( it) => it. resolver ( self . db . upcast ( ) ) ,
499+ ChildContainer :: ModuleId ( it) => it. resolver ( self . db . upcast ( ) ) ,
500+ ChildContainer :: EnumId ( it) => it. resolver ( self . db . upcast ( ) ) ,
501+ ChildContainer :: VariantId ( it) => it. resolver ( self . db . upcast ( ) ) ,
502+ ChildContainer :: GenericDefId ( it) => it. resolver ( self . db . upcast ( ) ) ,
340503 } ;
341504 SourceAnalyzer :: new_for_resolver ( resolver, src)
342505 }
@@ -382,14 +545,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
382545pub trait ToDef : AstNode + Clone {
383546 type Def ;
384547
385- fn to_def < DB : HirDatabase > ( sema : & Semantics < DB > , src : InFile < Self > ) -> Option < Self :: Def > ;
548+ fn to_def ( sema : & SemanticsImpl , src : InFile < Self > ) -> Option < Self :: Def > ;
386549}
387550
388551macro_rules! to_def_impls {
389552 ( $( ( $def: path, $ast: path, $meth: ident) ) ,* , ) => { $(
390553 impl ToDef for $ast {
391554 type Def = $def;
392- fn to_def< DB : HirDatabase > ( sema: & Semantics < DB > , src: InFile <Self >) -> Option <Self :: Def > {
555+ fn to_def( sema: & SemanticsImpl , src: InFile <Self >) -> Option <Self :: Def > {
393556 sema. with_ctx( |ctx| ctx. $meth( src) ) . map( <$def>:: from)
394557 }
395558 }
0 commit comments