aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs60
1 files changed, 36 insertions, 24 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 5d3196c2a..727310f06 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -23,7 +23,7 @@ use crate::{
23 db::HirDatabase, 23 db::HirDatabase,
24 expr::{self, BodySourceMap, ExprScopes, ScopeId}, 24 expr::{self, BodySourceMap, ExprScopes, ScopeId},
25 ids::LocationCtx, 25 ids::LocationCtx,
26 resolve::{ScopeDef, TypeNs, ValueNs}, 26 resolve::{HasResolver, ScopeDef, TypeNs, ValueNs},
27 ty::method_resolution::{self, implements_trait}, 27 ty::method_resolution::{self, implements_trait},
28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, 28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody,
29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, 29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
@@ -31,24 +31,24 @@ use crate::{
31 31
32fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 32fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
33 match_ast! { 33 match_ast! {
34 match (node.ast) { 34 match (node.value) {
35 ast::Module(it) => { 35 ast::Module(it) => {
36 let src = node.with_ast(it); 36 let src = node.with_value(it);
37 Some(crate::Module::from_declaration(db, src)?.resolver(db)) 37 Some(crate::Module::from_declaration(db, src)?.resolver(db))
38 }, 38 },
39 ast::SourceFile(it) => { 39 ast::SourceFile(it) => {
40 let src = node.with_ast(crate::ModuleSource::SourceFile(it)); 40 let src = node.with_value(crate::ModuleSource::SourceFile(it));
41 Some(crate::Module::from_definition(db, src)?.resolver(db)) 41 Some(crate::Module::from_definition(db, src)?.resolver(db))
42 }, 42 },
43 ast::StructDef(it) => { 43 ast::StructDef(it) => {
44 let src = node.with_ast(it); 44 let src = node.with_value(it);
45 Some(Struct::from_source(db, src)?.resolver(db)) 45 Some(Struct::from_source(db, src)?.resolver(db))
46 }, 46 },
47 ast::EnumDef(it) => { 47 ast::EnumDef(it) => {
48 let src = node.with_ast(it); 48 let src = node.with_value(it);
49 Some(Enum::from_source(db, src)?.resolver(db)) 49 Some(Enum::from_source(db, src)?.resolver(db))
50 }, 50 },
51 _ => match node.ast.kind() { 51 _ => match node.value.kind() {
52 FN_DEF | CONST_DEF | STATIC_DEF => { 52 FN_DEF | CONST_DEF | STATIC_DEF => {
53 Some(def_with_body_from_child_node(db, node)?.resolver(db)) 53 Some(def_with_body_from_child_node(db, node)?.resolver(db))
54 } 54 }
@@ -67,11 +67,11 @@ fn def_with_body_from_child_node(
67 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; 67 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?;
68 let ctx = LocationCtx::new(db, module.id, child.file_id); 68 let ctx = LocationCtx::new(db, module.id, child.file_id);
69 69
70 child.ast.ancestors().find_map(|node| { 70 child.value.ancestors().find_map(|node| {
71 match_ast! { 71 match_ast! {
72 match node { 72 match node {
73 ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, 73 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
74 ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, 74 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, 75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) },
76 _ => { None }, 76 _ => { None },
77 } 77 }
@@ -157,7 +157,7 @@ impl SourceAnalyzer {
157 let scopes = def.expr_scopes(db); 157 let scopes = def.expr_scopes(db);
158 let scope = match offset { 158 let scope = match offset {
159 None => scope_for(&scopes, &source_map, node), 159 None => scope_for(&scopes, &source_map, node),
160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_ast(offset)), 160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
161 }; 161 };
162 let resolver = expr::resolver_for_scope(db, def, scope); 162 let resolver = expr::resolver_for_scope(db, def, scope);
163 SourceAnalyzer { 163 SourceAnalyzer {
@@ -171,9 +171,9 @@ impl SourceAnalyzer {
171 } else { 171 } else {
172 SourceAnalyzer { 172 SourceAnalyzer {
173 resolver: node 173 resolver: node
174 .ast 174 .value
175 .ancestors() 175 .ancestors()
176 .find_map(|it| try_get_resolver_for_node(db, node.with_ast(&it))) 176 .find_map(|it| try_get_resolver_for_node(db, node.with_value(&it)))
177 .unwrap_or_default(), 177 .unwrap_or_default(),
178 body_owner: None, 178 body_owner: None,
179 body_source_map: None, 179 body_source_map: None,
@@ -185,12 +185,12 @@ impl SourceAnalyzer {
185 } 185 }
186 186
187 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { 187 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> {
188 let src = Source { file_id: self.file_id, ast: expr }; 188 let src = Source { file_id: self.file_id, value: expr };
189 self.body_source_map.as_ref()?.node_expr(src) 189 self.body_source_map.as_ref()?.node_expr(src)
190 } 190 }
191 191
192 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { 192 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
193 let src = Source { file_id: self.file_id, ast: pat }; 193 let src = Source { file_id: self.file_id, value: pat };
194 self.body_source_map.as_ref()?.node_pat(src) 194 self.body_source_map.as_ref()?.node_pat(src)
195 } 195 }
196 196
@@ -302,7 +302,7 @@ impl SourceAnalyzer {
302 let entry = scopes.resolve_name_in_scope(scope, &name)?; 302 let entry = scopes.resolve_name_in_scope(scope, &name)?;
303 Some(ScopeEntryWithSyntax { 303 Some(ScopeEntryWithSyntax {
304 name: entry.name().clone(), 304 name: entry.name().clone(),
305 ptr: source_map.pat_syntax(entry.pat())?.ast, 305 ptr: source_map.pat_syntax(entry.pat())?.value,
306 }) 306 })
307 } 307 }
308 308
@@ -405,9 +405,16 @@ impl SourceAnalyzer {
405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) 405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait)
406 } 406 }
407 407
408 pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option<Expansion> { 408 pub fn expand(
409 let def = self.resolve_macro_call(db, macro_call)?.id; 409 &self,
410 let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); 410 db: &impl HirDatabase,
411 macro_call: Source<&ast::MacroCall>,
412 ) -> Option<Expansion> {
413 let def = self.resolve_macro_call(db, macro_call.value)?.id;
414 let ast_id = AstId::new(
415 macro_call.file_id,
416 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
417 );
411 let macro_call_loc = MacroCallLoc { def, ast_id }; 418 let macro_call_loc = MacroCallLoc { def, ast_id };
412 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 419 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) })
413 } 420 }
@@ -421,6 +428,11 @@ impl SourceAnalyzer {
421 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { 428 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
422 self.infer.clone().unwrap() 429 self.infer.clone().unwrap()
423 } 430 }
431
432 #[cfg(test)]
433 pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> {
434 self.body_owner
435 }
424} 436}
425 437
426fn scope_for( 438fn scope_for(
@@ -428,7 +440,7 @@ fn scope_for(
428 source_map: &BodySourceMap, 440 source_map: &BodySourceMap,
429 node: Source<&SyntaxNode>, 441 node: Source<&SyntaxNode>,
430) -> Option<ScopeId> { 442) -> Option<ScopeId> {
431 node.ast 443 node.value
432 .ancestors() 444 .ancestors()
433 .filter_map(ast::Expr::cast) 445 .filter_map(ast::Expr::cast)
434 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) 446 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it)))
@@ -450,18 +462,18 @@ fn scope_for_offset(
450 return None; 462 return None;
451 } 463 }
452 let syntax_node_ptr = 464 let syntax_node_ptr =
453 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); 465 source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
454 Some((syntax_node_ptr, scope)) 466 Some((syntax_node_ptr, scope))
455 }) 467 })
456 // find containing scope 468 // find containing scope
457 .min_by_key(|(ptr, _scope)| { 469 .min_by_key(|(ptr, _scope)| {
458 ( 470 (
459 !(ptr.range().start() <= offset.ast && offset.ast <= ptr.range().end()), 471 !(ptr.range().start() <= offset.value && offset.value <= ptr.range().end()),
460 ptr.range().len(), 472 ptr.range().len(),
461 ) 473 )
462 }) 474 })
463 .map(|(ptr, scope)| { 475 .map(|(ptr, scope)| {
464 adjust(scopes, source_map, ptr, offset.file_id, offset.ast).unwrap_or(*scope) 476 adjust(scopes, source_map, ptr, offset.file_id, offset.value).unwrap_or(*scope)
465 }) 477 })
466} 478}
467 479
@@ -485,7 +497,7 @@ fn adjust(
485 return None; 497 return None;
486 } 498 }
487 let syntax_node_ptr = 499 let syntax_node_ptr =
488 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); 500 source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
489 Some((syntax_node_ptr, scope)) 501 Some((syntax_node_ptr, scope))
490 }) 502 })
491 .map(|(ptr, scope)| (ptr.range(), scope)) 503 .map(|(ptr, scope)| (ptr.range(), scope))