aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/utils.rs')
-rw-r--r--crates/assists/src/utils.rs200
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.
2pub(crate) mod insert_use;
3pub(crate) mod import_assets; 2pub(crate) mod import_assets;
4 3
5use std::ops; 4use std::ops;
6 5
7use hir::{Crate, Enum, HasSource, Module, ScopeDef, Semantics, Trait}; 6use hir::HasSource;
8use ide_db::RootDatabase; 7use ide_db::RootDatabase;
9use itertools::Itertools; 8use itertools::Itertools;
10use syntax::{ 9use 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
25pub use insert_use::{insert_use, ImportScope, MergeBehaviour};
26
27pub 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
49pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { 24pub(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.
267pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>);
268
269#[allow(non_snake_case)]
270impl FamousDefs<'_, '_> {
271 pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
272pub mod convert {
273 pub trait From<T> {
274 fn from(t: T) -> Self;
275 }
276}
277
278pub mod default {
279 pub trait Default {
280 fn default() -> Self;
281 }
282}
283
284pub 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
349pub mod option {
350 pub enum Option<T> { None, Some(T)}
351}
352
353pub mod prelude {
354 pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}, default::Default};
355}
356#[prelude_import]
357pub 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
436pub(crate) fn next_prev() -> impl Iterator<Item = Direction> { 238pub(crate) fn next_prev() -> impl Iterator<Item = Direction> {
437 [Direction::Next, Direction::Prev].iter().copied() 239 [Direction::Next, Direction::Prev].iter().copied()
438} 240}