mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
generalize SourceAnalyzer to handle all defs with bodies
This commit is contained in:
parent
07cc047b4f
commit
5471c1ef4b
3 changed files with 51 additions and 11 deletions
|
@ -454,6 +454,14 @@ impl DefWithBody {
|
||||||
db.body_hir(*self)
|
db.body_hir(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||||
|
match *self {
|
||||||
|
DefWithBody::Const(ref c) => c.body_source_map(db),
|
||||||
|
DefWithBody::Function(ref f) => f.body_source_map(db),
|
||||||
|
DefWithBody::Static(ref s) => s.body_source_map(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds a resolver for code inside this item.
|
/// Builds a resolver for code inside this item.
|
||||||
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
HirDatabase, Function, Struct, Enum, Const, Static, Either,
|
HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody,
|
||||||
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
||||||
ids::LocationCtx,
|
ids::LocationCtx,
|
||||||
expr, AstId
|
expr, AstId
|
||||||
|
@ -219,7 +219,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub 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) -> Resolver {
|
||||||
node.ancestors()
|
node.ancestors()
|
||||||
.find_map(|node| {
|
.find_map(|node| {
|
||||||
if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
|
if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
|
||||||
|
@ -284,16 +284,24 @@ pub enum PathResolution {
|
||||||
|
|
||||||
impl SourceAnalyzer {
|
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) -> SourceAnalyzer {
|
||||||
let resolver = resolver_for_node(db, file_id, node);
|
let def_with_body = node.ancestors().find_map(|node| {
|
||||||
let function = function_from_child_node(db, file_id, node);
|
if let Some(src) = ast::FnDef::cast(node) {
|
||||||
if let Some(function) = function {
|
return function_from_source(db, file_id, src).map(DefWithBody::from);
|
||||||
SourceAnalyzer {
|
|
||||||
resolver,
|
|
||||||
body_source_map: Some(function.body_source_map(db)),
|
|
||||||
infer: Some(function.infer(db)),
|
|
||||||
}
|
}
|
||||||
} else {
|
if let Some(src) = ast::StaticDef::cast(node) {
|
||||||
SourceAnalyzer { resolver, body_source_map: None, infer: None }
|
return static_from_source(db, file_id, src).map(DefWithBody::from);
|
||||||
|
}
|
||||||
|
if let Some(src) = ast::ConstDef::cast(node) {
|
||||||
|
return const_from_source(db, file_id, src).map(DefWithBody::from);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
});
|
||||||
|
SourceAnalyzer {
|
||||||
|
resolver: def_with_body
|
||||||
|
.map(|it| it.resolver(db))
|
||||||
|
.unwrap_or_else(|| resolver_for_node(db, file_id, node)),
|
||||||
|
body_source_map: def_with_body.map(|it| it.body_source_map(db)),
|
||||||
|
infer: def_with_body.map(|it| it.infer(db)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,30 @@ mod tests {
|
||||||
kind: Method,
|
kind: Method,
|
||||||
detail: "pub fn blah(&self)"
|
detail: "pub fn blah(&self)"
|
||||||
}
|
}
|
||||||
|
]"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_completion_works_in_consts() {
|
||||||
|
assert_debug_snapshot_matches!(
|
||||||
|
do_ref_completion(
|
||||||
|
r"
|
||||||
|
struct A { the_field: u32 }
|
||||||
|
const X: u32 = {
|
||||||
|
A { the_field: 92 }.<|>
|
||||||
|
};
|
||||||
|
",
|
||||||
|
),
|
||||||
|
@r###"[
|
||||||
|
CompletionItem {
|
||||||
|
label: "the_field",
|
||||||
|
source_range: [106; 106),
|
||||||
|
delete: [106; 106),
|
||||||
|
insert: "the_field",
|
||||||
|
kind: Field,
|
||||||
|
detail: "u32"
|
||||||
|
}
|
||||||
]"###
|
]"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue