aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_db/src/traits.rs149
1 files changed, 149 insertions, 0 deletions
diff --git a/crates/ide_db/src/traits.rs b/crates/ide_db/src/traits.rs
index dcd61a595..f57b6dd91 100644
--- a/crates/ide_db/src/traits.rs
+++ b/crates/ide_db/src/traits.rs
@@ -76,3 +76,152 @@ pub fn get_missing_assoc_items(
76 .collect() 76 .collect()
77 }) 77 })
78} 78}
79
80#[cfg(test)]
81mod tests {
82 use crate::RootDatabase;
83 use base_db::{fixture::ChangeFixture, FilePosition};
84 use expect_test::{expect, Expect};
85 use hir::Semantics;
86 use syntax::ast::{self, AstNode};
87 use test_utils::RangeOrOffset;
88
89 /// Creates analysis from a multi-file fixture, returns positions marked with <|>.
90 pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
91 let change_fixture = ChangeFixture::parse(ra_fixture);
92 let mut database = RootDatabase::default();
93 database.apply_change(change_fixture.change);
94 let (file_id, range_or_offset) =
95 change_fixture.file_position.expect("expected a marker (<|>)");
96 let offset = match range_or_offset {
97 RangeOrOffset::Range(_) => panic!(),
98 RangeOrOffset::Offset(it) => it,
99 };
100 (database, FilePosition { file_id, offset })
101 }
102
103 fn check_trait(ra_fixture: &str, expect: Expect) {
104 let (db, position) = position(ra_fixture);
105 let sema = Semantics::new(&db);
106 let file = sema.parse(position.file_id);
107 let impl_block: ast::Impl =
108 sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
109 let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
110 let actual = match trait_ {
111 Some(trait_) => trait_.name(&db).to_string(),
112 None => String::new(),
113 };
114 expect.assert_eq(&actual);
115 }
116
117 fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
118 let (db, position) = position(ra_fixture);
119 let sema = Semantics::new(&db);
120 let file = sema.parse(position.file_id);
121 let impl_block: ast::Impl =
122 sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
123 let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
124 let actual = items
125 .into_iter()
126 .map(|item| item.name(&db).unwrap().to_string())
127 .collect::<Vec<_>>()
128 .join("\n");
129 expect.assert_eq(&actual);
130 }
131
132 #[test]
133 fn resolve_trait() {
134 check_trait(
135 r#"
136pub trait Foo {
137 fn bar();
138}
139impl Foo for u8 {
140 <|>
141}
142 "#,
143 expect![["Foo"]],
144 );
145 check_trait(
146 r#"
147pub trait Foo {
148 fn bar();
149}
150impl Foo for u8 {
151 fn bar() {
152 fn baz() {
153 <|>
154 }
155 baz();
156 }
157}
158 "#,
159 expect![["Foo"]],
160 );
161 check_trait(
162 r#"
163pub trait Foo {
164 fn bar();
165}
166pub struct Bar;
167impl Bar {
168 <|>
169}
170 "#,
171 expect![[""]],
172 );
173 }
174
175 #[test]
176 fn missing_assoc_items() {
177 check_missing_assoc(
178 r#"
179pub trait Foo {
180 const FOO: u8;
181 fn bar();
182}
183impl Foo for u8 {
184 <|>
185}"#,
186 expect![[r#"
187 FOO
188 bar"#]],
189 );
190
191 check_missing_assoc(
192 r#"
193pub trait Foo {
194 const FOO: u8;
195 fn bar();
196}
197impl Foo for u8 {
198 const FOO: u8 = 10;
199 <|>
200}"#,
201 expect![[r#"
202 bar"#]],
203 );
204
205 check_missing_assoc(
206 r#"
207pub trait Foo {
208 const FOO: u8;
209 fn bar();
210}
211impl Foo for u8 {
212 const FOO: u8 = 10;
213 fn bar() {<|>}
214}"#,
215 expect![[r#""#]],
216 );
217
218 check_missing_assoc(
219 r#"
220pub struct Foo;
221impl Foo {
222 fn bar() {<|>}
223}"#,
224 expect![[r#""#]],
225 );
226 }
227}