diff options
-rw-r--r-- | crates/ide_db/src/traits.rs | 149 |
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)] | ||
81 | mod 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#" | ||
136 | pub trait Foo { | ||
137 | fn bar(); | ||
138 | } | ||
139 | impl Foo for u8 { | ||
140 | <|> | ||
141 | } | ||
142 | "#, | ||
143 | expect![["Foo"]], | ||
144 | ); | ||
145 | check_trait( | ||
146 | r#" | ||
147 | pub trait Foo { | ||
148 | fn bar(); | ||
149 | } | ||
150 | impl 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#" | ||
163 | pub trait Foo { | ||
164 | fn bar(); | ||
165 | } | ||
166 | pub struct Bar; | ||
167 | impl Bar { | ||
168 | <|> | ||
169 | } | ||
170 | "#, | ||
171 | expect![[""]], | ||
172 | ); | ||
173 | } | ||
174 | |||
175 | #[test] | ||
176 | fn missing_assoc_items() { | ||
177 | check_missing_assoc( | ||
178 | r#" | ||
179 | pub trait Foo { | ||
180 | const FOO: u8; | ||
181 | fn bar(); | ||
182 | } | ||
183 | impl Foo for u8 { | ||
184 | <|> | ||
185 | }"#, | ||
186 | expect![[r#" | ||
187 | FOO | ||
188 | bar"#]], | ||
189 | ); | ||
190 | |||
191 | check_missing_assoc( | ||
192 | r#" | ||
193 | pub trait Foo { | ||
194 | const FOO: u8; | ||
195 | fn bar(); | ||
196 | } | ||
197 | impl Foo for u8 { | ||
198 | const FOO: u8 = 10; | ||
199 | <|> | ||
200 | }"#, | ||
201 | expect![[r#" | ||
202 | bar"#]], | ||
203 | ); | ||
204 | |||
205 | check_missing_assoc( | ||
206 | r#" | ||
207 | pub trait Foo { | ||
208 | const FOO: u8; | ||
209 | fn bar(); | ||
210 | } | ||
211 | impl Foo for u8 { | ||
212 | const FOO: u8 = 10; | ||
213 | fn bar() {<|>} | ||
214 | }"#, | ||
215 | expect![[r#""#]], | ||
216 | ); | ||
217 | |||
218 | check_missing_assoc( | ||
219 | r#" | ||
220 | pub struct Foo; | ||
221 | impl Foo { | ||
222 | fn bar() {<|>} | ||
223 | }"#, | ||
224 | expect![[r#""#]], | ||
225 | ); | ||
226 | } | ||
227 | } | ||