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.rs199
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.
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,29 +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 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
48pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { 24pub(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.
266pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option<Crate>);
267
268#[allow(non_snake_case)]
269impl FamousDefs<'_, '_> {
270 pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core
271pub mod convert {
272 pub trait From<T> {
273 fn from(t: T) -> Self;
274 }
275}
276
277pub mod default {
278 pub trait Default {
279 fn default() -> Self;
280 }
281}
282
283pub 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
348pub mod option {
349 pub enum Option<T> { None, Some(T)}
350}
351
352pub mod prelude {
353 pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}, default::Default};
354}
355#[prelude_import]
356pub 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
435pub(crate) fn next_prev() -> impl Iterator<Item = Direction> { 238pub(crate) fn next_prev() -> impl Iterator<Item = Direction> {
436 [Direction::Next, Direction::Prev].iter().copied() 239 [Direction::Next, Direction::Prev].iter().copied()
437} 240}