Correctly classify Rename Names

This commit is contained in:
Lukas Wirth 2021-07-23 02:14:59 +02:00
parent b744e3369d
commit ef6fed052c
2 changed files with 78 additions and 25 deletions

View file

@ -3780,4 +3780,63 @@ struct Foo;
"#]], "#]],
) )
} }
#[test]
fn hover_rename() {
check(
r#"
use self as foo$0;
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
check(
r#"
mod bar {}
use bar::{self as foo$0};
"#,
expect![[r#"
*foo*
```rust
test
```
```rust
mod bar
```
"#]],
);
check(
r#"
mod bar {
use super as foo$0;
}
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
check(
r#"
use crate as foo$0;
"#,
expect![[r#"
*foo*
```rust
extern crate test
```
"#]],
);
}
} }

View file

@ -10,8 +10,8 @@ use hir::{
PathResolution, Semantics, Visibility, PathResolution, Semantics, Visibility,
}; };
use syntax::{ use syntax::{
ast::{self, AstNode, PathSegmentKind}, ast::{self, AstNode},
match_ast, SyntaxKind, SyntaxNode, match_ast, SyntaxKind,
}; };
use crate::RootDatabase; use crate::RootDatabase;
@ -134,29 +134,23 @@ impl NameClass {
if let Some(use_tree) = it.syntax().parent().and_then(ast::UseTree::cast) { if let Some(use_tree) = it.syntax().parent().and_then(ast::UseTree::cast) {
let path = use_tree.path()?; let path = use_tree.path()?;
let path_segment = path.segment()?; let path_segment = path.segment()?;
let name_ref_class = path_segment let name_ref = path_segment.name_ref()?;
.kind() let name_ref = if name_ref.self_token().is_some() {
.and_then(|kind| { use_tree
match kind { .syntax()
// The rename might be from a `self` token, so fallback to the name higher .parent()
// in the use tree. .as_ref()
PathSegmentKind::SelfKw => { // Skip over UseTreeList
let use_tree = use_tree .and_then(|it| {
.syntax() let use_tree = it.parent().and_then(ast::UseTree::cast)?;
.parent() let path = use_tree.path()?;
.as_ref() let path_segment = path.segment()?;
// Skip over UseTreeList path_segment.name_ref()
.and_then(SyntaxNode::parent) }).unwrap_or(name_ref)
.and_then(ast::UseTree::cast)?; } else {
let path = use_tree.path()?; name_ref
let path_segment = path.segment()?; };
path_segment.name_ref() let name_ref_class = NameRefClass::classify(sema, &name_ref)?;
},
PathSegmentKind::Name(name_ref) => Some(name_ref),
_ => None,
}
})
.and_then(|name_ref| NameRefClass::classify(sema, &name_ref))?;
Some(NameClass::Definition(match name_ref_class { Some(NameClass::Definition(match name_ref_class {
NameRefClass::Definition(def) => def, NameRefClass::Definition(def) => def,