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.rs115
1 files changed, 87 insertions, 28 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 727310f06..797f90d50 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -10,6 +10,8 @@ use std::sync::Arc;
10use hir_def::{ 10use hir_def::{
11 expr::{ExprId, PatId}, 11 expr::{ExprId, PatId},
12 path::known, 12 path::known,
13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
14 DefWithBodyId,
13}; 15};
14use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; 16use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source};
15use ra_syntax::{ 17use ra_syntax::{
@@ -21,12 +23,12 @@ use ra_syntax::{
21 23
22use crate::{ 24use crate::{
23 db::HirDatabase, 25 db::HirDatabase,
24 expr::{self, BodySourceMap, ExprScopes, ScopeId}, 26 expr::{BodySourceMap, ExprScopes, ScopeId},
25 ids::LocationCtx, 27 ids::LocationCtx,
26 resolve::{HasResolver, ScopeDef, TypeNs, ValueNs},
27 ty::method_resolution::{self, implements_trait}, 28 ty::method_resolution::{self, implements_trait},
28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, 29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, 30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static,
31 Struct, Trait, Ty, TypeAlias,
30}; 32};
31 33
32fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
@@ -34,23 +36,25 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
34 match (node.value) { 36 match (node.value) {
35 ast::Module(it) => { 37 ast::Module(it) => {
36 let src = node.with_value(it); 38 let src = node.with_value(it);
37 Some(crate::Module::from_declaration(db, src)?.resolver(db)) 39 Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
38 }, 40 },
39 ast::SourceFile(it) => { 41 ast::SourceFile(it) => {
40 let src = node.with_value(crate::ModuleSource::SourceFile(it)); 42 let src = node.with_value(crate::ModuleSource::SourceFile(it));
41 Some(crate::Module::from_definition(db, src)?.resolver(db)) 43 Some(crate::Module::from_definition(db, src)?.id.resolver(db))
42 }, 44 },
43 ast::StructDef(it) => { 45 ast::StructDef(it) => {
44 let src = node.with_value(it); 46 let src = node.with_value(it);
45 Some(Struct::from_source(db, src)?.resolver(db)) 47 Some(Struct::from_source(db, src)?.id.resolver(db))
46 }, 48 },
47 ast::EnumDef(it) => { 49 ast::EnumDef(it) => {
48 let src = node.with_value(it); 50 let src = node.with_value(it);
49 Some(Enum::from_source(db, src)?.resolver(db)) 51 Some(Enum::from_source(db, src)?.id.resolver(db))
50 }, 52 },
51 _ => match node.value.kind() { 53 _ => match node.value.kind() {
52 FN_DEF | CONST_DEF | STATIC_DEF => { 54 FN_DEF | CONST_DEF | STATIC_DEF => {
53 Some(def_with_body_from_child_node(db, node)?.resolver(db)) 55 let def = def_with_body_from_child_node(db, node)?;
56 let def = DefWithBodyId::from(def);
57 Some(def.resolver(db))
54 } 58 }
55 // FIXME add missing cases 59 // FIXME add missing cases
56 _ => None 60 _ => None
@@ -127,6 +131,7 @@ pub struct ReferenceDescriptor {
127} 131}
128 132
129pub struct Expansion { 133pub struct Expansion {
134 macro_file_kind: MacroFileKind,
130 macro_call_id: MacroCallId, 135 macro_call_id: MacroCallId,
131} 136}
132 137
@@ -141,7 +146,7 @@ impl Expansion {
141 } 146 }
142 147
143 pub fn file_id(&self) -> HirFileId { 148 pub fn file_id(&self) -> HirFileId {
144 self.macro_call_id.as_file(MacroFileKind::Items) 149 self.macro_call_id.as_file(self.macro_file_kind)
145 } 150 }
146} 151}
147 152
@@ -159,7 +164,7 @@ impl SourceAnalyzer {
159 None => scope_for(&scopes, &source_map, node), 164 None => scope_for(&scopes, &source_map, node),
160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 165 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
161 }; 166 };
162 let resolver = expr::resolver_for_scope(db, def, scope); 167 let resolver = resolver_for_scope(db, def.into(), scope);
163 SourceAnalyzer { 168 SourceAnalyzer {
164 resolver, 169 resolver,
165 body_owner: Some(def), 170 body_owner: Some(def),
@@ -231,7 +236,7 @@ impl SourceAnalyzer {
231 ) -> Option<MacroDef> { 236 ) -> Option<MacroDef> {
232 // This must be a normal source file rather than macro file. 237 // This must be a normal source file rather than macro file.
233 let path = macro_call.path().and_then(Path::from_ast)?; 238 let path = macro_call.path().and_then(Path::from_ast)?;
234 self.resolver.resolve_path_as_macro(db, &path) 239 self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into())
235 } 240 }
236 241
237 pub fn resolve_hir_path( 242 pub fn resolve_hir_path(
@@ -240,16 +245,18 @@ impl SourceAnalyzer {
240 path: &crate::Path, 245 path: &crate::Path,
241 ) -> Option<PathResolution> { 246 ) -> Option<PathResolution> {
242 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 247 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
243 TypeNs::SelfType(it) => PathResolution::SelfType(it), 248 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
244 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 249 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
245 parent: self.resolver.generic_def().unwrap(), 250 parent: self.resolver.generic_def().unwrap().into(),
246 idx, 251 idx,
247 }), 252 }),
248 TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), 253 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
249 TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), 254 PathResolution::Def(Adt::from(it).into())
250 TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), 255 }
256 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
257 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
251 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 258 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
252 TypeNs::Trait(it) => PathResolution::Def(it.into()), 259 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
253 }); 260 });
254 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { 261 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| {
255 let res = match val { 262 let res = match val {
@@ -257,11 +264,11 @@ impl SourceAnalyzer {
257 let var = Local { parent: self.body_owner?, pat_id }; 264 let var = Local { parent: self.body_owner?, pat_id };
258 PathResolution::Local(var) 265 PathResolution::Local(var)
259 } 266 }
260 ValueNs::Function(it) => PathResolution::Def(it.into()), 267 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
261 ValueNs::Const(it) => PathResolution::Def(it.into()), 268 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
262 ValueNs::Static(it) => PathResolution::Def(it.into()), 269 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
263 ValueNs::Struct(it) => PathResolution::Def(it.into()), 270 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
264 ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), 271 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
265 }; 272 };
266 Some(res) 273 Some(res)
267 }); 274 });
@@ -272,7 +279,9 @@ impl SourceAnalyzer {
272 .take_types() 279 .take_types()
273 .map(|it| PathResolution::Def(it.into())); 280 .map(|it| PathResolution::Def(it.into()));
274 types.or(values).or(items).or_else(|| { 281 types.or(values).or(items).or_else(|| {
275 self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) 282 self.resolver
283 .resolve_path_as_macro(db, &path)
284 .map(|def| PathResolution::Macro(def.into()))
276 }) 285 })
277 } 286 }
278 287
@@ -307,7 +316,22 @@ impl SourceAnalyzer {
307 } 316 }
308 317
309 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 318 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
310 self.resolver.process_all_names(db, f) 319 self.resolver.process_all_names(db, &mut |name, def| {
320 let def = match def {
321 resolver::ScopeDef::PerNs(it) => it.into(),
322 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
323 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
324 resolver::ScopeDef::GenericParam(idx) => {
325 let parent = self.resolver.generic_def().unwrap().into();
326 ScopeDef::GenericParam(GenericParam { parent, idx })
327 }
328 resolver::ScopeDef::Local(pat_id) => {
329 let parent = self.resolver.body_owner().unwrap().into();
330 ScopeDef::Local(Local { parent, pat_id })
331 }
332 };
333 f(name, def)
334 })
311 } 335 }
312 336
313 // FIXME: we only use this in `inline_local_variable` assist, ideally, we 337 // FIXME: we only use this in `inline_local_variable` assist, ideally, we
@@ -392,7 +416,7 @@ impl SourceAnalyzer {
392 let std_future_path = known::std_future_future(); 416 let std_future_path = known::std_future_future();
393 417
394 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { 418 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
395 Some(it) => it, 419 Some(it) => it.into(),
396 _ => return false, 420 _ => return false,
397 }; 421 };
398 422
@@ -402,7 +426,7 @@ impl SourceAnalyzer {
402 }; 426 };
403 427
404 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 428 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) 429 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
406 } 430 }
407 431
408 pub fn expand( 432 pub fn expand(
@@ -416,7 +440,10 @@ impl SourceAnalyzer {
416 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 440 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
417 ); 441 );
418 let macro_call_loc = MacroCallLoc { def, ast_id }; 442 let macro_call_loc = MacroCallLoc { def, ast_id };
419 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 443 Some(Expansion {
444 macro_call_id: db.intern_macro(macro_call_loc),
445 macro_file_kind: to_macro_file_kind(macro_call.value),
446 })
420 } 447 }
421 448
422 #[cfg(test)] 449 #[cfg(test)]
@@ -515,3 +542,35 @@ fn adjust(
515 }) 542 })
516 .map(|(_ptr, scope)| *scope) 543 .map(|(_ptr, scope)| *scope)
517} 544}
545
546/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
547/// FIXME: Not completed
548fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
549 let syn = macro_call.syntax();
550 let parent = match syn.parent() {
551 Some(it) => it,
552 None => {
553 // FIXME:
554 // If it is root, which means the parent HirFile
555 // MacroKindFile must be non-items
556 // return expr now.
557 return MacroFileKind::Expr;
558 }
559 };
560
561 match parent.kind() {
562 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
563 LET_STMT => {
564 // FIXME: Handle Pattern
565 MacroFileKind::Expr
566 }
567 EXPR_STMT => MacroFileKind::Statements,
568 BLOCK => MacroFileKind::Statements,
569 ARG_LIST => MacroFileKind::Expr,
570 TRY_EXPR => MacroFileKind::Expr,
571 _ => {
572 // Unknown , Just guess it is `Items`
573 MacroFileKind::Items
574 }
575 }
576}