mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
146 lines
3.1 KiB
Rust
146 lines
3.1 KiB
Rust
use base_db::{fixture::ChangeFixture, FilePosition};
|
|
use expect_test::{expect, Expect};
|
|
use hir::Semantics;
|
|
use syntax::ast::{self, AstNode};
|
|
use test_utils::RangeOrOffset;
|
|
|
|
use crate::RootDatabase;
|
|
|
|
/// Creates analysis from a multi-file fixture, returns positions marked with $0.
|
|
pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
|
|
let change_fixture = ChangeFixture::parse(ra_fixture);
|
|
let mut database = RootDatabase::default();
|
|
database.apply_change(change_fixture.change);
|
|
let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
|
|
let offset = match range_or_offset {
|
|
RangeOrOffset::Range(_) => panic!(),
|
|
RangeOrOffset::Offset(it) => it,
|
|
};
|
|
(database, FilePosition { file_id, offset })
|
|
}
|
|
|
|
fn check_trait(ra_fixture: &str, expect: Expect) {
|
|
let (db, position) = position(ra_fixture);
|
|
let sema = Semantics::new(&db);
|
|
let file = sema.parse(position.file_id);
|
|
let impl_block: ast::Impl =
|
|
sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
|
|
let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
|
|
let actual = match trait_ {
|
|
Some(trait_) => trait_.name(&db).to_string(),
|
|
None => String::new(),
|
|
};
|
|
expect.assert_eq(&actual);
|
|
}
|
|
|
|
fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
|
|
let (db, position) = position(ra_fixture);
|
|
let sema = Semantics::new(&db);
|
|
let file = sema.parse(position.file_id);
|
|
let impl_block: ast::Impl =
|
|
sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
|
|
let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
|
|
let actual = items
|
|
.into_iter()
|
|
.map(|item| item.name(&db).unwrap().to_string())
|
|
.collect::<Vec<_>>()
|
|
.join("\n");
|
|
expect.assert_eq(&actual);
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_trait() {
|
|
check_trait(
|
|
r#"
|
|
pub trait Foo {
|
|
fn bar();
|
|
}
|
|
impl Foo for u8 {
|
|
$0
|
|
}
|
|
"#,
|
|
expect![["Foo"]],
|
|
);
|
|
check_trait(
|
|
r#"
|
|
pub trait Foo {
|
|
fn bar();
|
|
}
|
|
impl Foo for u8 {
|
|
fn bar() {
|
|
fn baz() {
|
|
$0
|
|
}
|
|
baz();
|
|
}
|
|
}
|
|
"#,
|
|
expect![["Foo"]],
|
|
);
|
|
check_trait(
|
|
r#"
|
|
pub trait Foo {
|
|
fn bar();
|
|
}
|
|
pub struct Bar;
|
|
impl Bar {
|
|
$0
|
|
}
|
|
"#,
|
|
expect![[""]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn missing_assoc_items() {
|
|
check_missing_assoc(
|
|
r#"
|
|
pub trait Foo {
|
|
const FOO: u8;
|
|
fn bar();
|
|
}
|
|
impl Foo for u8 {
|
|
$0
|
|
}"#,
|
|
expect![[r#"
|
|
FOO
|
|
bar"#]],
|
|
);
|
|
|
|
check_missing_assoc(
|
|
r#"
|
|
pub trait Foo {
|
|
const FOO: u8;
|
|
fn bar();
|
|
}
|
|
impl Foo for u8 {
|
|
const FOO: u8 = 10;
|
|
$0
|
|
}"#,
|
|
expect![[r#"
|
|
bar"#]],
|
|
);
|
|
|
|
check_missing_assoc(
|
|
r#"
|
|
pub trait Foo {
|
|
const FOO: u8;
|
|
fn bar();
|
|
}
|
|
impl Foo for u8 {
|
|
const FOO: u8 = 10;
|
|
fn bar() {$0}
|
|
}"#,
|
|
expect![[r#""#]],
|
|
);
|
|
|
|
check_missing_assoc(
|
|
r#"
|
|
pub struct Foo;
|
|
impl Foo {
|
|
fn bar() {$0}
|
|
}"#,
|
|
expect![[r#""#]],
|
|
);
|
|
}
|