use really correct resolver for expressions
This commit is contained in:
parent
20013de2ab
commit
0fd93bc14a
9 changed files with 27 additions and 13 deletions
|
@ -29,7 +29,7 @@ pub(crate) fn add_explicit_type(mut ctx: AssistCtx<impl HirDatabase>) -> 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) {
|
||||
|
|
|
@ -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)?
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As
|
|||
}
|
||||
|
||||
let expr = match_expr.expr()?;
|
||||
let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, expr.syntax());
|
||||
let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, expr.syntax(), None);
|
||||
let match_expr_ty = analyzer.type_of(ctx.db, expr)?;
|
||||
let enum_def = match_expr_ty.autoderef(ctx.db).find_map(|ty| match ty.as_adt() {
|
||||
Some((AdtDef::Enum(e), _)) => Some(e),
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<TextUnit>,
|
||||
) -> 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<TextUnit>,
|
||||
) -> 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)),
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
|
|||
let calling_node = FnCallNode::with_node(syntax, position.offset)?;
|
||||
let name_ref = calling_node.name_ref()?;
|
||||
|
||||
let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax());
|
||||
let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None);
|
||||
let function = match calling_node {
|
||||
FnCallNode::CallExpr(expr) => {
|
||||
//FIXME: apply subst
|
||||
|
|
|
@ -48,7 +48,8 @@ impl<'a> CompletionContext<'a> {
|
|||
) -> Option<CompletionContext<'a>> {
|
||||
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,
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
|
|||
.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)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue