From 0fd93bc14a2d0ce2edd682d26c18979c13f181c5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 13 Apr 2019 00:44:47 +0300 Subject: use really correct resolver for expressions --- crates/ra_assists/src/add_explicit_type.rs | 2 +- crates/ra_assists/src/add_missing_impl_members.rs | 2 +- crates/ra_assists/src/fill_match_arms.rs | 2 +- crates/ra_assists/src/fill_struct_fields.rs | 1 + crates/ra_hir/src/source_binder.rs | 24 ++++++++++++++++------ crates/ra_ide_api/src/call_info.rs | 2 +- .../src/completion/completion_context.rs | 3 ++- crates/ra_ide_api/src/goto_definition.rs | 2 +- crates/ra_ide_api/src/hover.rs | 2 +- 9 files changed, 27 insertions(+), 13 deletions(-) diff --git a/crates/ra_assists/src/add_explicit_type.rs b/crates/ra_assists/src/add_explicit_type.rs index c3674ffdc..cb0ac9885 100644 --- a/crates/ra_assists/src/add_explicit_type.rs +++ b/crates/ra_assists/src/add_explicit_type.rs @@ -29,7 +29,7 @@ pub(crate) fn add_explicit_type(mut ctx: AssistCtx) -> Option< } // Infer type let db = ctx.db; - let analyzer = hir::SourceAnalyzer::new(db, ctx.frange.file_id, stmt.syntax()); + let analyzer = hir::SourceAnalyzer::new(db, ctx.frange.file_id, stmt.syntax(), None); let ty = analyzer.type_of(db, expr)?; // Assist not applicable if the type is unknown if is_unknown(&ty) { diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs index 104a4d78a..100ebb7b6 100644 --- a/crates/ra_assists/src/add_missing_impl_members.rs +++ b/crates/ra_assists/src/add_missing_impl_members.rs @@ -45,7 +45,7 @@ fn add_missing_impl_members_inner( let trait_def = { let file_id = ctx.frange.file_id; let position = FilePosition { file_id, offset: impl_node.syntax().range().start() }; - let analyzer = hir::SourceAnalyzer::new(ctx.db, position.file_id, impl_node.syntax()); + let analyzer = hir::SourceAnalyzer::new(ctx.db, position.file_id, impl_node.syntax(), None); resolve_target_trait_def(ctx.db, &analyzer, impl_node)? }; diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index 8110b2676..45e327cd4 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs @@ -20,7 +20,7 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option Some(e), diff --git a/crates/ra_assists/src/fill_struct_fields.rs b/crates/ra_assists/src/fill_struct_fields.rs index 81f762e8d..663b4f669 100644 --- a/crates/ra_assists/src/fill_struct_fields.rs +++ b/crates/ra_assists/src/fill_struct_fields.rs @@ -55,6 +55,7 @@ where self.ctx.db, self.ctx.frange.file_id, self.struct_lit.syntax(), + None, ); let struct_lit_ty = analyzer.type_of(self.ctx.db, self.struct_lit.into())?; let struct_def = match struct_lit_ty.as_adt() { diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 182bc36ff..846394212 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use ra_db::{FileId, FilePosition}; use ra_syntax::{ - SyntaxNode, AstPtr, + SyntaxNode, AstPtr, TextUnit, ast::{self, AstNode, NameOwner}, algo::find_node_at_offset, }; @@ -196,13 +196,21 @@ pub fn trait_from_module( Trait { id: ctx.to_def(trait_def) } } -fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { +fn resolver_for_node( + db: &impl HirDatabase, + file_id: FileId, + node: &SyntaxNode, + offset: Option, +) -> Resolver { node.ancestors() .find_map(|node| { if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { if let Some(func) = function_from_child_node(db, file_id, node) { let scopes = func.scopes(db); - let scope = scopes.scope_for(&node); + let scope = match offset { + None => scopes.scope_for(&node), + Some(offset) => scopes.scope_for_offset(offset), + }; Some(expr::resolver_for_scope(func.body(db), db, scope)) } else { // FIXME const/static/array length @@ -260,7 +268,12 @@ pub enum PathResolution { } impl SourceAnalyzer { - pub fn new(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> SourceAnalyzer { + pub fn new( + db: &impl HirDatabase, + file_id: FileId, + node: &SyntaxNode, + offset: Option, + ) -> SourceAnalyzer { let def_with_body = node.ancestors().find_map(|node| { if let Some(src) = ast::FnDef::cast(node) { return function_from_source(db, file_id, src).map(DefWithBody::from); @@ -274,8 +287,7 @@ impl SourceAnalyzer { None }); SourceAnalyzer { - //TODO: use scope_for_offset here to get correct scope for completion - resolver: resolver_for_node(db, file_id, node), + resolver: resolver_for_node(db, file_id, node, offset), body_source_map: def_with_body.map(|it| it.body_source_map(db)), infer: def_with_body.map(|it| it.infer(db)), } diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index a8495ab01..4413aec73 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -17,7 +17,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { //FIXME: apply subst diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index 86b30e787..359f2cffa 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs @@ -48,7 +48,8 @@ impl<'a> CompletionContext<'a> { ) -> Option> { let module = source_binder::module_from_position(db, position); let token = find_token_at_offset(original_file.syntax(), position.offset).left_biased()?; - let analyzer = hir::SourceAnalyzer::new(db, position.file_id, token.parent()); + let analyzer = + hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset)); let mut ctx = CompletionContext { db, analyzer, diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index abcc682e7..517dffbca 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -47,7 +47,7 @@ pub(crate) fn reference_definition( ) -> ReferenceResult { use self::ReferenceResult::*; - let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax()); + let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); // Special cases: diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 0cba5a665..397b56786 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -132,7 +132,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option { .ancestors() .take_while(|it| it.range() == leaf_node.range()) .find(|&it| ast::Expr::cast(it).is_some() || ast::Pat::cast(it).is_some())?; - let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, node); + let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, node, None); let ty = if let Some(ty) = ast::Expr::cast(node).and_then(|e| analyzer.type_of(db, e)) { ty } else if let Some(ty) = ast::Pat::cast(node).and_then(|p| analyzer.type_of_pat(db, p)) { -- cgit v1.2.3