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.rs29
1 files changed, 22 insertions, 7 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index e5f4d11a6..fdbe5e8b0 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -228,7 +228,7 @@ impl SourceAnalyzer {
228 let scopes = db.expr_scopes(def); 228 let scopes = db.expr_scopes(def);
229 let scope = match offset { 229 let scope = match offset {
230 None => scope_for(&scopes, &source_map, &node), 230 None => scope_for(&scopes, &source_map, &node),
231 Some(offset) => scope_for_offset(&scopes, &source_map, offset), 231 Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset),
232 }; 232 };
233 let resolver = expr::resolver_for_scope(def.body(db), db, scope); 233 let resolver = expr::resolver_for_scope(def.body(db), db, scope);
234 SourceAnalyzer { 234 SourceAnalyzer {
@@ -330,6 +330,7 @@ impl SourceAnalyzer {
330 .body_source_map 330 .body_source_map
331 .as_ref()? 331 .as_ref()?
332 .pat_syntax(it)? 332 .pat_syntax(it)?
333 .ast // FIXME: ignoring file_id here is definitelly wrong
333 .map_a(|ptr| ptr.cast::<ast::BindPat>().unwrap()); 334 .map_a(|ptr| ptr.cast::<ast::BindPat>().unwrap());
334 PathResolution::LocalBinding(pat_ptr) 335 PathResolution::LocalBinding(pat_ptr)
335 } 336 }
@@ -354,7 +355,7 @@ impl SourceAnalyzer {
354 ret.and_then(|entry| { 355 ret.and_then(|entry| {
355 Some(ScopeEntryWithSyntax { 356 Some(ScopeEntryWithSyntax {
356 name: entry.name().clone(), 357 name: entry.name().clone(),
357 ptr: source_map.pat_syntax(entry.pat())?, 358 ptr: source_map.pat_syntax(entry.pat())?.ast,
358 }) 359 })
359 }) 360 })
360 } 361 }
@@ -470,20 +471,27 @@ fn scope_for(
470fn scope_for_offset( 471fn scope_for_offset(
471 scopes: &ExprScopes, 472 scopes: &ExprScopes,
472 source_map: &BodySourceMap, 473 source_map: &BodySourceMap,
474 file_id: HirFileId,
473 offset: TextUnit, 475 offset: TextUnit,
474) -> Option<ScopeId> { 476) -> Option<ScopeId> {
475 scopes 477 scopes
476 .scope_by_expr() 478 .scope_by_expr()
477 .iter() 479 .iter()
478 .filter_map(|(id, scope)| { 480 .filter_map(|(id, scope)| {
479 let ast_ptr = source_map.expr_syntax(*id)?.a()?; 481 let source = source_map.expr_syntax(*id)?;
480 Some((ast_ptr.syntax_node_ptr(), scope)) 482 // FIXME: correctly handle macro expansion
483 if source.file_id != file_id {
484 return None;
485 }
486 let syntax_node_ptr =
487 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
488 Some((syntax_node_ptr, scope))
481 }) 489 })
482 // find containing scope 490 // find containing scope
483 .min_by_key(|(ptr, _scope)| { 491 .min_by_key(|(ptr, _scope)| {
484 (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) 492 (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len())
485 }) 493 })
486 .map(|(ptr, scope)| adjust(scopes, source_map, ptr, offset).unwrap_or(*scope)) 494 .map(|(ptr, scope)| adjust(scopes, source_map, ptr, file_id, offset).unwrap_or(*scope))
487} 495}
488 496
489// XXX: during completion, cursor might be outside of any particular 497// XXX: during completion, cursor might be outside of any particular
@@ -492,6 +500,7 @@ fn adjust(
492 scopes: &ExprScopes, 500 scopes: &ExprScopes,
493 source_map: &BodySourceMap, 501 source_map: &BodySourceMap,
494 ptr: SyntaxNodePtr, 502 ptr: SyntaxNodePtr,
503 file_id: HirFileId,
495 offset: TextUnit, 504 offset: TextUnit,
496) -> Option<ScopeId> { 505) -> Option<ScopeId> {
497 let r = ptr.range(); 506 let r = ptr.range();
@@ -499,8 +508,14 @@ fn adjust(
499 .scope_by_expr() 508 .scope_by_expr()
500 .iter() 509 .iter()
501 .filter_map(|(id, scope)| { 510 .filter_map(|(id, scope)| {
502 let ast_ptr = source_map.expr_syntax(*id)?.a()?; 511 let source = source_map.expr_syntax(*id)?;
503 Some((ast_ptr.syntax_node_ptr(), scope)) 512 // FIXME: correctly handle macro expansion
513 if source.file_id != file_id {
514 return None;
515 }
516 let syntax_node_ptr =
517 source.ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
518 Some((syntax_node_ptr, scope))
504 }) 519 })
505 .map(|(ptr, scope)| (ptr.range(), scope)) 520 .map(|(ptr, scope)| (ptr.range(), scope))
506 .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r); 521 .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r);