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