2021-03-27 21:51:00 +01:00

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#""#]],
);
}