diff options
-rw-r--r-- | crates/ra_ide_api_light/src/typing.rs | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/crates/ra_ide_api_light/src/typing.rs b/crates/ra_ide_api_light/src/typing.rs index 05845a0cc..c8f3dfe44 100644 --- a/crates/ra_ide_api_light/src/typing.rs +++ b/crates/ra_ide_api_light/src/typing.rs | |||
@@ -133,12 +133,18 @@ mod tests { | |||
133 | 133 | ||
134 | #[test] | 134 | #[test] |
135 | fn test_on_eq_typed() { | 135 | fn test_on_eq_typed() { |
136 | fn do_check(before: &str, after: &str) { | 136 | fn type_eq(before: &str, after: &str) { |
137 | let (offset, before) = extract_offset(before); | 137 | let (offset, before) = extract_offset(before); |
138 | let mut edit = TextEditBuilder::default(); | ||
139 | edit.insert(offset, "=".to_string()); | ||
140 | let before = edit.finish().apply(&before); | ||
138 | let file = SourceFile::parse(&before); | 141 | let file = SourceFile::parse(&before); |
139 | let result = on_eq_typed(&file, offset).unwrap(); | 142 | if let Some(result) = on_eq_typed(&file, offset) { |
140 | let actual = result.edit.apply(&before); | 143 | let actual = result.edit.apply(&before); |
141 | assert_eq_text!(after, &actual); | 144 | assert_eq_text!(after, &actual); |
145 | } else { | ||
146 | assert_eq_text!(&before, after) | ||
147 | }; | ||
142 | } | 148 | } |
143 | 149 | ||
144 | // do_check(r" | 150 | // do_check(r" |
@@ -150,10 +156,10 @@ mod tests { | |||
150 | // let foo =; | 156 | // let foo =; |
151 | // } | 157 | // } |
152 | // "); | 158 | // "); |
153 | do_check( | 159 | type_eq( |
154 | r" | 160 | r" |
155 | fn foo() { | 161 | fn foo() { |
156 | let foo <|>= 1 + 1 | 162 | let foo <|> 1 + 1 |
157 | } | 163 | } |
158 | ", | 164 | ", |
159 | r" | 165 | r" |
@@ -175,24 +181,27 @@ fn foo() { | |||
175 | // "); | 181 | // "); |
176 | } | 182 | } |
177 | 183 | ||
184 | fn type_dot(before: &str, after: &str) { | ||
185 | let (offset, before) = extract_offset(before); | ||
186 | let mut edit = TextEditBuilder::default(); | ||
187 | edit.insert(offset, ".".to_string()); | ||
188 | let before = edit.finish().apply(&before); | ||
189 | let file = SourceFile::parse(&before); | ||
190 | if let Some(result) = on_dot_typed(&file, offset) { | ||
191 | let actual = result.edit.apply(&before); | ||
192 | assert_eq_text!(after, &actual); | ||
193 | } else { | ||
194 | assert_eq_text!(&before, after) | ||
195 | }; | ||
196 | } | ||
197 | |||
178 | #[test] | 198 | #[test] |
179 | fn test_on_dot_typed() { | 199 | fn indents_new_chain_call() { |
180 | fn do_check(before: &str, after: &str) { | 200 | type_dot( |
181 | let (offset, before) = extract_offset(before); | ||
182 | let file = SourceFile::parse(&before); | ||
183 | if let Some(result) = on_dot_typed(&file, offset) { | ||
184 | let actual = result.edit.apply(&before); | ||
185 | assert_eq_text!(after, &actual); | ||
186 | } else { | ||
187 | assert_eq_text!(&before, after) | ||
188 | }; | ||
189 | } | ||
190 | // indent if continuing chain call | ||
191 | do_check( | ||
192 | r" | 201 | r" |
193 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 202 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
194 | self.child_impl(db, name) | 203 | self.child_impl(db, name) |
195 | <|>. | 204 | <|> |
196 | } | 205 | } |
197 | ", | 206 | ", |
198 | r" | 207 | r" |
@@ -202,13 +211,11 @@ fn foo() { | |||
202 | } | 211 | } |
203 | ", | 212 | ", |
204 | ); | 213 | ); |
205 | 214 | type_dot( | |
206 | // do not indent if already indented | ||
207 | do_check( | ||
208 | r" | 215 | r" |
209 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 216 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
210 | self.child_impl(db, name) | 217 | self.child_impl(db, name) |
211 | <|>. | 218 | <|> |
212 | } | 219 | } |
213 | ", | 220 | ", |
214 | r" | 221 | r" |
@@ -217,15 +224,17 @@ fn foo() { | |||
217 | . | 224 | . |
218 | } | 225 | } |
219 | ", | 226 | ", |
220 | ); | 227 | ) |
228 | } | ||
221 | 229 | ||
222 | // indent if the previous line is already indented | 230 | #[test] |
223 | do_check( | 231 | fn indents_continued_chain_call() { |
232 | type_dot( | ||
224 | r" | 233 | r" |
225 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 234 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
226 | self.child_impl(db, name) | 235 | self.child_impl(db, name) |
227 | .first() | 236 | .first() |
228 | <|>. | 237 | <|> |
229 | } | 238 | } |
230 | ", | 239 | ", |
231 | r" | 240 | r" |
@@ -236,14 +245,12 @@ fn foo() { | |||
236 | } | 245 | } |
237 | ", | 246 | ", |
238 | ); | 247 | ); |
239 | 248 | type_dot( | |
240 | // don't indent if indent matches previous line | ||
241 | do_check( | ||
242 | r" | 249 | r" |
243 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 250 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
244 | self.child_impl(db, name) | 251 | self.child_impl(db, name) |
245 | .first() | 252 | .first() |
246 | <|>. | 253 | <|> |
247 | } | 254 | } |
248 | ", | 255 | ", |
249 | r" | 256 | r" |
@@ -254,12 +261,14 @@ fn foo() { | |||
254 | } | 261 | } |
255 | ", | 262 | ", |
256 | ); | 263 | ); |
264 | } | ||
257 | 265 | ||
258 | // don't indent if there is no method call on previous line | 266 | #[test] |
259 | do_check( | 267 | fn dont_indent_freestanding_dot() { |
268 | type_dot( | ||
260 | r" | 269 | r" |
261 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 270 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
262 | <|>. | 271 | <|> |
263 | } | 272 | } |
264 | ", | 273 | ", |
265 | r" | 274 | r" |
@@ -268,19 +277,15 @@ fn foo() { | |||
268 | } | 277 | } |
269 | ", | 278 | ", |
270 | ); | 279 | ); |
271 | 280 | type_dot( | |
272 | // indent to match previous expr | ||
273 | do_check( | ||
274 | r" | 281 | r" |
275 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 282 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
276 | self.child_impl(db, name) | 283 | <|> |
277 | <|>. | 284 | } |
278 | } | ||
279 | ", | 285 | ", |
280 | r" | 286 | r" |
281 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 287 | pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
282 | self.child_impl(db, name) | 288 | . |
283 | . | ||
284 | } | 289 | } |
285 | ", | 290 | ", |
286 | ); | 291 | ); |