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.rs213
1 files changed, 90 insertions, 123 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 76c493f1a..85b378483 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -7,19 +7,26 @@
7//! purely for "IDE needs". 7//! purely for "IDE needs".
8use std::sync::Arc; 8use std::sync::Arc;
9 9
10use either::Either;
10use hir_def::{ 11use hir_def::{
11 body::{ 12 body::{
12 scope::{ExprScopes, ScopeId}, 13 scope::{ExprScopes, ScopeId},
13 BodySourceMap, 14 BodySourceMap,
14 }, 15 },
15 expr::{ExprId, PatId}, 16 expr::{ExprId, PatId},
16 path::known, 17 nameres::ModuleSource,
18 path::path,
17 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, 19 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
18 AssocItemId, DefWithBodyId, 20 AssocItemId, DefWithBodyId,
19}; 21};
20use hir_expand::{ 22use hir_expand::{
21 hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, 23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
22}; 24};
25use hir_ty::{
26 method_resolution::{self, implements_trait},
27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
28};
29use ra_prof::profile;
23use ra_syntax::{ 30use ra_syntax::{
24 ast::{self, AstNode}, 31 ast::{self, AstNode},
25 match_ast, AstPtr, 32 match_ast, AstPtr,
@@ -28,16 +35,12 @@ use ra_syntax::{
28}; 35};
29 36
30use crate::{ 37use crate::{
31 db::HirDatabase, 38 db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function,
32 ty::{ 39 ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias,
33 method_resolution::{self, implements_trait}, 40 TypeParam,
34 InEnvironment, TraitEnvironment, Ty,
35 },
36 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
37 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias,
38}; 41};
39 42
40fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 43fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
41 match_ast! { 44 match_ast! {
42 match (node.value) { 45 match (node.value) {
43 ast::Module(it) => { 46 ast::Module(it) => {
@@ -45,7 +48,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
45 Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) 48 Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
46 }, 49 },
47 ast::SourceFile(it) => { 50 ast::SourceFile(it) => {
48 let src = node.with_value(crate::ModuleSource::SourceFile(it)); 51 let src = node.with_value(ModuleSource::SourceFile(it));
49 Some(crate::Module::from_definition(db, src)?.id.resolver(db)) 52 Some(crate::Module::from_definition(db, src)?.id.resolver(db))
50 }, 53 },
51 ast::StructDef(it) => { 54 ast::StructDef(it) => {
@@ -56,6 +59,14 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
56 let src = node.with_value(it); 59 let src = node.with_value(it);
57 Some(Enum::from_source(db, src)?.id.resolver(db)) 60 Some(Enum::from_source(db, src)?.id.resolver(db))
58 }, 61 },
62 ast::ImplBlock(it) => {
63 let src = node.with_value(it);
64 Some(ImplBlock::from_source(db, src)?.id.resolver(db))
65 },
66 ast::TraitDef(it) => {
67 let src = node.with_value(it);
68 Some(Trait::from_source(db, src)?.id.resolver(db))
69 },
59 _ => match node.value.kind() { 70 _ => match node.value.kind() {
60 FN_DEF | CONST_DEF | STATIC_DEF => { 71 FN_DEF | CONST_DEF | STATIC_DEF => {
61 let def = def_with_body_from_child_node(db, node)?; 72 let def = def_with_body_from_child_node(db, node)?;
@@ -71,14 +82,16 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
71 82
72fn def_with_body_from_child_node( 83fn def_with_body_from_child_node(
73 db: &impl HirDatabase, 84 db: &impl HirDatabase,
74 child: Source<&SyntaxNode>, 85 child: InFile<&SyntaxNode>,
75) -> Option<DefWithBody> { 86) -> Option<DefWithBody> {
76 child.value.ancestors().find_map(|node| { 87 let _p = profile("def_with_body_from_child_node");
88 child.cloned().ancestors_with_macros(db).find_map(|node| {
89 let n = &node.value;
77 match_ast! { 90 match_ast! {
78 match node { 91 match n {
79 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 92 ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
80 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 93 ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
81 ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 94 ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
82 _ => { None }, 95 _ => { None },
83 } 96 }
84 } 97 }
@@ -93,7 +106,7 @@ pub struct SourceAnalyzer {
93 resolver: Resolver, 106 resolver: Resolver,
94 body_owner: Option<DefWithBody>, 107 body_owner: Option<DefWithBody>,
95 body_source_map: Option<Arc<BodySourceMap>>, 108 body_source_map: Option<Arc<BodySourceMap>>,
96 infer: Option<Arc<crate::ty::InferenceResult>>, 109 infer: Option<Arc<InferenceResult>>,
97 scopes: Option<Arc<ExprScopes>>, 110 scopes: Option<Arc<ExprScopes>>,
98} 111}
99 112
@@ -104,7 +117,7 @@ pub enum PathResolution {
104 /// A local binding (only value namespace) 117 /// A local binding (only value namespace)
105 Local(Local), 118 Local(Local),
106 /// A generic parameter 119 /// A generic parameter
107 GenericParam(GenericParam), 120 TypeParam(TypeParam),
108 SelfType(crate::ImplBlock), 121 SelfType(crate::ImplBlock),
109 Macro(MacroDef), 122 Macro(MacroDef),
110 AssocItem(crate::AssocItem), 123 AssocItem(crate::AssocItem),
@@ -132,8 +145,8 @@ pub struct ReferenceDescriptor {
132 pub name: String, 145 pub name: String,
133} 146}
134 147
148#[derive(Debug)]
135pub struct Expansion { 149pub struct Expansion {
136 macro_file_kind: MacroFileKind,
137 macro_call_id: MacroCallId, 150 macro_call_id: MacroCallId,
138} 151}
139 152
@@ -141,23 +154,24 @@ impl Expansion {
141 pub fn map_token_down( 154 pub fn map_token_down(
142 &self, 155 &self,
143 db: &impl HirDatabase, 156 db: &impl HirDatabase,
144 token: Source<&SyntaxToken>, 157 token: InFile<&SyntaxToken>,
145 ) -> Option<Source<SyntaxToken>> { 158 ) -> Option<InFile<SyntaxToken>> {
146 let exp_info = self.file_id().expansion_info(db)?; 159 let exp_info = self.file_id().expansion_info(db)?;
147 exp_info.map_token_down(token) 160 exp_info.map_token_down(token)
148 } 161 }
149 162
150 pub fn file_id(&self) -> HirFileId { 163 pub fn file_id(&self) -> HirFileId {
151 self.macro_call_id.as_file(self.macro_file_kind) 164 self.macro_call_id.as_file()
152 } 165 }
153} 166}
154 167
155impl SourceAnalyzer { 168impl SourceAnalyzer {
156 pub fn new( 169 pub fn new(
157 db: &impl HirDatabase, 170 db: &impl HirDatabase,
158 node: Source<&SyntaxNode>, 171 node: InFile<&SyntaxNode>,
159 offset: Option<TextUnit>, 172 offset: Option<TextUnit>,
160 ) -> SourceAnalyzer { 173 ) -> SourceAnalyzer {
174 let _p = profile("SourceAnalyzer::new");
161 let def_with_body = def_with_body_from_child_node(db, node); 175 let def_with_body = def_with_body_from_child_node(db, node);
162 if let Some(def) = def_with_body { 176 if let Some(def) = def_with_body {
163 let (_body, source_map) = db.body_with_source_map(def.into()); 177 let (_body, source_map) = db.body_with_source_map(def.into());
@@ -192,12 +206,12 @@ impl SourceAnalyzer {
192 } 206 }
193 207
194 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { 208 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> {
195 let src = Source { file_id: self.file_id, value: expr }; 209 let src = InFile { file_id: self.file_id, value: expr };
196 self.body_source_map.as_ref()?.node_expr(src) 210 self.body_source_map.as_ref()?.node_expr(src)
197 } 211 }
198 212
199 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { 213 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
200 let src = Source { file_id: self.file_id, value: pat }; 214 let src = InFile { file_id: self.file_id, value: pat };
201 self.body_source_map.as_ref()?.node_pat(src) 215 self.body_source_map.as_ref()?.node_pat(src)
202 } 216 }
203 217
@@ -226,7 +240,13 @@ impl SourceAnalyzer {
226 } 240 }
227 241
228 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { 242 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
229 let expr_id = self.expr_id(&field.expr()?)?; 243 let expr_id = match field.expr() {
244 Some(it) => self.expr_id(&it)?,
245 None => {
246 let src = InFile { file_id: self.file_id, value: field };
247 self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?
248 }
249 };
230 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) 250 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into())
231 } 251 }
232 252
@@ -243,11 +263,11 @@ impl SourceAnalyzer {
243 pub fn resolve_macro_call( 263 pub fn resolve_macro_call(
244 &self, 264 &self,
245 db: &impl HirDatabase, 265 db: &impl HirDatabase,
246 macro_call: Source<&ast::MacroCall>, 266 macro_call: InFile<&ast::MacroCall>,
247 ) -> Option<MacroDef> { 267 ) -> Option<MacroDef> {
248 let hygiene = Hygiene::new(db, macro_call.file_id); 268 let hygiene = Hygiene::new(db, macro_call.file_id);
249 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; 269 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?;
250 self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) 270 self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into())
251 } 271 }
252 272
253 pub fn resolve_hir_path( 273 pub fn resolve_hir_path(
@@ -255,43 +275,42 @@ impl SourceAnalyzer {
255 db: &impl HirDatabase, 275 db: &impl HirDatabase,
256 path: &crate::Path, 276 path: &crate::Path,
257 ) -> Option<PathResolution> { 277 ) -> Option<PathResolution> {
258 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 278 let types =
259 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 279 self.resolver.resolve_path_in_type_ns_fully(db, path.mod_path()).map(|ty| match ty {
260 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 280 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
261 parent: self.resolver.generic_def().unwrap(), 281 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
262 idx, 282 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
263 }), 283 PathResolution::Def(Adt::from(it).into())
264 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
265 PathResolution::Def(Adt::from(it).into())
266 }
267 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
268 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
269 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
270 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
271 });
272 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| {
273 let res = match val {
274 ValueNs::LocalBinding(pat_id) => {
275 let var = Local { parent: self.body_owner?, pat_id };
276 PathResolution::Local(var)
277 } 284 }
278 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), 285 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
279 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), 286 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
280 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), 287 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
281 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), 288 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
282 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), 289 });
283 }; 290 let values =
284 Some(res) 291 self.resolver.resolve_path_in_value_ns_fully(db, path.mod_path()).and_then(|val| {
285 }); 292 let res = match val {
293 ValueNs::LocalBinding(pat_id) => {
294 let var = Local { parent: self.body_owner?, pat_id };
295 PathResolution::Local(var)
296 }
297 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
298 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
299 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
300 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
301 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
302 };
303 Some(res)
304 });
286 305
287 let items = self 306 let items = self
288 .resolver 307 .resolver
289 .resolve_module_path(db, &path) 308 .resolve_module_path_in_items(db, path.mod_path())
290 .take_types() 309 .take_types()
291 .map(|it| PathResolution::Def(it.into())); 310 .map(|it| PathResolution::Def(it.into()));
292 types.or(values).or(items).or_else(|| { 311 types.or(values).or(items).or_else(|| {
293 self.resolver 312 self.resolver
294 .resolve_path_as_macro(db, &path) 313 .resolve_path_as_macro(db, path.mod_path())
295 .map(|def| PathResolution::Macro(def.into())) 314 .map(|def| PathResolution::Macro(def.into()))
296 }) 315 })
297 } 316 }
@@ -318,7 +337,7 @@ impl SourceAnalyzer {
318 let name = name_ref.as_name(); 337 let name = name_ref.as_name();
319 let source_map = self.body_source_map.as_ref()?; 338 let source_map = self.body_source_map.as_ref()?;
320 let scopes = self.scopes.as_ref()?; 339 let scopes = self.scopes.as_ref()?;
321 let scope = scope_for(scopes, source_map, Source::new(self.file_id, name_ref.syntax()))?; 340 let scope = scope_for(scopes, source_map, InFile::new(self.file_id, name_ref.syntax()))?;
322 let entry = scopes.resolve_name_in_scope(scope, &name)?; 341 let entry = scopes.resolve_name_in_scope(scope, &name)?;
323 Some(ScopeEntryWithSyntax { 342 Some(ScopeEntryWithSyntax {
324 name: entry.name().clone(), 343 name: entry.name().clone(),
@@ -332,10 +351,7 @@ impl SourceAnalyzer {
332 resolver::ScopeDef::PerNs(it) => it.into(), 351 resolver::ScopeDef::PerNs(it) => it.into(),
333 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 352 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
334 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 353 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
335 resolver::ScopeDef::GenericParam(idx) => { 354 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),
336 let parent = self.resolver.generic_def().unwrap();
337 ScopeDef::GenericParam(GenericParam { parent, idx })
338 }
339 resolver::ScopeDef::Local(pat_id) => { 355 resolver::ScopeDef::Local(pat_id) => {
340 let parent = self.resolver.body_owner().unwrap().into(); 356 let parent = self.resolver.body_owner().unwrap().into();
341 ScopeDef::Local(Local { parent, pat_id }) 357 ScopeDef::Local(Local { parent, pat_id })
@@ -349,7 +365,7 @@ impl SourceAnalyzer {
349 // should switch to general reference search infra there. 365 // should switch to general reference search infra there.
350 pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { 366 pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> {
351 let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); 367 let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap();
352 let ptr = Either::A(AstPtr::new(&ast::Pat::from(pat.clone()))); 368 let ptr = Either::Left(AstPtr::new(&ast::Pat::from(pat.clone())));
353 fn_def 369 fn_def
354 .syntax() 370 .syntax()
355 .descendants() 371 .descendants()
@@ -375,7 +391,7 @@ impl SourceAnalyzer {
375 // There should be no inference vars in types passed here 391 // There should be no inference vars in types passed here
376 // FIXME check that? 392 // FIXME check that?
377 // FIXME replace Unknown by bound vars here 393 // FIXME replace Unknown by bound vars here
378 let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; 394 let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
379 method_resolution::iterate_method_candidates( 395 method_resolution::iterate_method_candidates(
380 &canonical, 396 &canonical,
381 db, 397 db,
@@ -399,7 +415,7 @@ impl SourceAnalyzer {
399 // There should be no inference vars in types passed here 415 // There should be no inference vars in types passed here
400 // FIXME check that? 416 // FIXME check that?
401 // FIXME replace Unknown by bound vars here 417 // FIXME replace Unknown by bound vars here
402 let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; 418 let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
403 method_resolution::iterate_method_candidates( 419 method_resolution::iterate_method_candidates(
404 &canonical, 420 &canonical,
405 db, 421 db,
@@ -410,24 +426,10 @@ impl SourceAnalyzer {
410 ) 426 )
411 } 427 }
412 428
413 // pub fn autoderef<'a>(
414 // &'a self,
415 // db: &'a impl HirDatabase,
416 // ty: Ty,
417 // ) -> impl Iterator<Item = Ty> + 'a {
418 // // There should be no inference vars in types passed here
419 // // FIXME check that?
420 // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
421 // let krate = self.resolver.krate();
422 // let environment = TraitEnvironment::lower(db, &self.resolver);
423 // let ty = crate::ty::InEnvironment { value: canonical, environment };
424 // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value)
425 // }
426
427 /// Checks that particular type `ty` implements `std::future::Future`. 429 /// Checks that particular type `ty` implements `std::future::Future`.
428 /// This function is used in `.await` syntax completion. 430 /// This function is used in `.await` syntax completion.
429 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { 431 pub fn impls_future(&self, db: &impl HirDatabase, ty: Type) -> bool {
430 let std_future_path = known::std_future_future(); 432 let std_future_path = path![std::future::Future];
431 433
432 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { 434 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
433 Some(it) => it.into(), 435 Some(it) => it.into(),
@@ -439,43 +441,40 @@ impl SourceAnalyzer {
439 _ => return false, 441 _ => return false,
440 }; 442 };
441 443
442 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 444 let canonical_ty = Canonical { value: ty.ty.value, num_vars: 0 };
443 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) 445 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
444 } 446 }
445 447
446 pub fn expand( 448 pub fn expand(
447 &self, 449 &self,
448 db: &impl HirDatabase, 450 db: &impl HirDatabase,
449 macro_call: Source<&ast::MacroCall>, 451 macro_call: InFile<&ast::MacroCall>,
450 ) -> Option<Expansion> { 452 ) -> Option<Expansion> {
451 let def = self.resolve_macro_call(db, macro_call)?.id; 453 let def = self.resolve_macro_call(db, macro_call)?.id;
452 let ast_id = AstId::new( 454 let ast_id = AstId::new(
453 macro_call.file_id, 455 macro_call.file_id,
454 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 456 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
455 ); 457 );
456 Some(Expansion { 458 Some(Expansion { macro_call_id: def.as_call_id(db, MacroCallKind::FnLike(ast_id)) })
457 macro_call_id: def.as_call_id(db, ast_id),
458 macro_file_kind: to_macro_file_kind(macro_call.value),
459 })
460 } 459 }
461} 460}
462 461
463fn scope_for( 462fn scope_for(
464 scopes: &ExprScopes, 463 scopes: &ExprScopes,
465 source_map: &BodySourceMap, 464 source_map: &BodySourceMap,
466 node: Source<&SyntaxNode>, 465 node: InFile<&SyntaxNode>,
467) -> Option<ScopeId> { 466) -> Option<ScopeId> {
468 node.value 467 node.value
469 .ancestors() 468 .ancestors()
470 .filter_map(ast::Expr::cast) 469 .filter_map(ast::Expr::cast)
471 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) 470 .filter_map(|it| source_map.node_expr(InFile::new(node.file_id, &it)))
472 .find_map(|it| scopes.scope_for(it)) 471 .find_map(|it| scopes.scope_for(it))
473} 472}
474 473
475fn scope_for_offset( 474fn scope_for_offset(
476 scopes: &ExprScopes, 475 scopes: &ExprScopes,
477 source_map: &BodySourceMap, 476 source_map: &BodySourceMap,
478 offset: Source<TextUnit>, 477 offset: InFile<TextUnit>,
479) -> Option<ScopeId> { 478) -> Option<ScopeId> {
480 scopes 479 scopes
481 .scope_by_expr() 480 .scope_by_expr()
@@ -540,35 +539,3 @@ fn adjust(
540 }) 539 })
541 .map(|(_ptr, scope)| *scope) 540 .map(|(_ptr, scope)| *scope)
542} 541}
543
544/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
545/// FIXME: Not completed
546fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
547 let syn = macro_call.syntax();
548 let parent = match syn.parent() {
549 Some(it) => it,
550 None => {
551 // FIXME:
552 // If it is root, which means the parent HirFile
553 // MacroKindFile must be non-items
554 // return expr now.
555 return MacroFileKind::Expr;
556 }
557 };
558
559 match parent.kind() {
560 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
561 LET_STMT => {
562 // FIXME: Handle Pattern
563 MacroFileKind::Expr
564 }
565 EXPR_STMT => MacroFileKind::Statements,
566 BLOCK => MacroFileKind::Statements,
567 ARG_LIST => MacroFileKind::Expr,
568 TRY_EXPR => MacroFileKind::Expr,
569 _ => {
570 // Unknown , Just guess it is `Items`
571 MacroFileKind::Items
572 }
573 }
574}