diff options
Diffstat (limited to 'crates/assists/src/utils.rs')
-rw-r--r-- | crates/assists/src/utils.rs | 199 |
1 files changed, 1 insertions, 198 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 66c0cdd5f..01f5c291f 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -1,10 +1,9 @@ | |||
1 | //! Assorted functions shared by several assists. | 1 | //! Assorted functions shared by several assists. |
2 | pub(crate) mod insert_use; | ||
3 | pub(crate) mod import_assets; | 2 | pub(crate) mod import_assets; |
4 | 3 | ||
5 | use std::ops; | 4 | use std::ops; |
6 | 5 | ||
7 | use hir::{Crate, Enum, HasSource, Module, ScopeDef, Semantics, Trait}; | 6 | use hir::HasSource; |
8 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
9 | use itertools::Itertools; | 8 | use itertools::Itertools; |
10 | use syntax::{ | 9 | use syntax::{ |
@@ -22,29 +21,6 @@ use crate::{ | |||
22 | ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, | 21 | ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, |
23 | }; | 22 | }; |
24 | 23 | ||
25 | pub use insert_use::{insert_use, ImportScope, MergeBehaviour}; | ||
26 | |||
27 | pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { | ||
28 | let mut segments = Vec::new(); | ||
29 | let mut is_abs = false; | ||
30 | match path.kind { | ||
31 | hir::PathKind::Plain => {} | ||
32 | hir::PathKind::Super(0) => segments.push(make::path_segment_self()), | ||
33 | hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())), | ||
34 | hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => { | ||
35 | segments.push(make::path_segment_crate()) | ||
36 | } | ||
37 | hir::PathKind::Abs => is_abs = true, | ||
38 | } | ||
39 | |||
40 | segments.extend( | ||
41 | path.segments | ||
42 | .iter() | ||
43 | .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))), | ||
44 | ); | ||
45 | make::path_from_segments(segments, is_abs) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | 24 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { |
49 | extract_trivial_expression(&block) | 25 | extract_trivial_expression(&block) |
50 | .filter(|expr| !expr.syntax().text().contains_char('\n')) | 26 | .filter(|expr| !expr.syntax().text().contains_char('\n')) |
@@ -259,179 +235,6 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> { | |||
259 | } | 235 | } |
260 | } | 236 | } |
261 | 237 | ||
262 | /// Helps with finding well-know things inside the standard library. This is | ||
263 | /// somewhat similar to the known paths infra inside hir, but it different; We | ||
264 | /// want to make sure that IDE specific paths don't become interesting inside | ||
265 | /// the compiler itself as well. | ||
266 | pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>); | ||
267 | |||
268 | #[allow(non_snake_case)] | ||
269 | impl FamousDefs<'_, '_> { | ||
270 | pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core | ||
271 | pub mod convert { | ||
272 | pub trait From<T> { | ||
273 | fn from(t: T) -> Self; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | pub mod default { | ||
278 | pub trait Default { | ||
279 | fn default() -> Self; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | pub mod iter { | ||
284 | pub use self::traits::{collect::IntoIterator, iterator::Iterator}; | ||
285 | mod traits { | ||
286 | pub(crate) mod iterator { | ||
287 | use crate::option::Option; | ||
288 | pub trait Iterator { | ||
289 | type Item; | ||
290 | fn next(&mut self) -> Option<Self::Item>; | ||
291 | fn by_ref(&mut self) -> &mut Self { | ||
292 | self | ||
293 | } | ||
294 | fn take(self, n: usize) -> crate::iter::Take<Self> { | ||
295 | crate::iter::Take { inner: self } | ||
296 | } | ||
297 | } | ||
298 | |||
299 | impl<I: Iterator> Iterator for &mut I { | ||
300 | type Item = I::Item; | ||
301 | fn next(&mut self) -> Option<I::Item> { | ||
302 | (**self).next() | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | pub(crate) mod collect { | ||
307 | pub trait IntoIterator { | ||
308 | type Item; | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | pub use self::sources::*; | ||
314 | pub(crate) mod sources { | ||
315 | use super::Iterator; | ||
316 | use crate::option::Option::{self, *}; | ||
317 | pub struct Repeat<A> { | ||
318 | element: A, | ||
319 | } | ||
320 | |||
321 | pub fn repeat<T>(elt: T) -> Repeat<T> { | ||
322 | Repeat { element: elt } | ||
323 | } | ||
324 | |||
325 | impl<A> Iterator for Repeat<A> { | ||
326 | type Item = A; | ||
327 | |||
328 | fn next(&mut self) -> Option<A> { | ||
329 | None | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | pub use self::adapters::*; | ||
335 | pub(crate) mod adapters { | ||
336 | use super::Iterator; | ||
337 | use crate::option::Option::{self, *}; | ||
338 | pub struct Take<I> { pub(crate) inner: I } | ||
339 | impl<I> Iterator for Take<I> where I: Iterator { | ||
340 | type Item = <I as Iterator>::Item; | ||
341 | fn next(&mut self) -> Option<<I as Iterator>::Item> { | ||
342 | None | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | |||
348 | pub mod option { | ||
349 | pub enum Option<T> { None, Some(T)} | ||
350 | } | ||
351 | |||
352 | pub mod prelude { | ||
353 | pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}, default::Default}; | ||
354 | } | ||
355 | #[prelude_import] | ||
356 | pub use prelude::*; | ||
357 | "#; | ||
358 | |||
359 | pub fn core(&self) -> Option<Crate> { | ||
360 | self.find_crate("core") | ||
361 | } | ||
362 | |||
363 | pub(crate) fn core_convert_From(&self) -> Option<Trait> { | ||
364 | self.find_trait("core:convert:From") | ||
365 | } | ||
366 | |||
367 | pub(crate) fn core_option_Option(&self) -> Option<Enum> { | ||
368 | self.find_enum("core:option:Option") | ||
369 | } | ||
370 | |||
371 | pub fn core_default_Default(&self) -> Option<Trait> { | ||
372 | self.find_trait("core:default:Default") | ||
373 | } | ||
374 | |||
375 | pub fn core_iter_Iterator(&self) -> Option<Trait> { | ||
376 | self.find_trait("core:iter:traits:iterator:Iterator") | ||
377 | } | ||
378 | |||
379 | pub fn core_iter(&self) -> Option<Module> { | ||
380 | self.find_module("core:iter") | ||
381 | } | ||
382 | |||
383 | fn find_trait(&self, path: &str) -> Option<Trait> { | ||
384 | match self.find_def(path)? { | ||
385 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), | ||
386 | _ => None, | ||
387 | } | ||
388 | } | ||
389 | |||
390 | fn find_enum(&self, path: &str) -> Option<Enum> { | ||
391 | match self.find_def(path)? { | ||
392 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it), | ||
393 | _ => None, | ||
394 | } | ||
395 | } | ||
396 | |||
397 | fn find_module(&self, path: &str) -> Option<Module> { | ||
398 | match self.find_def(path)? { | ||
399 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it), | ||
400 | _ => None, | ||
401 | } | ||
402 | } | ||
403 | |||
404 | fn find_crate(&self, name: &str) -> Option<Crate> { | ||
405 | let krate = self.1?; | ||
406 | let db = self.0.db; | ||
407 | let res = | ||
408 | krate.dependencies(db).into_iter().find(|dep| dep.name.to_string() == name)?.krate; | ||
409 | Some(res) | ||
410 | } | ||
411 | |||
412 | fn find_def(&self, path: &str) -> Option<ScopeDef> { | ||
413 | let db = self.0.db; | ||
414 | let mut path = path.split(':'); | ||
415 | let trait_ = path.next_back()?; | ||
416 | let std_crate = path.next()?; | ||
417 | let std_crate = self.find_crate(std_crate)?; | ||
418 | let mut module = std_crate.root_module(db); | ||
419 | for segment in path { | ||
420 | module = module.children(db).find_map(|child| { | ||
421 | let name = child.name(db)?; | ||
422 | if name.to_string() == segment { | ||
423 | Some(child) | ||
424 | } else { | ||
425 | None | ||
426 | } | ||
427 | })?; | ||
428 | } | ||
429 | let def = | ||
430 | module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1; | ||
431 | Some(def) | ||
432 | } | ||
433 | } | ||
434 | |||
435 | pub(crate) fn next_prev() -> impl Iterator<Item = Direction> { | 238 | pub(crate) fn next_prev() -> impl Iterator<Item = Direction> { |
436 | [Direction::Next, Direction::Prev].iter().copied() | 239 | [Direction::Next, Direction::Prev].iter().copied() |
437 | } | 240 | } |