From f4ae3650d855554575f866264a3c8197dfd12835 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 24 Nov 2020 23:25:13 +0200 Subject: [PATCH 1/4] Extract the import code into the shared module --- Cargo.lock | 18 +- crates/assists/Cargo.toml | 3 +- crates/assists/src/assist_config.rs | 3 +- crates/assists/src/ast_transform.rs | 3 +- crates/assists/src/handlers/auto_import.rs | 5 +- .../extract_struct_from_enum_variant.rs | 16 +- .../assists/src/handlers/fill_match_arms.rs | 9 +- .../handlers/generate_from_impl_for_enum.rs | 3 +- crates/assists/src/handlers/merge_imports.rs | 6 +- crates/assists/src/handlers/qualify_path.rs | 2 +- .../replace_derive_with_manual_impl.rs | 4 +- .../replace_qualified_name_with_use.rs | 8 +- crates/assists/src/utils.rs | 200 +---------------- crates/completion/Cargo.toml | 2 +- crates/completion/src/completions/record.rs | 4 +- .../src/completions/unqualified_path.rs | 2 +- crates/completion/src/config.rs | 2 +- crates/completion/src/item.rs | 7 +- crates/completion/src/render.rs | 2 +- crates/completion/src/render/enum_variant.rs | 2 +- crates/completion/src/render/function.rs | 2 +- crates/completion/src/render/macro_.rs | 3 +- crates/ide/Cargo.toml | 1 + crates/ide/src/inlay_hints.rs | 4 +- crates/ide/src/lib.rs | 4 +- crates/ide_helpers/Cargo.toml | 23 ++ .../utils => ide_helpers/src}/insert_use.rs | 6 +- crates/ide_helpers/src/lib.rs | 201 ++++++++++++++++++ crates/rust-analyzer/Cargo.toml | 1 + crates/rust-analyzer/src/config.rs | 6 +- 30 files changed, 298 insertions(+), 254 deletions(-) create mode 100644 crates/ide_helpers/Cargo.toml rename crates/{assists/src/utils => ide_helpers/src}/insert_use.rs (99%) create mode 100644 crates/ide_helpers/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 633b997580a3..e7d1782cccf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,6 +53,7 @@ dependencies = [ "either", "hir", "ide_db", + "ide_helpers", "itertools", "profile", "rustc-hash", @@ -253,12 +254,12 @@ dependencies = [ name = "completion" version = "0.0.0" dependencies = [ - "assists", "base_db", "either", "expect-test", "hir", "ide_db", + "ide_helpers", "itertools", "log", "profile", @@ -657,6 +658,7 @@ dependencies = [ "expect-test", "hir", "ide_db", + "ide_helpers", "indexmap", "itertools", "log", @@ -693,6 +695,19 @@ dependencies = [ "text_edit", ] +[[package]] +name = "ide_helpers" +version = "0.0.0" +dependencies = [ + "either", + "hir", + "ide_db", + "itertools", + "profile", + "syntax", + "test_utils", +] + [[package]] name = "idna" version = "0.2.0" @@ -1361,6 +1376,7 @@ dependencies = [ "hir_ty", "ide", "ide_db", + "ide_helpers", "itertools", "jod-thread", "log", diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml index 108f656e920e..91d9b6e3f71a 100644 --- a/crates/assists/Cargo.toml +++ b/crates/assists/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] rustc-hash = "1.1.0" itertools = "0.9.0" -either = "1.5.3" +either = "1.6.1" stdx = { path = "../stdx", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" } @@ -21,3 +21,4 @@ profile = { path = "../profile", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } hir = { path = "../hir", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } +ide_helpers = { path = "../ide_helpers", version = "0.0.0" } diff --git a/crates/assists/src/assist_config.rs b/crates/assists/src/assist_config.rs index b24527ec4d43..6d9934e931c0 100644 --- a/crates/assists/src/assist_config.rs +++ b/crates/assists/src/assist_config.rs @@ -5,8 +5,9 @@ //! assists if we are allowed to. use hir::PrefixKind; +use ide_helpers::insert_use::MergeBehaviour; -use crate::{utils::MergeBehaviour, AssistKind}; +use crate::AssistKind; #[derive(Clone, Debug, PartialEq, Eq)] pub struct AssistConfig { diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs index ac72f3f02e24..95b0605993b0 100644 --- a/crates/assists/src/ast_transform.rs +++ b/crates/assists/src/ast_transform.rs @@ -1,5 +1,6 @@ //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. use hir::{HirDisplay, PathResolution, SemanticsScope}; +use ide_helpers::mod_path_to_ast; use rustc_hash::FxHashMap; use syntax::{ algo::SyntaxRewriter, @@ -7,8 +8,6 @@ use syntax::{ SyntaxNode, }; -use crate::utils::mod_path_to_ast; - pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N { SyntaxRewriter::from_fn(|element| match element { syntax::SyntaxElement::Node(n) => { diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs index d665837a2f3b..0b2d508d594d 100644 --- a/crates/assists/src/handlers/auto_import.rs +++ b/crates/assists/src/handlers/auto_import.rs @@ -1,8 +1,11 @@ +use ide_helpers::{ + insert_use::{insert_use, ImportScope}, + mod_path_to_ast, +}; use syntax::ast; use crate::{ utils::import_assets::{ImportAssets, ImportCandidate}, - utils::{insert_use, mod_path_to_ast, ImportScope}, AssistContext, AssistId, AssistKind, Assists, GroupLabel, }; diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs index cac77c49bbc4..fddd5354aa06 100644 --- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs @@ -3,6 +3,10 @@ use std::iter; use either::Either; use hir::{AsName, EnumVariant, Module, ModuleDef, Name}; use ide_db::{defs::Definition, search::Reference, RootDatabase}; +use ide_helpers::{ + insert_use::{insert_use, ImportScope}, + mod_path_to_ast, +}; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ algo::{find_node_at_offset, SyntaxRewriter}, @@ -10,10 +14,7 @@ use syntax::{ SourceFile, SyntaxElement, SyntaxNode, T, }; -use crate::{ - utils::{insert_use, mod_path_to_ast, ImportScope}, - AssistContext, AssistId, AssistKind, Assists, -}; +use crate::{AssistContext, AssistId, AssistKind, Assists}; // Assist: extract_struct_from_enum_variant // @@ -236,10 +237,9 @@ fn update_reference( #[cfg(test)] mod tests { - use crate::{ - tests::{check_assist, check_assist_not_applicable}, - utils::FamousDefs, - }; + use ide_helpers::FamousDefs; + + use crate::tests::{check_assist, check_assist_not_applicable}; use super::*; diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index eda45f5b3fe2..bd42e0f16621 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs @@ -2,12 +2,13 @@ use std::iter; use hir::{Adt, HasSource, ModuleDef, Semantics}; use ide_db::RootDatabase; +use ide_helpers::{mod_path_to_ast, FamousDefs}; use itertools::Itertools; use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; use test_utils::mark; use crate::{ - utils::{mod_path_to_ast, render_snippet, Cursor, FamousDefs}, + utils::{render_snippet, Cursor}, AssistContext, AssistId, AssistKind, Assists, }; @@ -212,12 +213,10 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O #[cfg(test)] mod tests { + use ide_helpers::FamousDefs; use test_utils::mark; - use crate::{ - tests::{check_assist, check_assist_not_applicable, check_assist_target}, - utils::FamousDefs, - }; + use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; use super::fill_match_arms; diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index 674e5a175715..01b14d94d5fa 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs @@ -1,8 +1,9 @@ use ide_db::RootDatabase; +use ide_helpers::FamousDefs; use syntax::ast::{self, AstNode, NameOwner}; use test_utils::mark; -use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists}; // Assist: generate_from_impl_for_enum // diff --git a/crates/assists/src/handlers/merge_imports.rs b/crates/assists/src/handlers/merge_imports.rs index fd9c9e03c725..8207f0e6eba0 100644 --- a/crates/assists/src/handlers/merge_imports.rs +++ b/crates/assists/src/handlers/merge_imports.rs @@ -1,3 +1,4 @@ +use ide_helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehaviour}; use syntax::{ algo::{neighbor, SyntaxRewriter}, ast, AstNode, @@ -5,10 +6,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::{ - insert_use::{try_merge_imports, try_merge_trees}, - next_prev, MergeBehaviour, - }, + utils::next_prev, AssistId, AssistKind, }; diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs index d5bc4e574f18..c0ee7ea0b8d4 100644 --- a/crates/assists/src/handlers/qualify_path.rs +++ b/crates/assists/src/handlers/qualify_path.rs @@ -2,6 +2,7 @@ use std::iter; use hir::AsName; use ide_db::RootDatabase; +use ide_helpers::mod_path_to_ast; use syntax::{ ast, ast::{make, ArgListOwner}, @@ -12,7 +13,6 @@ use test_utils::mark; use crate::{ assist_context::{AssistContext, Assists}, utils::import_assets::{ImportAssets, ImportCandidate}, - utils::mod_path_to_ast, AssistId, AssistKind, GroupLabel, }; diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index 453a6cebfb8c..fe262377c923 100644 --- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,4 +1,5 @@ use ide_db::imports_locator; +use ide_helpers::mod_path_to_ast; use itertools::Itertools; use syntax::{ ast::{self, make, AstNode}, @@ -10,8 +11,7 @@ use syntax::{ use crate::{ assist_context::{AssistBuilder, AssistContext, Assists}, utils::{ - add_trait_assoc_items_to_impl, filter_assoc_items, mod_path_to_ast, render_snippet, Cursor, - DefaultMethods, + add_trait_assoc_items_to_impl, filter_assoc_items, render_snippet, Cursor, DefaultMethods, }, AssistId, AssistKind, }; diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs index a66db9ae3a15..9b8caacd99b2 100644 --- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,10 +1,8 @@ +use ide_helpers::insert_use::{insert_use, ImportScope}; use syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SyntaxNode}; use test_utils::mark; -use crate::{ - utils::{insert_use, ImportScope}, - AssistContext, AssistId, AssistKind, Assists, -}; +use crate::{AssistContext, AssistId, AssistKind, Assists}; // Assist: replace_qualified_name_with_use // @@ -53,7 +51,7 @@ pub(crate) fn replace_qualified_name_with_use( ) } -/// Adds replacements to `re` that shorten `path` in all descendants of `node`. +/// Adds replacements to `re` that shorten `path` in all descendants of `node`.g fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ast::Path) { for child in node.children() { match_ast! { diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 0487465874a8..01f5c291fb35 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -1,10 +1,9 @@ //! Assorted functions shared by several assists. -pub(crate) mod insert_use; pub(crate) mod import_assets; use std::ops; -use hir::{Crate, Enum, HasSource, Module, ScopeDef, Semantics, Trait}; +use hir::HasSource; use ide_db::RootDatabase; use itertools::Itertools; use syntax::{ @@ -22,30 +21,6 @@ use crate::{ ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, }; -pub use insert_use::{insert_use, ImportScope, MergeBehaviour}; - -pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { - let _p = profile::span("mod_path_to_ast"); - let mut segments = Vec::new(); - let mut is_abs = false; - match path.kind { - hir::PathKind::Plain => {} - hir::PathKind::Super(0) => segments.push(make::path_segment_self()), - hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())), - hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => { - segments.push(make::path_segment_crate()) - } - hir::PathKind::Abs => is_abs = true, - } - - segments.extend( - path.segments - .iter() - .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))), - ); - make::path_from_segments(segments, is_abs) -} - pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { extract_trivial_expression(&block) .filter(|expr| !expr.syntax().text().contains_char('\n')) @@ -260,179 +235,6 @@ fn invert_special_case(expr: &ast::Expr) -> Option { } } -/// Helps with finding well-know things inside the standard library. This is -/// somewhat similar to the known paths infra inside hir, but it different; We -/// want to make sure that IDE specific paths don't become interesting inside -/// the compiler itself as well. -pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option); - -#[allow(non_snake_case)] -impl FamousDefs<'_, '_> { - pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core -pub mod convert { - pub trait From { - fn from(t: T) -> Self; - } -} - -pub mod default { - pub trait Default { - fn default() -> Self; - } -} - -pub mod iter { - pub use self::traits::{collect::IntoIterator, iterator::Iterator}; - mod traits { - pub(crate) mod iterator { - use crate::option::Option; - pub trait Iterator { - type Item; - fn next(&mut self) -> Option; - fn by_ref(&mut self) -> &mut Self { - self - } - fn take(self, n: usize) -> crate::iter::Take { - crate::iter::Take { inner: self } - } - } - - impl Iterator for &mut I { - type Item = I::Item; - fn next(&mut self) -> Option { - (**self).next() - } - } - } - pub(crate) mod collect { - pub trait IntoIterator { - type Item; - } - } - } - - pub use self::sources::*; - pub(crate) mod sources { - use super::Iterator; - use crate::option::Option::{self, *}; - pub struct Repeat { - element: A, - } - - pub fn repeat(elt: T) -> Repeat { - Repeat { element: elt } - } - - impl Iterator for Repeat { - type Item = A; - - fn next(&mut self) -> Option { - None - } - } - } - - pub use self::adapters::*; - pub(crate) mod adapters { - use super::Iterator; - use crate::option::Option::{self, *}; - pub struct Take { pub(crate) inner: I } - impl Iterator for Take where I: Iterator { - type Item = ::Item; - fn next(&mut self) -> Option<::Item> { - None - } - } - } -} - -pub mod option { - pub enum Option { None, Some(T)} -} - -pub mod prelude { - pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}, default::Default}; -} -#[prelude_import] -pub use prelude::*; -"#; - - pub fn core(&self) -> Option { - self.find_crate("core") - } - - pub(crate) fn core_convert_From(&self) -> Option { - self.find_trait("core:convert:From") - } - - pub(crate) fn core_option_Option(&self) -> Option { - self.find_enum("core:option:Option") - } - - pub fn core_default_Default(&self) -> Option { - self.find_trait("core:default:Default") - } - - pub fn core_iter_Iterator(&self) -> Option { - self.find_trait("core:iter:traits:iterator:Iterator") - } - - pub fn core_iter(&self) -> Option { - self.find_module("core:iter") - } - - fn find_trait(&self, path: &str) -> Option { - match self.find_def(path)? { - hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), - _ => None, - } - } - - fn find_enum(&self, path: &str) -> Option { - match self.find_def(path)? { - hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it), - _ => None, - } - } - - fn find_module(&self, path: &str) -> Option { - match self.find_def(path)? { - hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it), - _ => None, - } - } - - fn find_crate(&self, name: &str) -> Option { - let krate = self.1?; - let db = self.0.db; - let res = - krate.dependencies(db).into_iter().find(|dep| dep.name.to_string() == name)?.krate; - Some(res) - } - - fn find_def(&self, path: &str) -> Option { - let db = self.0.db; - let mut path = path.split(':'); - let trait_ = path.next_back()?; - let std_crate = path.next()?; - let std_crate = self.find_crate(std_crate)?; - let mut module = std_crate.root_module(db); - for segment in path { - module = module.children(db).find_map(|child| { - let name = child.name(db)?; - if name.to_string() == segment { - Some(child) - } else { - None - } - })?; - } - let def = - module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1; - Some(def) - } -} - pub(crate) fn next_prev() -> impl Iterator { [Direction::Next, Direction::Prev].iter().copied() } diff --git a/crates/completion/Cargo.toml b/crates/completion/Cargo.toml index e7df9d955656..102de33f8fc3 100644 --- a/crates/completion/Cargo.toml +++ b/crates/completion/Cargo.toml @@ -15,7 +15,6 @@ log = "0.4.8" rustc-hash = "1.1.0" either = "1.6.1" -assists = { path = "../assists", version = "0.0.0" } stdx = { path = "../stdx", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" } text_edit = { path = "../text_edit", version = "0.0.0" } @@ -23,6 +22,7 @@ base_db = { path = "../base_db", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } +ide_helpers = { path = "../ide_helpers", version = "0.0.0" } # completions crate should depend only on the top-level `hir` package. if you need # something from some `hir_xxx` subpackage, reexport the API via `hir`. diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs index 2049b9d09116..218a1923c5fb 100644 --- a/crates/completion/src/completions/record.rs +++ b/crates/completion/src/completions/record.rs @@ -1,5 +1,5 @@ //! Complete fields in record literals and patterns. -use assists::utils::FamousDefs; +use ide_helpers::FamousDefs; use syntax::ast::Expr; use crate::{ @@ -45,8 +45,8 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> #[cfg(test)] mod tests { - use assists::utils::FamousDefs; use expect_test::{expect, Expect}; + use ide_helpers::FamousDefs; use crate::{test_utils::completion_list, CompletionKind}; diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 3bd776905226..db5dbb7ddbc4 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs @@ -1,9 +1,9 @@ //! Completion of names from the current scope, e.g. locals and imported items. -use assists::utils::ImportScope; use either::Either; use hir::{Adt, ModuleDef, ScopeDef, Type}; use ide_db::imports_locator; +use ide_helpers::insert_use::ImportScope; use syntax::AstNode; use test_utils::mark; diff --git a/crates/completion/src/config.rs b/crates/completion/src/config.rs index f5073537295b..1995b0754826 100644 --- a/crates/completion/src/config.rs +++ b/crates/completion/src/config.rs @@ -4,7 +4,7 @@ //! module, and we use to statically check that we only produce snippet //! completions if we are allowed to. -use assists::utils::MergeBehaviour; +use ide_helpers::insert_use::MergeBehaviour; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CompletionConfig { diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 7b62c2c4ed13..675cef8c45a8 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs @@ -2,8 +2,11 @@ use std::fmt; -use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour}; use hir::{Documentation, ModPath, Mutability}; +use ide_helpers::{ + insert_use::{self, ImportScope, MergeBehaviour}, + mod_path_to_ast, +}; use syntax::{algo, TextRange}; use text_edit::TextEdit; @@ -300,7 +303,7 @@ impl Builder { label = format!("{}::{}", import_path_without_last_segment, label); } - let rewriter = insert_use(&import_scope, import, merge_behaviour); + let rewriter = insert_use::insert_use(&import_scope, import, merge_behaviour); if let Some(old_ast) = rewriter.rewrite_root() { algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits); } diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index bce02f577388..e9704c27c921 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs @@ -9,9 +9,9 @@ pub(crate) mod type_alias; mod builder_ext; -use assists::utils::{ImportScope, MergeBehaviour}; use hir::{Documentation, HasAttrs, HirDisplay, ModPath, Mutability, ScopeDef, Type}; use ide_db::RootDatabase; +use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use syntax::TextRange; use test_utils::mark; diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs index 64e742b77900..5d4fbb641182 100644 --- a/crates/completion/src/render/enum_variant.rs +++ b/crates/completion/src/render/enum_variant.rs @@ -1,7 +1,7 @@ //! Renderer for `enum` variants. -use assists::utils::{ImportScope, MergeBehaviour}; use hir::{HasAttrs, HirDisplay, ModPath, StructKind}; +use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use itertools::Itertools; use test_utils::mark; diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index e8b726ad61b3..07e99058af81 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs @@ -1,7 +1,7 @@ //! Renderer for function calls. -use assists::utils::{ImportScope, MergeBehaviour}; use hir::{HasSource, ModPath, Type}; +use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use syntax::{ast::Fn, display::function_declaration}; use crate::{ diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index 91055a2969a7..b1284f2019e2 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs @@ -1,7 +1,7 @@ //! Renderer for macro invocations. -use assists::utils::{ImportScope, MergeBehaviour}; use hir::{Documentation, HasSource, ModPath}; +use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use syntax::display::macro_label; use test_utils::mark; @@ -12,6 +12,7 @@ use crate::{ pub(crate) fn render_macro<'a>( ctx: RenderContext<'a>, + // TODO kb add some object instead of a tuple? import_data: Option<(ModPath, ImportScope, Option)>, name: String, macro_: hir::MacroDef, diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 4d483580df37..92d4e5e9fa0b 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -24,6 +24,7 @@ stdx = { path = "../stdx", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" } text_edit = { path = "../text_edit", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } +ide_helpers = { path = "../ide_helpers", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 6cfb22e13ee3..9c8bb7c45cfb 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -1,7 +1,7 @@ -use assists::utils::FamousDefs; use either::Either; use hir::{known, Callable, HirDisplay, Semantics}; use ide_db::RootDatabase; +use ide_helpers::FamousDefs; use stdx::to_lower_snake_case; use syntax::{ ast::{self, ArgListOwner, AstNode, NameOwner}, @@ -427,8 +427,8 @@ fn get_callable(sema: &Semantics, expr: &ast::Expr) -> Option Option { + pub fn from(syntax: SyntaxNode) -> Option { if let Some(module) = ast::Module::cast(syntax.clone()) { module.item_list().map(ImportScope::Module) } else if let this @ Some(_) = ast::SourceFile::cast(syntax.clone()) { @@ -180,7 +180,7 @@ fn eq_visibility(vis0: Option, vis1: Option) - } } -pub(crate) fn try_merge_imports( +pub fn try_merge_imports( lhs: &ast::Use, rhs: &ast::Use, merge_behaviour: MergeBehaviour, @@ -195,7 +195,7 @@ pub(crate) fn try_merge_imports( Some(lhs.with_use_tree(merged)) } -pub(crate) fn try_merge_trees( +pub fn try_merge_trees( lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehaviour, diff --git a/crates/ide_helpers/src/lib.rs b/crates/ide_helpers/src/lib.rs new file mode 100644 index 000000000000..069cb2bdd2aa --- /dev/null +++ b/crates/ide_helpers/src/lib.rs @@ -0,0 +1,201 @@ +use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait}; +use ide_db::RootDatabase; +use syntax::ast::{self, make}; + +pub mod insert_use; + +pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { + let _p = profile::span("mod_path_to_ast"); + + let mut segments = Vec::new(); + let mut is_abs = false; + match path.kind { + hir::PathKind::Plain => {} + hir::PathKind::Super(0) => segments.push(make::path_segment_self()), + hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())), + hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => { + segments.push(make::path_segment_crate()) + } + hir::PathKind::Abs => is_abs = true, + } + + segments.extend( + path.segments + .iter() + .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))), + ); + make::path_from_segments(segments, is_abs) +} + +/// Helps with finding well-know things inside the standard library. This is +/// somewhat similar to the known paths infra inside hir, but it different; We +/// want to make sure that IDE specific paths don't become interesting inside +/// the compiler itself as well. +pub struct FamousDefs<'a, 'b>(pub &'a Semantics<'b, RootDatabase>, pub Option); + +#[allow(non_snake_case)] +impl FamousDefs<'_, '_> { + pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core +pub mod convert { + pub trait From { + fn from(t: T) -> Self; + } +} + +pub mod default { + pub trait Default { + fn default() -> Self; + } +} + +pub mod iter { + pub use self::traits::{collect::IntoIterator, iterator::Iterator}; + mod traits { + pub(crate) mod iterator { + use crate::option::Option; + pub trait Iterator { + type Item; + fn next(&mut self) -> Option; + fn by_ref(&mut self) -> &mut Self { + self + } + fn take(self, n: usize) -> crate::iter::Take { + crate::iter::Take { inner: self } + } + } + + impl Iterator for &mut I { + type Item = I::Item; + fn next(&mut self) -> Option { + (**self).next() + } + } + } + pub(crate) mod collect { + pub trait IntoIterator { + type Item; + } + } + } + + pub use self::sources::*; + pub(crate) mod sources { + use super::Iterator; + use crate::option::Option::{self, *}; + pub struct Repeat { + element: A, + } + + pub fn repeat(elt: T) -> Repeat { + Repeat { element: elt } + } + + impl Iterator for Repeat { + type Item = A; + + fn next(&mut self) -> Option { + None + } + } + } + + pub use self::adapters::*; + pub(crate) mod adapters { + use super::Iterator; + use crate::option::Option::{self, *}; + pub struct Take { pub(crate) inner: I } + impl Iterator for Take where I: Iterator { + type Item = ::Item; + fn next(&mut self) -> Option<::Item> { + None + } + } + } +} + +pub mod option { + pub enum Option { None, Some(T)} +} + +pub mod prelude { + pub use crate::{convert::From, iter::{IntoIterator, Iterator}, option::Option::{self, *}, default::Default}; +} +#[prelude_import] +pub use prelude::*; +"#; + + pub fn core(&self) -> Option { + self.find_crate("core") + } + + pub fn core_convert_From(&self) -> Option { + self.find_trait("core:convert:From") + } + + pub fn core_option_Option(&self) -> Option { + self.find_enum("core:option:Option") + } + + pub fn core_default_Default(&self) -> Option { + self.find_trait("core:default:Default") + } + + pub fn core_iter_Iterator(&self) -> Option { + self.find_trait("core:iter:traits:iterator:Iterator") + } + + pub fn core_iter(&self) -> Option { + self.find_module("core:iter") + } + + fn find_trait(&self, path: &str) -> Option { + match self.find_def(path)? { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), + _ => None, + } + } + + fn find_enum(&self, path: &str) -> Option { + match self.find_def(path)? { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it), + _ => None, + } + } + + fn find_module(&self, path: &str) -> Option { + match self.find_def(path)? { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(it)) => Some(it), + _ => None, + } + } + + fn find_crate(&self, name: &str) -> Option { + let krate = self.1?; + let db = self.0.db; + let res = + krate.dependencies(db).into_iter().find(|dep| dep.name.to_string() == name)?.krate; + Some(res) + } + + fn find_def(&self, path: &str) -> Option { + let db = self.0.db; + let mut path = path.split(':'); + let trait_ = path.next_back()?; + let std_crate = path.next()?; + let std_crate = self.find_crate(std_crate)?; + let mut module = std_crate.root_module(db); + for segment in path { + module = module.children(db).find_map(|child| { + let name = child.name(db)?; + if name.to_string() == segment { + Some(child) + } else { + None + } + })?; + } + let def = + module.scope(db, None).into_iter().find(|(name, _def)| name.to_string() == trait_)?.1; + Some(def) + } +} diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 436f5041bc45..3afcd2edaa17 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -39,6 +39,7 @@ tracing-tree = { version = "0.1.4" } stdx = { path = "../stdx", version = "0.0.0" } flycheck = { path = "../flycheck", version = "0.0.0" } ide = { path = "../ide", version = "0.0.0" } +ide_helpers = { path = "../ide_helpers", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } project_model = { path = "../project_model", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" } diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index a334cdb116a2..d7b711f9451c 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -11,10 +11,8 @@ use std::{convert::TryFrom, ffi::OsString, path::PathBuf}; use flycheck::FlycheckConfig; use hir::PrefixKind; -use ide::{ - AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig, - MergeBehaviour, -}; +use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; +use ide_helpers::insert_use::MergeBehaviour; use lsp_types::{ClientCapabilities, MarkupKind}; use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest}; use rustc_hash::FxHashSet; From f75f07019bd754e4fcc40c6144cc83911bbf21c8 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 27 Nov 2020 12:22:10 +0200 Subject: [PATCH 2/4] Group import data in a struct --- crates/completion/src/item.rs | 31 +++++++++++++------- crates/completion/src/render.rs | 23 ++++++++------- crates/completion/src/render/enum_variant.rs | 14 ++++----- crates/completion/src/render/function.rs | 16 ++++------ crates/completion/src/render/macro_.rs | 17 ++++------- 5 files changed, 49 insertions(+), 52 deletions(-) diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 675cef8c45a8..3bfee1b3f962 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs @@ -204,7 +204,7 @@ impl CompletionItem { trigger_call_info: None, score: None, ref_match: None, - import_data: None, + import_to_add: None, } } @@ -258,13 +258,21 @@ impl CompletionItem { } } +/// An extra import to add after the completion is applied. +#[derive(Clone)] +pub(crate) struct ImportToAdd { + pub(crate) import_path: ModPath, + pub(crate) import_scope: ImportScope, + pub(crate) merge_behaviour: Option, +} + /// A helper to make `CompletionItem`s. #[must_use] #[derive(Clone)] pub(crate) struct Builder { source_range: TextRange, completion_kind: CompletionKind, - import_data: Option<(ModPath, ImportScope, Option)>, + import_to_add: Option, label: String, insert_text: Option, insert_text_format: InsertTextFormat, @@ -288,9 +296,9 @@ impl Builder { let mut insert_text = self.insert_text; let mut text_edits = TextEdit::builder(); - if let Some((import_path, import_scope, merge_behaviour)) = self.import_data { - let import = mod_path_to_ast(&import_path); - let mut import_path_without_last_segment = import_path; + if let Some(import_data) = self.import_to_add { + let import = mod_path_to_ast(&import_data.import_path); + let mut import_path_without_last_segment = import_data.import_path; let _ = import_path_without_last_segment.segments.pop(); if !import_path_without_last_segment.segments.is_empty() { @@ -303,7 +311,11 @@ impl Builder { label = format!("{}::{}", import_path_without_last_segment, label); } - let rewriter = insert_use::insert_use(&import_scope, import, merge_behaviour); + let rewriter = insert_use::insert_use( + &import_data.import_scope, + import, + import_data.merge_behaviour, + ); if let Some(old_ast) = rewriter.rewrite_root() { algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits); } @@ -395,11 +407,8 @@ impl Builder { self.trigger_call_info = Some(true); self } - pub(crate) fn import_data( - mut self, - import_data: Option<(ModPath, ImportScope, Option)>, - ) -> Builder { - self.import_data = import_data; + pub(crate) fn add_import(mut self, import_to_add: Option) -> Builder { + self.import_to_add = import_to_add; self } pub(crate) fn set_ref_match( diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index e9704c27c921..e84aef0e4a9a 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs @@ -16,8 +16,8 @@ use syntax::TextRange; use test_utils::mark; use crate::{ - config::SnippetCap, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, - CompletionScore, + config::SnippetCap, item::ImportToAdd, CompletionContext, CompletionItem, CompletionItemKind, + CompletionKind, CompletionScore, }; use crate::render::{enum_variant::render_enum_variant, function::render_fn, macro_::render_macro}; @@ -48,15 +48,15 @@ pub(crate) fn render_resolution<'a>( pub(crate) fn render_resolution_with_import<'a>( ctx: RenderContext<'a>, - import: ModPath, + import_path: ModPath, import_scope: ImportScope, merge_behaviour: Option, resolution: &ScopeDef, ) -> Option { - let local_name = import.segments.last()?.to_string(); + let local_name = import_path.segments.last()?.to_string(); Render::new(ctx).render_resolution( local_name, - Some((import, import_scope, merge_behaviour)), + Some(ImportToAdd { import_path, import_scope, merge_behaviour }), resolution, ) } @@ -147,7 +147,7 @@ impl<'a> Render<'a> { fn render_resolution( self, local_name: String, - import_data: Option<(ModPath, ImportScope, Option)>, + import_to_add: Option, resolution: &ScopeDef, ) -> Option { let _p = profile::span("render_resolution"); @@ -160,15 +160,16 @@ impl<'a> Render<'a> { let kind = match resolution { ScopeDef::ModuleDef(Function(func)) => { - let item = render_fn(self.ctx, import_data, Some(local_name), *func); + let item = render_fn(self.ctx, import_to_add, Some(local_name), *func); return Some(item); } ScopeDef::ModuleDef(EnumVariant(var)) => { - let item = render_enum_variant(self.ctx, import_data, Some(local_name), *var, None); + let item = + render_enum_variant(self.ctx, import_to_add, Some(local_name), *var, None); return Some(item); } ScopeDef::MacroDef(mac) => { - let item = render_macro(self.ctx, import_data, local_name, *mac); + let item = render_macro(self.ctx, import_to_add, local_name, *mac); return item; } @@ -193,7 +194,7 @@ impl<'a> Render<'a> { local_name, ) .kind(CompletionItemKind::UnresolvedReference) - .import_data(import_data) + .add_import(import_to_add) .build(); return Some(item); } @@ -248,7 +249,7 @@ impl<'a> Render<'a> { let item = item .kind(kind) - .import_data(import_data) + .add_import(import_to_add) .set_documentation(docs) .set_ref_match(ref_match) .build(); diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs index 5d4fbb641182..f4bd02f25815 100644 --- a/crates/completion/src/render/enum_variant.rs +++ b/crates/completion/src/render/enum_variant.rs @@ -1,24 +1,23 @@ //! Renderer for `enum` variants. use hir::{HasAttrs, HirDisplay, ModPath, StructKind}; -use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use itertools::Itertools; use test_utils::mark; use crate::{ - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind, CompletionKind, ImportToAdd}, render::{builder_ext::Params, RenderContext}, }; pub(crate) fn render_enum_variant<'a>( ctx: RenderContext<'a>, - import_data: Option<(ModPath, ImportScope, Option)>, + import_to_add: Option, local_name: Option, variant: hir::EnumVariant, path: Option, ) -> CompletionItem { let _p = profile::span("render_enum_variant"); - EnumVariantRender::new(ctx, local_name, variant, path).render(import_data) + EnumVariantRender::new(ctx, local_name, variant, path).render(import_to_add) } #[derive(Debug)] @@ -63,10 +62,7 @@ impl<'a> EnumVariantRender<'a> { } } - fn render( - self, - import_data: Option<(ModPath, ImportScope, Option)>, - ) -> CompletionItem { + fn render(self, import_to_add: Option) -> CompletionItem { let mut builder = CompletionItem::new( CompletionKind::Reference, self.ctx.source_range(), @@ -75,7 +71,7 @@ impl<'a> EnumVariantRender<'a> { .kind(CompletionItemKind::EnumVariant) .set_documentation(self.variant.docs(self.ctx.db())) .set_deprecated(self.ctx.is_deprecated(self.variant)) - .import_data(import_data) + .add_import(import_to_add) .detail(self.detail()); if self.variant_kind == StructKind::Tuple { diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index 07e99058af81..542383d7e770 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs @@ -1,22 +1,21 @@ //! Renderer for function calls. -use hir::{HasSource, ModPath, Type}; -use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; +use hir::{HasSource, Type}; use syntax::{ast::Fn, display::function_declaration}; use crate::{ - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind, CompletionKind, ImportToAdd}, render::{builder_ext::Params, RenderContext}, }; pub(crate) fn render_fn<'a>( ctx: RenderContext<'a>, - import_data: Option<(ModPath, ImportScope, Option)>, + import_to_add: Option, local_name: Option, fn_: hir::Function, ) -> CompletionItem { let _p = profile::span("render_fn"); - FunctionRender::new(ctx, local_name, fn_).render(import_data) + FunctionRender::new(ctx, local_name, fn_).render(import_to_add) } #[derive(Debug)] @@ -39,10 +38,7 @@ impl<'a> FunctionRender<'a> { FunctionRender { ctx, name, fn_, ast_node } } - fn render( - self, - import_data: Option<(ModPath, ImportScope, Option)>, - ) -> CompletionItem { + fn render(self, import_to_add: Option) -> CompletionItem { let params = self.params(); CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone()) .kind(self.kind()) @@ -50,7 +46,7 @@ impl<'a> FunctionRender<'a> { .set_deprecated(self.ctx.is_deprecated(self.fn_)) .detail(self.detail()) .add_call_parens(self.ctx.completion, self.name, params) - .import_data(import_data) + .add_import(import_to_add) .build() } diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index b1284f2019e2..b4ab32c6e43c 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs @@ -1,24 +1,22 @@ //! Renderer for macro invocations. -use hir::{Documentation, HasSource, ModPath}; -use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; +use hir::{Documentation, HasSource}; use syntax::display::macro_label; use test_utils::mark; use crate::{ - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind, CompletionKind, ImportToAdd}, render::RenderContext, }; pub(crate) fn render_macro<'a>( ctx: RenderContext<'a>, - // TODO kb add some object instead of a tuple? - import_data: Option<(ModPath, ImportScope, Option)>, + import_to_add: Option, name: String, macro_: hir::MacroDef, ) -> Option { let _p = profile::span("render_macro"); - MacroRender::new(ctx, name, macro_).render(import_data) + MacroRender::new(ctx, name, macro_).render(import_to_add) } #[derive(Debug)] @@ -40,10 +38,7 @@ impl<'a> MacroRender<'a> { MacroRender { ctx, name, macro_, docs, bra, ket } } - fn render( - &self, - import_data: Option<(ModPath, ImportScope, Option)>, - ) -> Option { + fn render(&self, import_to_add: Option) -> Option { // FIXME: Currently proc-macro do not have ast-node, // such that it does not have source if self.macro_.is_proc_macro() { @@ -55,7 +50,7 @@ impl<'a> MacroRender<'a> { .kind(CompletionItemKind::Macro) .set_documentation(self.docs.clone()) .set_deprecated(self.ctx.is_deprecated(self.macro_)) - .import_data(import_data) + .add_import(import_to_add) .detail(self.detail()); let needs_bang = self.needs_bang(); From 7b145bd99c855b2f4a15835a2298dde504b04d8f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 27 Nov 2020 12:26:20 +0200 Subject: [PATCH 3/4] Rustdocs fixes --- .../assists/src/handlers/replace_qualified_name_with_use.rs | 2 +- crates/ide_helpers/src/lib.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs index 9b8caacd99b2..5e5c41a6fe30 100644 --- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs @@ -51,7 +51,7 @@ pub(crate) fn replace_qualified_name_with_use( ) } -/// Adds replacements to `re` that shorten `path` in all descendants of `node`.g +/// Adds replacements to `re` that shorten `path` in all descendants of `node`. fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ast::Path) { for child in node.children() { match_ast! { diff --git a/crates/ide_helpers/src/lib.rs b/crates/ide_helpers/src/lib.rs index 069cb2bdd2aa..ad4404b19552 100644 --- a/crates/ide_helpers/src/lib.rs +++ b/crates/ide_helpers/src/lib.rs @@ -1,12 +1,14 @@ +//! A module with ide helpers for high-level ide features. use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait}; use ide_db::RootDatabase; use syntax::ast::{self, make}; pub mod insert_use; +/// Converts the mod path struct into its ast representation. pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { let _p = profile::span("mod_path_to_ast"); - + let mut segments = Vec::new(); let mut is_abs = false; match path.kind { From 3f612d37c68a6e4c09e407b7cd2ad8a1d17ab4e6 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 28 Nov 2020 16:30:39 +0200 Subject: [PATCH 4/4] Move the helpers into ide_db --- Cargo.lock | 18 +-------------- crates/assists/Cargo.toml | 1 - crates/assists/src/assist_config.rs | 2 +- crates/assists/src/ast_transform.rs | 2 +- crates/assists/src/handlers/auto_import.rs | 2 +- .../extract_struct_from_enum_variant.rs | 6 ++--- .../assists/src/handlers/fill_match_arms.rs | 4 ++-- .../handlers/generate_from_impl_for_enum.rs | 2 +- crates/assists/src/handlers/merge_imports.rs | 2 +- crates/assists/src/handlers/qualify_path.rs | 2 +- .../replace_derive_with_manual_impl.rs | 2 +- .../replace_qualified_name_with_use.rs | 2 +- crates/completion/Cargo.toml | 1 - crates/completion/src/completions/record.rs | 4 ++-- .../src/completions/unqualified_path.rs | 2 +- crates/completion/src/config.rs | 2 +- crates/completion/src/item.rs | 2 +- crates/completion/src/render.rs | 2 +- crates/ide/Cargo.toml | 1 - crates/ide/src/inlay_hints.rs | 4 ++-- crates/ide_db/Cargo.toml | 3 ++- .../src/lib.rs => ide_db/src/helpers.rs} | 2 +- .../src => ide_db/src/helpers}/insert_use.rs | 2 +- crates/ide_db/src/lib.rs | 1 + crates/ide_helpers/Cargo.toml | 23 ------------------- crates/rust-analyzer/Cargo.toml | 3 +-- crates/rust-analyzer/src/config.rs | 2 +- 27 files changed, 29 insertions(+), 70 deletions(-) rename crates/{ide_helpers/src/lib.rs => ide_db/src/helpers.rs} (99%) rename crates/{ide_helpers/src => ide_db/src/helpers}/insert_use.rs (99%) delete mode 100644 crates/ide_helpers/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index e7d1782cccf1..f50e9edd66ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,6 @@ dependencies = [ "either", "hir", "ide_db", - "ide_helpers", "itertools", "profile", "rustc-hash", @@ -259,7 +258,6 @@ dependencies = [ "expect-test", "hir", "ide_db", - "ide_helpers", "itertools", "log", "profile", @@ -658,7 +656,6 @@ dependencies = [ "expect-test", "hir", "ide_db", - "ide_helpers", "indexmap", "itertools", "log", @@ -684,6 +681,7 @@ dependencies = [ "expect-test", "fst", "hir", + "itertools", "log", "once_cell", "profile", @@ -695,19 +693,6 @@ dependencies = [ "text_edit", ] -[[package]] -name = "ide_helpers" -version = "0.0.0" -dependencies = [ - "either", - "hir", - "ide_db", - "itertools", - "profile", - "syntax", - "test_utils", -] - [[package]] name = "idna" version = "0.2.0" @@ -1376,7 +1361,6 @@ dependencies = [ "hir_ty", "ide", "ide_db", - "ide_helpers", "itertools", "jod-thread", "log", diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml index 91d9b6e3f71a..3fd8327d6a32 100644 --- a/crates/assists/Cargo.toml +++ b/crates/assists/Cargo.toml @@ -21,4 +21,3 @@ profile = { path = "../profile", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } hir = { path = "../hir", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } -ide_helpers = { path = "../ide_helpers", version = "0.0.0" } diff --git a/crates/assists/src/assist_config.rs b/crates/assists/src/assist_config.rs index 6d9934e931c0..786224cfa1ca 100644 --- a/crates/assists/src/assist_config.rs +++ b/crates/assists/src/assist_config.rs @@ -5,7 +5,7 @@ //! assists if we are allowed to. use hir::PrefixKind; -use ide_helpers::insert_use::MergeBehaviour; +use ide_db::helpers::insert_use::MergeBehaviour; use crate::AssistKind; diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs index 95b0605993b0..66e4634b1d30 100644 --- a/crates/assists/src/ast_transform.rs +++ b/crates/assists/src/ast_transform.rs @@ -1,6 +1,6 @@ //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. use hir::{HirDisplay, PathResolution, SemanticsScope}; -use ide_helpers::mod_path_to_ast; +use ide_db::helpers::mod_path_to_ast; use rustc_hash::FxHashMap; use syntax::{ algo::SyntaxRewriter, diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs index 0b2d508d594d..bd5bba64601e 100644 --- a/crates/assists/src/handlers/auto_import.rs +++ b/crates/assists/src/handlers/auto_import.rs @@ -1,4 +1,4 @@ -use ide_helpers::{ +use ide_db::helpers::{ insert_use::{insert_use, ImportScope}, mod_path_to_ast, }; diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs index fddd5354aa06..d85767b4ecdc 100644 --- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs @@ -2,11 +2,11 @@ use std::iter; use either::Either; use hir::{AsName, EnumVariant, Module, ModuleDef, Name}; -use ide_db::{defs::Definition, search::Reference, RootDatabase}; -use ide_helpers::{ +use ide_db::helpers::{ insert_use::{insert_use, ImportScope}, mod_path_to_ast, }; +use ide_db::{defs::Definition, search::Reference, RootDatabase}; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ algo::{find_node_at_offset, SyntaxRewriter}, @@ -237,7 +237,7 @@ fn update_reference( #[cfg(test)] mod tests { - use ide_helpers::FamousDefs; + use ide_db::helpers::FamousDefs; use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index bd42e0f16621..ef12ef0cf1ad 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs @@ -1,8 +1,8 @@ use std::iter; use hir::{Adt, HasSource, ModuleDef, Semantics}; +use ide_db::helpers::{mod_path_to_ast, FamousDefs}; use ide_db::RootDatabase; -use ide_helpers::{mod_path_to_ast, FamousDefs}; use itertools::Itertools; use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; use test_utils::mark; @@ -213,7 +213,7 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O #[cfg(test)] mod tests { - use ide_helpers::FamousDefs; + use ide_db::helpers::FamousDefs; use test_utils::mark; use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index 01b14d94d5fa..3c374e5d95bc 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs @@ -1,5 +1,5 @@ +use ide_db::helpers::FamousDefs; use ide_db::RootDatabase; -use ide_helpers::FamousDefs; use syntax::ast::{self, AstNode, NameOwner}; use test_utils::mark; diff --git a/crates/assists/src/handlers/merge_imports.rs b/crates/assists/src/handlers/merge_imports.rs index 8207f0e6eba0..b7e853994b3f 100644 --- a/crates/assists/src/handlers/merge_imports.rs +++ b/crates/assists/src/handlers/merge_imports.rs @@ -1,4 +1,4 @@ -use ide_helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehaviour}; +use ide_db::helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehaviour}; use syntax::{ algo::{neighbor, SyntaxRewriter}, ast, AstNode, diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs index c0ee7ea0b8d4..6f9810fe88dc 100644 --- a/crates/assists/src/handlers/qualify_path.rs +++ b/crates/assists/src/handlers/qualify_path.rs @@ -1,8 +1,8 @@ use std::iter; use hir::AsName; +use ide_db::helpers::mod_path_to_ast; use ide_db::RootDatabase; -use ide_helpers::mod_path_to_ast; use syntax::{ ast, ast::{make, ArgListOwner}, diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index fe262377c923..4d6a1956bb19 100644 --- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,5 +1,5 @@ +use ide_db::helpers::mod_path_to_ast; use ide_db::imports_locator; -use ide_helpers::mod_path_to_ast; use itertools::Itertools; use syntax::{ ast::{self, make, AstNode}, diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs index 5e5c41a6fe30..8bdf9eea5e47 100644 --- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,4 +1,4 @@ -use ide_helpers::insert_use::{insert_use, ImportScope}; +use ide_db::helpers::insert_use::{insert_use, ImportScope}; use syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SyntaxNode}; use test_utils::mark; diff --git a/crates/completion/Cargo.toml b/crates/completion/Cargo.toml index 102de33f8fc3..35e169a28c11 100644 --- a/crates/completion/Cargo.toml +++ b/crates/completion/Cargo.toml @@ -22,7 +22,6 @@ base_db = { path = "../base_db", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } -ide_helpers = { path = "../ide_helpers", version = "0.0.0" } # completions crate should depend only on the top-level `hir` package. if you need # something from some `hir_xxx` subpackage, reexport the API via `hir`. diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs index 218a1923c5fb..eaa44c97d1f1 100644 --- a/crates/completion/src/completions/record.rs +++ b/crates/completion/src/completions/record.rs @@ -1,5 +1,5 @@ //! Complete fields in record literals and patterns. -use ide_helpers::FamousDefs; +use ide_db::helpers::FamousDefs; use syntax::ast::Expr; use crate::{ @@ -46,7 +46,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> #[cfg(test)] mod tests { use expect_test::{expect, Expect}; - use ide_helpers::FamousDefs; + use ide_db::helpers::FamousDefs; use crate::{test_utils::completion_list, CompletionKind}; diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index db5dbb7ddbc4..81691cd7f23b 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs @@ -2,8 +2,8 @@ use either::Either; use hir::{Adt, ModuleDef, ScopeDef, Type}; +use ide_db::helpers::insert_use::ImportScope; use ide_db::imports_locator; -use ide_helpers::insert_use::ImportScope; use syntax::AstNode; use test_utils::mark; diff --git a/crates/completion/src/config.rs b/crates/completion/src/config.rs index 1995b0754826..654a76f7b33e 100644 --- a/crates/completion/src/config.rs +++ b/crates/completion/src/config.rs @@ -4,7 +4,7 @@ //! module, and we use to statically check that we only produce snippet //! completions if we are allowed to. -use ide_helpers::insert_use::MergeBehaviour; +use ide_db::helpers::insert_use::MergeBehaviour; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CompletionConfig { diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 3bfee1b3f962..e85549fef4d4 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs @@ -3,7 +3,7 @@ use std::fmt; use hir::{Documentation, ModPath, Mutability}; -use ide_helpers::{ +use ide_db::helpers::{ insert_use::{self, ImportScope, MergeBehaviour}, mod_path_to_ast, }; diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index e84aef0e4a9a..504757a6ae2f 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs @@ -10,8 +10,8 @@ pub(crate) mod type_alias; mod builder_ext; use hir::{Documentation, HasAttrs, HirDisplay, ModPath, Mutability, ScopeDef, Type}; +use ide_db::helpers::insert_use::{ImportScope, MergeBehaviour}; use ide_db::RootDatabase; -use ide_helpers::insert_use::{ImportScope, MergeBehaviour}; use syntax::TextRange; use test_utils::mark; diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 92d4e5e9fa0b..4d483580df37 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -24,7 +24,6 @@ stdx = { path = "../stdx", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" } text_edit = { path = "../text_edit", version = "0.0.0" } ide_db = { path = "../ide_db", version = "0.0.0" } -ide_helpers = { path = "../ide_helpers", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 9c8bb7c45cfb..65df7979cfa2 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -1,7 +1,7 @@ use either::Either; use hir::{known, Callable, HirDisplay, Semantics}; +use ide_db::helpers::FamousDefs; use ide_db::RootDatabase; -use ide_helpers::FamousDefs; use stdx::to_lower_snake_case; use syntax::{ ast::{self, ArgListOwner, AstNode, NameOwner}, @@ -428,7 +428,7 @@ fn get_callable(sema: &Semantics, expr: &ast::Expr) -> Option