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.rs79
1 files changed, 61 insertions, 18 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c42ceabdf..cbfeca3ab 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,7 +13,9 @@ use hir_def::{
13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, 13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
14 DefWithBodyId, 14 DefWithBodyId,
15}; 15};
16use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; 16use hir_expand::{
17 name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source,
18};
17use ra_syntax::{ 19use ra_syntax::{
18 ast::{self, AstNode}, 20 ast::{self, AstNode},
19 match_ast, AstPtr, 21 match_ast, AstPtr,
@@ -24,11 +26,12 @@ use ra_syntax::{
24use crate::{ 26use crate::{
25 db::HirDatabase, 27 db::HirDatabase,
26 expr::{BodySourceMap, ExprScopes, ScopeId}, 28 expr::{BodySourceMap, ExprScopes, ScopeId},
27 ids::LocationCtx, 29 ty::{
28 ty::method_resolution::{self, implements_trait}, 30 method_resolution::{self, implements_trait},
31 TraitEnvironment,
32 },
29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, 33 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static, 34 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias,
31 Struct, Trait, Ty, TypeAlias,
32}; 35};
33 36
34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 37fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
@@ -67,16 +70,12 @@ fn def_with_body_from_child_node(
67 db: &impl HirDatabase, 70 db: &impl HirDatabase,
68 child: Source<&SyntaxNode>, 71 child: Source<&SyntaxNode>,
69) -> Option<DefWithBody> { 72) -> Option<DefWithBody> {
70 let module_source = crate::ModuleSource::from_child_node(db, child);
71 let module = Module::from_definition(db, Source::new(child.file_id, module_source))?;
72 let ctx = LocationCtx::new(db, module.id, child.file_id);
73
74 child.value.ancestors().find_map(|node| { 73 child.value.ancestors().find_map(|node| {
75 match_ast! { 74 match_ast! {
76 match node { 75 match node {
77 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 76 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
78 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 77 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
79 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, 78 ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); },
80 _ => { None }, 79 _ => { None },
81 } 80 }
82 } 81 }
@@ -131,6 +130,7 @@ pub struct ReferenceDescriptor {
131} 130}
132 131
133pub struct Expansion { 132pub struct Expansion {
133 macro_file_kind: MacroFileKind,
134 macro_call_id: MacroCallId, 134 macro_call_id: MacroCallId,
135} 135}
136 136
@@ -145,7 +145,7 @@ impl Expansion {
145 } 145 }
146 146
147 pub fn file_id(&self) -> HirFileId { 147 pub fn file_id(&self) -> HirFileId {
148 self.macro_call_id.as_file(MacroFileKind::Items) 148 self.macro_call_id.as_file(self.macro_file_kind)
149 } 149 }
150} 150}
151 151
@@ -157,8 +157,8 @@ impl SourceAnalyzer {
157 ) -> SourceAnalyzer { 157 ) -> SourceAnalyzer {
158 let def_with_body = def_with_body_from_child_node(db, node); 158 let def_with_body = def_with_body_from_child_node(db, node);
159 if let Some(def) = def_with_body { 159 if let Some(def) = def_with_body {
160 let source_map = def.body_source_map(db); 160 let (_body, source_map) = db.body_with_source_map(def.into());
161 let scopes = def.expr_scopes(db); 161 let scopes = db.expr_scopes(def.into());
162 let scope = match offset { 162 let scope = match offset {
163 None => scope_for(&scopes, &source_map, node), 163 None => scope_for(&scopes, &source_map, node),
164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
@@ -168,7 +168,7 @@ impl SourceAnalyzer {
168 resolver, 168 resolver,
169 body_owner: Some(def), 169 body_owner: Some(def),
170 body_source_map: Some(source_map), 170 body_source_map: Some(source_map),
171 infer: Some(def.infer(db)), 171 infer: Some(db.infer(def)),
172 scopes: Some(scopes), 172 scopes: Some(scopes),
173 file_id: node.file_id, 173 file_id: node.file_id,
174 } 174 }
@@ -218,6 +218,11 @@ impl SourceAnalyzer {
218 self.infer.as_ref()?.field_resolution(expr_id) 218 self.infer.as_ref()?.field_resolution(expr_id)
219 } 219 }
220 220
221 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
222 let expr_id = self.expr_id(&field.expr()?)?;
223 self.infer.as_ref()?.record_field_resolution(expr_id)
224 }
225
221 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { 226 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> {
222 let expr_id = self.expr_id(&record_lit.clone().into())?; 227 let expr_id = self.expr_id(&record_lit.clone().into())?;
223 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 228 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@@ -246,7 +251,7 @@ impl SourceAnalyzer {
246 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 251 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
247 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 252 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
248 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 253 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
249 parent: self.resolver.generic_def().unwrap().into(), 254 parent: self.resolver.generic_def().unwrap(),
250 idx, 255 idx,
251 }), 256 }),
252 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { 257 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
@@ -321,7 +326,7 @@ impl SourceAnalyzer {
321 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 326 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
322 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 327 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
323 resolver::ScopeDef::GenericParam(idx) => { 328 resolver::ScopeDef::GenericParam(idx) => {
324 let parent = self.resolver.generic_def().unwrap().into(); 329 let parent = self.resolver.generic_def().unwrap();
325 ScopeDef::GenericParam(GenericParam { parent, idx }) 330 ScopeDef::GenericParam(GenericParam { parent, idx })
326 } 331 }
327 resolver::ScopeDef::Local(pat_id) => { 332 resolver::ScopeDef::Local(pat_id) => {
@@ -406,7 +411,10 @@ impl SourceAnalyzer {
406 // There should be no inference vars in types passed here 411 // There should be no inference vars in types passed here
407 // FIXME check that? 412 // FIXME check that?
408 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; 413 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
409 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 414 let krate = self.resolver.krate();
415 let environment = TraitEnvironment::lower(db, &self.resolver);
416 let ty = crate::ty::InEnvironment { value: canonical, environment };
417 crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value)
410 } 418 }
411 419
412 /// Checks that particular type `ty` implements `std::future::Future`. 420 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -439,7 +447,10 @@ impl SourceAnalyzer {
439 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 447 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
440 ); 448 );
441 let macro_call_loc = MacroCallLoc { def, ast_id }; 449 let macro_call_loc = MacroCallLoc { def, ast_id };
442 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 450 Some(Expansion {
451 macro_call_id: db.intern_macro(macro_call_loc),
452 macro_file_kind: to_macro_file_kind(macro_call.value),
453 })
443 } 454 }
444 455
445 #[cfg(test)] 456 #[cfg(test)]
@@ -538,3 +549,35 @@ fn adjust(
538 }) 549 })
539 .map(|(_ptr, scope)| *scope) 550 .map(|(_ptr, scope)| *scope)
540} 551}
552
553/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
554/// FIXME: Not completed
555fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
556 let syn = macro_call.syntax();
557 let parent = match syn.parent() {
558 Some(it) => it,
559 None => {
560 // FIXME:
561 // If it is root, which means the parent HirFile
562 // MacroKindFile must be non-items
563 // return expr now.
564 return MacroFileKind::Expr;
565 }
566 };
567
568 match parent.kind() {
569 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
570 LET_STMT => {
571 // FIXME: Handle Pattern
572 MacroFileKind::Expr
573 }
574 EXPR_STMT => MacroFileKind::Statements,
575 BLOCK => MacroFileKind::Statements,
576 ARG_LIST => MacroFileKind::Expr,
577 TRY_EXPR => MacroFileKind::Expr,
578 _ => {
579 // Unknown , Just guess it is `Items`
580 MacroFileKind::Items
581 }
582 }
583}