aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock22
-rw-r--r--crates/assists/Cargo.toml1
-rw-r--r--crates/assists/src/assist_context.rs2
-rw-r--r--crates/assists/src/handlers/add_missing_impl_members.rs3
-rw-r--r--crates/assists/src/handlers/extract_struct_from_enum_variant.rs2
-rw-r--r--crates/assists/src/handlers/fix_visibility.rs2
-rw-r--r--crates/assists/src/handlers/generate_function.rs2
-rw-r--r--crates/assists/src/handlers/replace_if_let_with_match.rs6
-rw-r--r--crates/assists/src/handlers/replace_let_with_if_let.rs3
-rw-r--r--crates/assists/src/handlers/replace_unwrap_with_match.rs3
-rw-r--r--crates/assists/src/lib.rs2
-rw-r--r--crates/assists/src/tests.rs2
-rw-r--r--crates/assists/src/utils.rs121
-rw-r--r--crates/call_info/Cargo.toml26
-rw-r--r--crates/completion/Cargo.toml2
-rw-r--r--crates/completion/src/complete_mod.rs2
-rw-r--r--crates/completion/src/complete_postfix.rs2
-rw-r--r--crates/completion/src/complete_trait_impl.rs2
-rw-r--r--crates/completion/src/completion_context.rs5
-rw-r--r--crates/completion/src/lib.rs2
-rw-r--r--crates/completion/src/test_utils.rs2
-rw-r--r--crates/ide/Cargo.toml2
-rw-r--r--crates/ide/src/call_hierarchy.rs4
-rw-r--r--crates/ide/src/diagnostics.rs2
-rw-r--r--crates/ide/src/diagnostics/field_shorthand.rs2
-rw-r--r--crates/ide/src/diagnostics/fixes.rs2
-rw-r--r--crates/ide/src/display/navigation_target.rs2
-rw-r--r--crates/ide/src/fixture.rs2
-rw-r--r--crates/ide/src/goto_definition.rs2
-rw-r--r--crates/ide/src/goto_implementation.rs2
-rw-r--r--crates/ide/src/goto_type_definition.rs2
-rw-r--r--crates/ide/src/hover.rs31
-rw-r--r--crates/ide/src/lib.rs12
-rw-r--r--crates/ide/src/parent_module.rs2
-rw-r--r--crates/ide/src/prime_caches.rs2
-rw-r--r--crates/ide/src/references.rs2
-rw-r--r--crates/ide/src/references/rename.rs2
-rw-r--r--crates/ide/src/status.rs6
-rw-r--r--crates/ide/src/syntax_highlighting/html.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/injection.rs2
-rw-r--r--crates/ide/src/syntax_tree.rs2
-rw-r--r--crates/ide/src/typing.rs2
-rw-r--r--crates/ide/src/typing/on_enter.rs2
-rw-r--r--crates/ide_db/Cargo.toml3
-rw-r--r--crates/ide_db/src/call_info.rs (renamed from crates/call_info/src/lib.rs)7
-rw-r--r--crates/ide_db/src/lib.rs6
-rw-r--r--crates/ide_db/src/traits.rs227
-rw-r--r--crates/ide_db/src/ty_filter.rs58
-rw-r--r--crates/rust-analyzer/Cargo.toml1
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs8
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs8
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs2
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs4
-rw-r--r--crates/rust-analyzer/src/from_proto.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs2
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs4
-rw-r--r--crates/ssr/Cargo.toml1
-rw-r--r--crates/ssr/src/lib.rs8
-rw-r--r--crates/ssr/src/matching.rs2
-rw-r--r--crates/ssr/src/resolving.rs2
-rw-r--r--crates/ssr/src/search.rs4
-rw-r--r--crates/ssr/src/tests.rs6
-rw-r--r--crates/syntax/src/ast/node_ext.rs14
67 files changed, 421 insertions, 259 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7d9b2f9c1..efabcf2c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -50,7 +50,6 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
50name = "assists" 50name = "assists"
51version = "0.0.0" 51version = "0.0.0"
52dependencies = [ 52dependencies = [
53 "base_db",
54 "either", 53 "either",
55 "hir", 54 "hir",
56 "ide_db", 55 "ide_db",
@@ -128,20 +127,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
128checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 127checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
129 128
130[[package]] 129[[package]]
131name = "call_info"
132version = "0.0.0"
133dependencies = [
134 "base_db",
135 "either",
136 "expect-test",
137 "hir",
138 "ide_db",
139 "stdx",
140 "syntax",
141 "test_utils",
142]
143
144[[package]]
145name = "cargo_metadata" 130name = "cargo_metadata"
146version = "0.12.0" 131version = "0.12.0"
147source = "registry+https://github.com/rust-lang/crates.io-index" 132source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -268,9 +253,7 @@ dependencies = [
268name = "completion" 253name = "completion"
269version = "0.0.0" 254version = "0.0.0"
270dependencies = [ 255dependencies = [
271 "assists",
272 "base_db", 256 "base_db",
273 "call_info",
274 "expect-test", 257 "expect-test",
275 "hir", 258 "hir",
276 "ide_db", 259 "ide_db",
@@ -655,8 +638,6 @@ name = "ide"
655version = "0.0.0" 638version = "0.0.0"
656dependencies = [ 639dependencies = [
657 "assists", 640 "assists",
658 "base_db",
659 "call_info",
660 "cfg", 641 "cfg",
661 "completion", 642 "completion",
662 "either", 643 "either",
@@ -685,6 +666,7 @@ version = "0.0.0"
685dependencies = [ 666dependencies = [
686 "base_db", 667 "base_db",
687 "either", 668 "either",
669 "expect-test",
688 "fst", 670 "fst",
689 "hir", 671 "hir",
690 "log", 672 "log",
@@ -1356,7 +1338,6 @@ name = "rust-analyzer"
1356version = "0.0.0" 1338version = "0.0.0"
1357dependencies = [ 1339dependencies = [
1358 "anyhow", 1340 "anyhow",
1359 "base_db",
1360 "cfg", 1341 "cfg",
1361 "crossbeam-channel 0.5.0", 1342 "crossbeam-channel 0.5.0",
1362 "env_logger", 1343 "env_logger",
@@ -1614,7 +1595,6 @@ dependencies = [
1614name = "ssr" 1595name = "ssr"
1615version = "0.0.0" 1596version = "0.0.0"
1616dependencies = [ 1597dependencies = [
1617 "base_db",
1618 "expect-test", 1598 "expect-test",
1619 "hir", 1599 "hir",
1620 "ide_db", 1600 "ide_db",
diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml
index 264125651..108f656e9 100644
--- a/crates/assists/Cargo.toml
+++ b/crates/assists/Cargo.toml
@@ -18,7 +18,6 @@ stdx = { path = "../stdx", version = "0.0.0" }
18syntax = { path = "../syntax", version = "0.0.0" } 18syntax = { path = "../syntax", version = "0.0.0" }
19text_edit = { path = "../text_edit", version = "0.0.0" } 19text_edit = { path = "../text_edit", version = "0.0.0" }
20profile = { path = "../profile", version = "0.0.0" } 20profile = { path = "../profile", version = "0.0.0" }
21base_db = { path = "../base_db", version = "0.0.0" }
22ide_db = { path = "../ide_db", version = "0.0.0" } 21ide_db = { path = "../ide_db", version = "0.0.0" }
23hir = { path = "../hir", version = "0.0.0" } 22hir = { path = "../hir", version = "0.0.0" }
24test_utils = { path = "../test_utils", version = "0.0.0" } 23test_utils = { path = "../test_utils", version = "0.0.0" }
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs
index bf520069e..d11fee196 100644
--- a/crates/assists/src/assist_context.rs
+++ b/crates/assists/src/assist_context.rs
@@ -3,8 +3,8 @@
3use std::mem; 3use std::mem;
4 4
5use algo::find_covering_element; 5use algo::find_covering_element;
6use base_db::{FileId, FileRange};
7use hir::Semantics; 6use hir::Semantics;
7use ide_db::base_db::{FileId, FileRange};
8use ide_db::{ 8use ide_db::{
9 label::Label, 9 label::Label,
10 source_change::{SourceChange, SourceFileEdit}, 10 source_change::{SourceChange, SourceFileEdit},
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs
index 4c400f287..b82fb30ad 100644
--- a/crates/assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/assists/src/handlers/add_missing_impl_members.rs
@@ -1,4 +1,5 @@
1use hir::HasSource; 1use hir::HasSource;
2use ide_db::traits::{get_missing_assoc_items, resolve_target_trait};
2use syntax::{ 3use syntax::{
3 ast::{ 4 ast::{
4 self, 5 self,
@@ -11,7 +12,7 @@ use syntax::{
11use crate::{ 12use crate::{
12 assist_context::{AssistContext, Assists}, 13 assist_context::{AssistContext, Assists},
13 ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, 14 ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
14 utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor}, 15 utils::{render_snippet, Cursor},
15 AssistId, AssistKind, 16 AssistId, AssistKind,
16}; 17};
17 18
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 7f4f80b23..48433feb9 100644
--- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -1,5 +1,5 @@
1use base_db::FileId;
2use hir::{EnumVariant, Module, ModuleDef, Name}; 1use hir::{EnumVariant, Module, ModuleDef, Name};
2use ide_db::base_db::FileId;
3use ide_db::{defs::Definition, search::Reference, RootDatabase}; 3use ide_db::{defs::Definition, search::Reference, RootDatabase};
4use itertools::Itertools; 4use itertools::Itertools;
5use rustc_hash::FxHashSet; 5use rustc_hash::FxHashSet;
diff --git a/crates/assists/src/handlers/fix_visibility.rs b/crates/assists/src/handlers/fix_visibility.rs
index 66f74150c..c86720787 100644
--- a/crates/assists/src/handlers/fix_visibility.rs
+++ b/crates/assists/src/handlers/fix_visibility.rs
@@ -1,5 +1,5 @@
1use base_db::FileId;
2use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution}; 1use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
2use ide_db::base_db::FileId;
3use syntax::{ 3use syntax::{
4 ast::{self, VisibilityOwner}, 4 ast::{self, VisibilityOwner},
5 AstNode, TextRange, TextSize, 5 AstNode, TextRange, TextSize,
diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs
index d23f4293b..758188a42 100644
--- a/crates/assists/src/handlers/generate_function.rs
+++ b/crates/assists/src/handlers/generate_function.rs
@@ -1,5 +1,5 @@
1use base_db::FileId;
2use hir::HirDisplay; 1use hir::HirDisplay;
2use ide_db::base_db::FileId;
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::{FxHashMap, FxHashSet};
4use syntax::{ 4use syntax::{
5 ast::{ 5 ast::{
diff --git a/crates/assists/src/handlers/replace_if_let_with_match.rs b/crates/assists/src/handlers/replace_if_let_with_match.rs
index 79097621e..9a49c48c1 100644
--- a/crates/assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/assists/src/handlers/replace_if_let_with_match.rs
@@ -7,10 +7,8 @@ use syntax::{
7 AstNode, 7 AstNode,
8}; 8};
9 9
10use crate::{ 10use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};
11 utils::{unwrap_trivial_block, TryEnum}, 11use ide_db::ty_filter::TryEnum;
12 AssistContext, AssistId, AssistKind, Assists,
13};
14 12
15// Assist: replace_if_let_with_match 13// Assist: replace_if_let_with_match
16// 14//
diff --git a/crates/assists/src/handlers/replace_let_with_if_let.rs b/crates/assists/src/handlers/replace_let_with_if_let.rs
index ed6d0c29b..a5bcbda24 100644
--- a/crates/assists/src/handlers/replace_let_with_if_let.rs
+++ b/crates/assists/src/handlers/replace_let_with_if_let.rs
@@ -9,7 +9,8 @@ use syntax::{
9 AstNode, T, 9 AstNode, T,
10}; 10};
11 11
12use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists}; 12use crate::{AssistContext, AssistId, AssistKind, Assists};
13use ide_db::ty_filter::TryEnum;
13 14
14// Assist: replace_let_with_if_let 15// Assist: replace_let_with_if_let
15// 16//
diff --git a/crates/assists/src/handlers/replace_unwrap_with_match.rs b/crates/assists/src/handlers/replace_unwrap_with_match.rs
index 4043c219c..f547066f0 100644
--- a/crates/assists/src/handlers/replace_unwrap_with_match.rs
+++ b/crates/assists/src/handlers/replace_unwrap_with_match.rs
@@ -10,9 +10,10 @@ use syntax::{
10}; 10};
11 11
12use crate::{ 12use crate::{
13 utils::{render_snippet, Cursor, TryEnum}, 13 utils::{render_snippet, Cursor},
14 AssistContext, AssistId, AssistKind, Assists, 14 AssistContext, AssistId, AssistKind, Assists,
15}; 15};
16use ide_db::ty_filter::TryEnum;
16 17
17// Assist: replace_unwrap_with_match 18// Assist: replace_unwrap_with_match
18// 19//
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs
index 8a664f654..70a651e10 100644
--- a/crates/assists/src/lib.rs
+++ b/crates/assists/src/lib.rs
@@ -17,8 +17,8 @@ mod tests;
17pub mod utils; 17pub mod utils;
18pub mod ast_transform; 18pub mod ast_transform;
19 19
20use base_db::FileRange;
21use hir::Semantics; 20use hir::Semantics;
21use ide_db::base_db::FileRange;
22use ide_db::{label::Label, source_change::SourceChange, RootDatabase}; 22use ide_db::{label::Label, source_change::SourceChange, RootDatabase};
23use syntax::TextRange; 23use syntax::TextRange;
24 24
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs
index 2b687decf..849d85e76 100644
--- a/crates/assists/src/tests.rs
+++ b/crates/assists/src/tests.rs
@@ -1,7 +1,7 @@
1mod generated; 1mod generated;
2 2
3use base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
4use hir::Semantics; 3use hir::Semantics;
4use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
5use ide_db::RootDatabase; 5use ide_db::RootDatabase;
6use syntax::TextRange; 6use syntax::TextRange;
7use test_utils::{assert_eq_text, extract_offset, extract_range}; 7use test_utils::{assert_eq_text, extract_offset, extract_range};
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index 1a6b48b45..56f925ee6 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -2,14 +2,13 @@
2pub(crate) mod insert_use; 2pub(crate) mod insert_use;
3pub(crate) mod import_assets; 3pub(crate) mod import_assets;
4 4
5use std::{iter, ops}; 5use std::ops;
6 6
7use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type}; 7use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait};
8use ide_db::RootDatabase; 8use ide_db::RootDatabase;
9use itertools::Itertools; 9use itertools::Itertools;
10use rustc_hash::FxHashSet;
11use syntax::{ 10use syntax::{
12 ast::{self, make, ArgListOwner, NameOwner}, 11 ast::{self, make, ArgListOwner},
13 AstNode, Direction, 12 AstNode, Direction,
14 SyntaxKind::*, 13 SyntaxKind::*,
15 SyntaxNode, TextSize, T, 14 SyntaxNode, TextSize, T,
@@ -115,72 +114,6 @@ pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor
115 } 114 }
116} 115}
117 116
118pub fn get_missing_assoc_items(
119 sema: &Semantics<RootDatabase>,
120 impl_def: &ast::Impl,
121) -> Vec<hir::AssocItem> {
122 // Names must be unique between constants and functions. However, type aliases
123 // may share the same name as a function or constant.
124 let mut impl_fns_consts = FxHashSet::default();
125 let mut impl_type = FxHashSet::default();
126
127 if let Some(item_list) = impl_def.assoc_item_list() {
128 for item in item_list.assoc_items() {
129 match item {
130 ast::AssocItem::Fn(f) => {
131 if let Some(n) = f.name() {
132 impl_fns_consts.insert(n.syntax().to_string());
133 }
134 }
135
136 ast::AssocItem::TypeAlias(t) => {
137 if let Some(n) = t.name() {
138 impl_type.insert(n.syntax().to_string());
139 }
140 }
141
142 ast::AssocItem::Const(c) => {
143 if let Some(n) = c.name() {
144 impl_fns_consts.insert(n.syntax().to_string());
145 }
146 }
147 ast::AssocItem::MacroCall(_) => (),
148 }
149 }
150 }
151
152 resolve_target_trait(sema, impl_def).map_or(vec![], |target_trait| {
153 target_trait
154 .items(sema.db)
155 .iter()
156 .filter(|i| match i {
157 hir::AssocItem::Function(f) => {
158 !impl_fns_consts.contains(&f.name(sema.db).to_string())
159 }
160 hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db).to_string()),
161 hir::AssocItem::Const(c) => c
162 .name(sema.db)
163 .map(|n| !impl_fns_consts.contains(&n.to_string()))
164 .unwrap_or_default(),
165 })
166 .cloned()
167 .collect()
168 })
169}
170
171pub(crate) fn resolve_target_trait(
172 sema: &Semantics<RootDatabase>,
173 impl_def: &ast::Impl,
174) -> Option<hir::Trait> {
175 let ast_path =
176 impl_def.trait_().map(|it| it.syntax().clone()).and_then(ast::PathType::cast)?.path()?;
177
178 match sema.resolve_path(&ast_path) {
179 Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def),
180 _ => None,
181 }
182}
183
184pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize { 117pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
185 node.children_with_tokens() 118 node.children_with_tokens()
186 .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR)) 119 .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
@@ -223,54 +156,6 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
223 } 156 }
224} 157}
225 158
226#[derive(Clone, Copy)]
227pub enum TryEnum {
228 Result,
229 Option,
230}
231
232impl TryEnum {
233 const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
234
235 pub fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> {
236 let enum_ = match ty.as_adt() {
237 Some(Adt::Enum(it)) => it,
238 _ => return None,
239 };
240 TryEnum::ALL.iter().find_map(|&var| {
241 if &enum_.name(sema.db).to_string() == var.type_name() {
242 return Some(var);
243 }
244 None
245 })
246 }
247
248 pub(crate) fn happy_case(self) -> &'static str {
249 match self {
250 TryEnum::Result => "Ok",
251 TryEnum::Option => "Some",
252 }
253 }
254
255 pub(crate) fn sad_pattern(self) -> ast::Pat {
256 match self {
257 TryEnum::Result => make::tuple_struct_pat(
258 make::path_unqualified(make::path_segment(make::name_ref("Err"))),
259 iter::once(make::wildcard_pat().into()),
260 )
261 .into(),
262 TryEnum::Option => make::ident_pat(make::name("None")).into(),
263 }
264 }
265
266 fn type_name(self) -> &'static str {
267 match self {
268 TryEnum::Result => "Result",
269 TryEnum::Option => "Option",
270 }
271 }
272}
273
274/// Helps with finding well-know things inside the standard library. This is 159/// Helps with finding well-know things inside the standard library. This is
275/// somewhat similar to the known paths infra inside hir, but it different; We 160/// somewhat similar to the known paths infra inside hir, but it different; We
276/// want to make sure that IDE specific paths don't become interesting inside 161/// want to make sure that IDE specific paths don't become interesting inside
diff --git a/crates/call_info/Cargo.toml b/crates/call_info/Cargo.toml
deleted file mode 100644
index 98c0bd6db..000000000
--- a/crates/call_info/Cargo.toml
+++ /dev/null
@@ -1,26 +0,0 @@
1[package]
2name = "call_info"
3version = "0.0.0"
4description = "TBD"
5license = "MIT OR Apache-2.0"
6authors = ["rust-analyzer developers"]
7edition = "2018"
8
9[lib]
10doctest = false
11
12[dependencies]
13either = "1.5.3"
14
15stdx = { path = "../stdx", version = "0.0.0" }
16syntax = { path = "../syntax", version = "0.0.0" }
17base_db = { path = "../base_db", version = "0.0.0" }
18ide_db = { path = "../ide_db", version = "0.0.0" }
19test_utils = { path = "../test_utils", version = "0.0.0" }
20
21# call_info crate should depend only on the top-level `hir` package. if you need
22# something from some `hir_xxx` subpackage, reexport the API via `hir`.
23hir = { path = "../hir", version = "0.0.0" }
24
25[dev-dependencies]
26expect-test = "1.0"
diff --git a/crates/completion/Cargo.toml b/crates/completion/Cargo.toml
index 25192456a..b79ee33f7 100644
--- a/crates/completion/Cargo.toml
+++ b/crates/completion/Cargo.toml
@@ -21,8 +21,6 @@ base_db = { path = "../base_db", version = "0.0.0" }
21ide_db = { path = "../ide_db", version = "0.0.0" } 21ide_db = { path = "../ide_db", version = "0.0.0" }
22profile = { path = "../profile", version = "0.0.0" } 22profile = { path = "../profile", version = "0.0.0" }
23test_utils = { path = "../test_utils", version = "0.0.0" } 23test_utils = { path = "../test_utils", version = "0.0.0" }
24assists = { path = "../assists", version = "0.0.0" }
25call_info = { path = "../call_info", version = "0.0.0" }
26 24
27# completions crate should depend only on the top-level `hir` package. if you need 25# completions crate should depend only on the top-level `hir` package. if you need
28# something from some `hir_xxx` subpackage, reexport the API via `hir`. 26# something from some `hir_xxx` subpackage, reexport the API via `hir`.
diff --git a/crates/completion/src/complete_mod.rs b/crates/completion/src/complete_mod.rs
index 35a57aba3..385911afa 100644
--- a/crates/completion/src/complete_mod.rs
+++ b/crates/completion/src/complete_mod.rs
@@ -1,7 +1,7 @@
1//! Completes mod declarations. 1//! Completes mod declarations.
2 2
3use base_db::{SourceDatabaseExt, VfsPath};
4use hir::{Module, ModuleSource}; 3use hir::{Module, ModuleSource};
4use ide_db::base_db::{SourceDatabaseExt, VfsPath};
5use ide_db::RootDatabase; 5use ide_db::RootDatabase;
6use rustc_hash::FxHashSet; 6use rustc_hash::FxHashSet;
7 7
diff --git a/crates/completion/src/complete_postfix.rs b/crates/completion/src/complete_postfix.rs
index 700573cf2..2622f12ab 100644
--- a/crates/completion/src/complete_postfix.rs
+++ b/crates/completion/src/complete_postfix.rs
@@ -2,7 +2,7 @@
2 2
3mod format_like; 3mod format_like;
4 4
5use assists::utils::TryEnum; 5use ide_db::ty_filter::TryEnum;
6use syntax::{ 6use syntax::{
7 ast::{self, AstNode, AstToken}, 7 ast::{self, AstNode, AstToken},
8 TextRange, TextSize, 8 TextRange, TextSize,
diff --git a/crates/completion/src/complete_trait_impl.rs b/crates/completion/src/complete_trait_impl.rs
index c06af99e2..a14be9c73 100644
--- a/crates/completion/src/complete_trait_impl.rs
+++ b/crates/completion/src/complete_trait_impl.rs
@@ -31,8 +31,8 @@
31//! } 31//! }
32//! ``` 32//! ```
33 33
34use assists::utils::get_missing_assoc_items;
35use hir::{self, HasAttrs, HasSource}; 34use hir::{self, HasAttrs, HasSource};
35use ide_db::traits::get_missing_assoc_items;
36use syntax::{ 36use syntax::{
37 ast::{self, edit, Impl}, 37 ast::{self, edit, Impl},
38 display::function_declaration, 38 display::function_declaration,
diff --git a/crates/completion/src/completion_context.rs b/crates/completion/src/completion_context.rs
index e4f86d0e0..dca304a8f 100644
--- a/crates/completion/src/completion_context.rs
+++ b/crates/completion/src/completion_context.rs
@@ -1,9 +1,8 @@
1//! See `CompletionContext` structure. 1//! See `CompletionContext` structure.
2 2
3use base_db::{FilePosition, SourceDatabase};
4use call_info::ActiveParameter;
5use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; 3use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
6use ide_db::RootDatabase; 4use ide_db::base_db::{FilePosition, SourceDatabase};
5use ide_db::{call_info::ActiveParameter, RootDatabase};
7use syntax::{ 6use syntax::{
8 algo::{find_covering_element, find_node_at_offset}, 7 algo::{find_covering_element, find_node_at_offset},
9 ast, match_ast, AstNode, NodeOrToken, 8 ast, match_ast, AstNode, NodeOrToken,
diff --git a/crates/completion/src/lib.rs b/crates/completion/src/lib.rs
index 0a60ea7f2..b72fd249d 100644
--- a/crates/completion/src/lib.rs
+++ b/crates/completion/src/lib.rs
@@ -23,7 +23,7 @@ mod complete_macro_in_item_position;
23mod complete_trait_impl; 23mod complete_trait_impl;
24mod complete_mod; 24mod complete_mod;
25 25
26use base_db::FilePosition; 26use ide_db::base_db::FilePosition;
27use ide_db::RootDatabase; 27use ide_db::RootDatabase;
28 28
29use crate::{ 29use crate::{
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs
index f2cf2561f..b02556797 100644
--- a/crates/completion/src/test_utils.rs
+++ b/crates/completion/src/test_utils.rs
@@ -1,7 +1,7 @@
1//! Runs completion for testing purposes. 1//! Runs completion for testing purposes.
2 2
3use base_db::{fixture::ChangeFixture, FileLoader, FilePosition};
4use hir::Semantics; 3use hir::Semantics;
4use ide_db::base_db::{fixture::ChangeFixture, FileLoader, FilePosition};
5use ide_db::RootDatabase; 5use ide_db::RootDatabase;
6use itertools::Itertools; 6use itertools::Itertools;
7use stdx::{format_to, trim_indent}; 7use stdx::{format_to, trim_indent};
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 76b52fa04..4d483580d 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -23,14 +23,12 @@ url = "2.1.1"
23stdx = { path = "../stdx", version = "0.0.0" } 23stdx = { path = "../stdx", version = "0.0.0" }
24syntax = { path = "../syntax", version = "0.0.0" } 24syntax = { path = "../syntax", version = "0.0.0" }
25text_edit = { path = "../text_edit", version = "0.0.0" } 25text_edit = { path = "../text_edit", version = "0.0.0" }
26base_db = { path = "../base_db", version = "0.0.0" }
27ide_db = { path = "../ide_db", version = "0.0.0" } 26ide_db = { path = "../ide_db", version = "0.0.0" }
28cfg = { path = "../cfg", version = "0.0.0" } 27cfg = { path = "../cfg", version = "0.0.0" }
29profile = { path = "../profile", version = "0.0.0" } 28profile = { path = "../profile", version = "0.0.0" }
30test_utils = { path = "../test_utils", version = "0.0.0" } 29test_utils = { path = "../test_utils", version = "0.0.0" }
31assists = { path = "../assists", version = "0.0.0" } 30assists = { path = "../assists", version = "0.0.0" }
32ssr = { path = "../ssr", version = "0.0.0" } 31ssr = { path = "../ssr", version = "0.0.0" }
33call_info = { path = "../call_info", version = "0.0.0" }
34completion = { path = "../completion", version = "0.0.0" } 32completion = { path = "../completion", version = "0.0.0" }
35 33
36# ide should depend only on the top-level `hir` package. if you need 34# ide should depend only on the top-level `hir` package. if you need
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs
index 9d6433fe0..8ad50a2ee 100644
--- a/crates/ide/src/call_hierarchy.rs
+++ b/crates/ide/src/call_hierarchy.rs
@@ -2,8 +2,8 @@
2 2
3use indexmap::IndexMap; 3use indexmap::IndexMap;
4 4
5use call_info::FnCallNode;
6use hir::Semantics; 5use hir::Semantics;
6use ide_db::call_info::FnCallNode;
7use ide_db::RootDatabase; 7use ide_db::RootDatabase;
8use syntax::{ast, match_ast, AstNode, TextRange}; 8use syntax::{ast, match_ast, AstNode, TextRange};
9 9
@@ -137,7 +137,7 @@ impl CallLocations {
137 137
138#[cfg(test)] 138#[cfg(test)]
139mod tests { 139mod tests {
140 use base_db::FilePosition; 140 use ide_db::base_db::FilePosition;
141 141
142 use crate::fixture; 142 use crate::fixture;
143 143
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index 232074c3d..d0ee58858 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -9,11 +9,11 @@ mod field_shorthand;
9 9
10use std::cell::RefCell; 10use std::cell::RefCell;
11 11
12use base_db::SourceDatabase;
13use hir::{ 12use hir::{
14 diagnostics::{Diagnostic as _, DiagnosticSinkBuilder}, 13 diagnostics::{Diagnostic as _, DiagnosticSinkBuilder},
15 Semantics, 14 Semantics,
16}; 15};
16use ide_db::base_db::SourceDatabase;
17use ide_db::RootDatabase; 17use ide_db::RootDatabase;
18use itertools::Itertools; 18use itertools::Itertools;
19use rustc_hash::FxHashSet; 19use rustc_hash::FxHashSet;
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs
index 54e9fce9e..f41bcd619 100644
--- a/crates/ide/src/diagnostics/field_shorthand.rs
+++ b/crates/ide/src/diagnostics/field_shorthand.rs
@@ -1,7 +1,7 @@
1//! Suggests shortening `Foo { field: field }` to `Foo { field }` in both 1//! Suggests shortening `Foo { field: field }` to `Foo { field }` in both
2//! expressions and patterns. 2//! expressions and patterns.
3 3
4use base_db::FileId; 4use ide_db::base_db::FileId;
5use ide_db::source_change::SourceFileEdit; 5use ide_db::source_change::SourceFileEdit;
6use syntax::{ast, match_ast, AstNode, SyntaxNode}; 6use syntax::{ast, match_ast, AstNode, SyntaxNode};
7use text_edit::TextEdit; 7use text_edit::TextEdit;
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs
index 0c75e50b0..0c950003e 100644
--- a/crates/ide/src/diagnostics/fixes.rs
+++ b/crates/ide/src/diagnostics/fixes.rs
@@ -1,6 +1,5 @@
1//! Provides a way to attach fixes to the diagnostics. 1//! Provides a way to attach fixes to the diagnostics.
2//! The same module also has all curret custom fixes for the diagnostics implemented. 2//! The same module also has all curret custom fixes for the diagnostics implemented.
3use base_db::FileId;
4use hir::{ 3use hir::{
5 db::AstDatabase, 4 db::AstDatabase,
6 diagnostics::{ 5 diagnostics::{
@@ -9,6 +8,7 @@ use hir::{
9 }, 8 },
10 HasSource, HirDisplay, Semantics, VariantDef, 9 HasSource, HirDisplay, Semantics, VariantDef,
11}; 10};
11use ide_db::base_db::FileId;
12use ide_db::{ 12use ide_db::{
13 source_change::{FileSystemEdit, SourceFileEdit}, 13 source_change::{FileSystemEdit, SourceFileEdit},
14 RootDatabase, 14 RootDatabase,
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index cf9d617dc..0c429a262 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -1,8 +1,8 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use base_db::{FileId, SourceDatabase};
4use either::Either; 3use either::Either;
5use hir::{original_range, AssocItem, FieldSource, HasSource, InFile, ModuleSource}; 4use hir::{original_range, AssocItem, FieldSource, HasSource, InFile, ModuleSource};
5use ide_db::base_db::{FileId, SourceDatabase};
6use ide_db::{defs::Definition, RootDatabase}; 6use ide_db::{defs::Definition, RootDatabase};
7use syntax::{ 7use syntax::{
8 ast::{self, DocCommentsOwner, NameOwner}, 8 ast::{self, DocCommentsOwner, NameOwner},
diff --git a/crates/ide/src/fixture.rs b/crates/ide/src/fixture.rs
index ed06689f0..eb57f9224 100644
--- a/crates/ide/src/fixture.rs
+++ b/crates/ide/src/fixture.rs
@@ -1,5 +1,5 @@
1//! Utilities for creating `Analysis` instances for tests. 1//! Utilities for creating `Analysis` instances for tests.
2use base_db::fixture::ChangeFixture; 2use ide_db::base_db::fixture::ChangeFixture;
3use test_utils::{extract_annotations, RangeOrOffset}; 3use test_utils::{extract_annotations, RangeOrOffset};
4 4
5use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; 5use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index a87e31019..15792f947 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -100,7 +100,7 @@ pub(crate) fn reference_definition(
100 100
101#[cfg(test)] 101#[cfg(test)]
102mod tests { 102mod tests {
103 use base_db::FileRange; 103 use ide_db::base_db::FileRange;
104 use syntax::{TextRange, TextSize}; 104 use syntax::{TextRange, TextSize};
105 105
106 use crate::fixture; 106 use crate::fixture;
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 6c586bbd1..529004878 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -74,7 +74,7 @@ fn impls_for_trait(
74 74
75#[cfg(test)] 75#[cfg(test)]
76mod tests { 76mod tests {
77 use base_db::FileRange; 77 use ide_db::base_db::FileRange;
78 78
79 use crate::fixture; 79 use crate::fixture;
80 80
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs
index 6d0df04dd..aba6bf5dc 100644
--- a/crates/ide/src/goto_type_definition.rs
+++ b/crates/ide/src/goto_type_definition.rs
@@ -54,7 +54,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
54 54
55#[cfg(test)] 55#[cfg(test)]
56mod tests { 56mod tests {
57 use base_db::FileRange; 57 use ide_db::base_db::FileRange;
58 58
59 use crate::fixture; 59 use crate::fixture;
60 60
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 0332c7be0..832192881 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -1,8 +1,8 @@
1use base_db::SourceDatabase;
2use hir::{ 1use hir::{
3 Adt, AsAssocItem, AssocItemContainer, Documentation, FieldSource, HasSource, HirDisplay, 2 Adt, AsAssocItem, AssocItemContainer, Documentation, FieldSource, HasSource, HirDisplay,
4 Module, ModuleDef, ModuleSource, Semantics, 3 Module, ModuleDef, ModuleSource, Semantics,
5}; 4};
5use ide_db::base_db::SourceDatabase;
6use ide_db::{ 6use ide_db::{
7 defs::{Definition, NameClass, NameRefClass}, 7 defs::{Definition, NameClass, NameRefClass},
8 RootDatabase, 8 RootDatabase,
@@ -385,8 +385,8 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
385 385
386#[cfg(test)] 386#[cfg(test)]
387mod tests { 387mod tests {
388 use base_db::FileLoader;
389 use expect_test::{expect, Expect}; 388 use expect_test::{expect, Expect};
389 use ide_db::base_db::FileLoader;
390 390
391 use crate::fixture; 391 use crate::fixture;
392 392
@@ -638,6 +638,33 @@ fn main() { }
638 } 638 }
639 639
640 #[test] 640 #[test]
641 fn hover_shows_fn_doc_attr_raw_string() {
642 check(
643 r##"
644#[doc = r#"Raw string doc attr"#]
645pub fn foo<|>(_: &Path) {}
646
647fn main() { }
648"##,
649 expect![[r##"
650 *foo*
651
652 ```rust
653 test
654 ```
655
656 ```rust
657 pub fn foo(_: &Path)
658 ```
659
660 ---
661
662 Raw string doc attr
663 "##]],
664 );
665 }
666
667 #[test]
641 fn hover_shows_struct_field_info() { 668 fn hover_shows_struct_field_info() {
642 // Hovering over the field when instantiating 669 // Hovering over the field when instantiating
643 check( 670 check(
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index cecfae4c7..4bc733b70 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -48,11 +48,11 @@ mod doc_links;
48 48
49use std::sync::Arc; 49use std::sync::Arc;
50 50
51use base_db::{ 51use cfg::CfgOptions;
52use ide_db::base_db::{
52 salsa::{self, ParallelDatabase}, 53 salsa::{self, ParallelDatabase},
53 CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath, 54 CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath,
54}; 55};
55use cfg::CfgOptions;
56use ide_db::{ 56use ide_db::{
57 symbol_index::{self, FileSymbol}, 57 symbol_index::{self, FileSymbol},
58 LineIndexDatabase, 58 LineIndexDatabase,
@@ -80,19 +80,19 @@ pub use crate::{
80 Highlight, HighlightModifier, HighlightModifiers, HighlightTag, HighlightedRange, 80 Highlight, HighlightModifier, HighlightModifiers, HighlightTag, HighlightedRange,
81 }, 81 },
82}; 82};
83pub use call_info::CallInfo;
84pub use completion::{ 83pub use completion::{
85 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, 84 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
86}; 85};
86pub use ide_db::call_info::CallInfo;
87 87
88pub use assists::{ 88pub use assists::{
89 utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, 89 utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist,
90}; 90};
91pub use base_db::{ 91pub use hir::{Documentation, Semantics};
92pub use ide_db::base_db::{
92 Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, 93 Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot,
93 SourceRootId, 94 SourceRootId,
94}; 95};
95pub use hir::{Documentation, Semantics};
96pub use ide_db::{ 96pub use ide_db::{
97 label::Label, 97 label::Label,
98 line_index::{LineCol, LineIndex}, 98 line_index::{LineCol, LineIndex},
@@ -396,7 +396,7 @@ impl Analysis {
396 396
397 /// Computes parameter information for the given call expression. 397 /// Computes parameter information for the given call expression.
398 pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> { 398 pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> {
399 self.with_db(|db| call_info::call_info(db, position)) 399 self.with_db(|db| ide_db::call_info::call_info(db, position))
400 } 400 }
401 401
402 /// Computes call hierarchy candidates for the given file position. 402 /// Computes call hierarchy candidates for the given file position.
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs
index ef94acfec..6cc3b2991 100644
--- a/crates/ide/src/parent_module.rs
+++ b/crates/ide/src/parent_module.rs
@@ -1,5 +1,5 @@
1use base_db::{CrateId, FileId, FilePosition};
2use hir::Semantics; 1use hir::Semantics;
2use ide_db::base_db::{CrateId, FileId, FilePosition};
3use ide_db::RootDatabase; 3use ide_db::RootDatabase;
4use syntax::{ 4use syntax::{
5 algo::find_node_at_offset, 5 algo::find_node_at_offset,
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs
index 6944dbcd2..ea0acfaa0 100644
--- a/crates/ide/src/prime_caches.rs
+++ b/crates/ide/src/prime_caches.rs
@@ -3,8 +3,8 @@
3//! request takes longer to compute. This modules implemented prepopulating of 3//! request takes longer to compute. This modules implemented prepopulating of
4//! various caches, it's not really advanced at the moment. 4//! various caches, it's not really advanced at the moment.
5 5
6use base_db::SourceDatabase;
7use hir::db::DefDatabase; 6use hir::db::DefDatabase;
7use ide_db::base_db::SourceDatabase;
8 8
9use crate::RootDatabase; 9use crate::RootDatabase;
10 10
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 67ec257a8..a517081d5 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -191,8 +191,8 @@ fn get_struct_def_name_for_struct_literal_search(
191 191
192#[cfg(test)] 192#[cfg(test)]
193mod tests { 193mod tests {
194 use base_db::FileId;
195 use expect_test::{expect, Expect}; 194 use expect_test::{expect, Expect};
195 use ide_db::base_db::FileId;
196 use stdx::format_to; 196 use stdx::format_to;
197 197
198 use crate::{fixture, SearchScope}; 198 use crate::{fixture, SearchScope};
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 35aafc49d..26ac2371a 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use base_db::SourceDatabaseExt;
4use hir::{Module, ModuleDef, ModuleSource, Semantics}; 3use hir::{Module, ModuleDef, ModuleSource, Semantics};
4use ide_db::base_db::SourceDatabaseExt;
5use ide_db::{ 5use ide_db::{
6 defs::{Definition, NameClass, NameRefClass}, 6 defs::{Definition, NameClass, NameRefClass},
7 RootDatabase, 7 RootDatabase,
diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs
index 0af84daa0..8e91c99d7 100644
--- a/crates/ide/src/status.rs
+++ b/crates/ide/src/status.rs
@@ -1,10 +1,10 @@
1use std::{fmt, iter::FromIterator, sync::Arc}; 1use std::{fmt, iter::FromIterator, sync::Arc};
2 2
3use base_db::{ 3use hir::MacroFile;
4use ide_db::base_db::{
4 salsa::debug::{DebugQueryTable, TableEntry}, 5 salsa::debug::{DebugQueryTable, TableEntry},
5 CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId, 6 CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId,
6}; 7};
7use hir::MacroFile;
8use ide_db::{ 8use ide_db::{
9 symbol_index::{LibrarySymbolsQuery, SymbolIndex}, 9 symbol_index::{LibrarySymbolsQuery, SymbolIndex},
10 RootDatabase, 10 RootDatabase,
@@ -16,7 +16,7 @@ use stdx::format_to;
16use syntax::{ast, Parse, SyntaxNode}; 16use syntax::{ast, Parse, SyntaxNode};
17 17
18fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { 18fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
19 base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>() 19 ide_db::base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
20} 20}
21fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { 21fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
22 hir::db::ParseMacroQuery.in_db(db).entries::<SyntaxTreeStats>() 22 hir::db::ParseMacroQuery.in_db(db).entries::<SyntaxTreeStats>()
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs
index 57e2d2923..abcc5cccc 100644
--- a/crates/ide/src/syntax_highlighting/html.rs
+++ b/crates/ide/src/syntax_highlighting/html.rs
@@ -1,6 +1,6 @@
1//! Renders a bit of code as HTML. 1//! Renders a bit of code as HTML.
2 2
3use base_db::SourceDatabase; 3use ide_db::base_db::SourceDatabase;
4use oorandom::Rand32; 4use oorandom::Rand32;
5use stdx::format_to; 5use stdx::format_to;
6use syntax::{AstNode, TextRange, TextSize}; 6use syntax::{AstNode, TextRange, TextSize};
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs
index acd91b26c..59a74bc02 100644
--- a/crates/ide/src/syntax_highlighting/injection.rs
+++ b/crates/ide/src/syntax_highlighting/injection.rs
@@ -3,8 +3,8 @@
3use std::{collections::BTreeMap, convert::TryFrom}; 3use std::{collections::BTreeMap, convert::TryFrom};
4 4
5use ast::{HasQuotes, HasStringValue}; 5use ast::{HasQuotes, HasStringValue};
6use call_info::ActiveParameter;
7use hir::Semantics; 6use hir::Semantics;
7use ide_db::call_info::ActiveParameter;
8use itertools::Itertools; 8use itertools::Itertools;
9use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; 9use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
10 10
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs
index 0eed2dbd7..7941610d6 100644
--- a/crates/ide/src/syntax_tree.rs
+++ b/crates/ide/src/syntax_tree.rs
@@ -1,4 +1,4 @@
1use base_db::{FileId, SourceDatabase}; 1use ide_db::base_db::{FileId, SourceDatabase};
2use ide_db::RootDatabase; 2use ide_db::RootDatabase;
3use syntax::{ 3use syntax::{
4 algo, AstNode, NodeOrToken, SourceFile, 4 algo, AstNode, NodeOrToken, SourceFile,
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs
index 94b91f049..43458a3a2 100644
--- a/crates/ide/src/typing.rs
+++ b/crates/ide/src/typing.rs
@@ -15,7 +15,7 @@
15 15
16mod on_enter; 16mod on_enter;
17 17
18use base_db::{FilePosition, SourceDatabase}; 18use ide_db::base_db::{FilePosition, SourceDatabase};
19use ide_db::{source_change::SourceFileEdit, RootDatabase}; 19use ide_db::{source_change::SourceFileEdit, RootDatabase};
20use syntax::{ 20use syntax::{
21 algo::find_node_at_offset, 21 algo::find_node_at_offset,
diff --git a/crates/ide/src/typing/on_enter.rs b/crates/ide/src/typing/on_enter.rs
index 98adef1d6..f4ea30352 100644
--- a/crates/ide/src/typing/on_enter.rs
+++ b/crates/ide/src/typing/on_enter.rs
@@ -1,7 +1,7 @@
1//! Handles the `Enter` key press. At the momently, this only continues 1//! Handles the `Enter` key press. At the momently, this only continues
2//! comments, but should handle indent some time in the future as well. 2//! comments, but should handle indent some time in the future as well.
3 3
4use base_db::{FilePosition, SourceDatabase}; 4use ide_db::base_db::{FilePosition, SourceDatabase};
5use ide_db::RootDatabase; 5use ide_db::RootDatabase;
6use syntax::{ 6use syntax::{
7 ast::{self, AstToken}, 7 ast::{self, AstToken},
diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml
index 62c5a29ae..72a9212f1 100644
--- a/crates/ide_db/Cargo.toml
+++ b/crates/ide_db/Cargo.toml
@@ -29,3 +29,6 @@ test_utils = { path = "../test_utils", version = "0.0.0" }
29# ide should depend only on the top-level `hir` package. if you need 29# ide should depend only on the top-level `hir` package. if you need
30# something from some `hir_xxx` subpackage, reexport the API via `hir`. 30# something from some `hir_xxx` subpackage, reexport the API via `hir`.
31hir = { path = "../hir", version = "0.0.0" } 31hir = { path = "../hir", version = "0.0.0" }
32
33[dev-dependencies]
34expect-test = "1.0"
diff --git a/crates/call_info/src/lib.rs b/crates/ide_db/src/call_info.rs
index c45406c25..83a602b9a 100644
--- a/crates/call_info/src/lib.rs
+++ b/crates/ide_db/src/call_info.rs
@@ -2,7 +2,6 @@
2use base_db::FilePosition; 2use base_db::FilePosition;
3use either::Either; 3use either::Either;
4use hir::{HasAttrs, HirDisplay, Semantics, Type}; 4use hir::{HasAttrs, HirDisplay, Semantics, Type};
5use ide_db::RootDatabase;
6use stdx::format_to; 5use stdx::format_to;
7use syntax::{ 6use syntax::{
8 ast::{self, ArgListOwner}, 7 ast::{self, ArgListOwner},
@@ -10,6 +9,8 @@ use syntax::{
10}; 9};
11use test_utils::mark; 10use test_utils::mark;
12 11
12use crate::RootDatabase;
13
13/// Contains information about a call site. Specifically the 14/// Contains information about a call site. Specifically the
14/// `FunctionSignature`and current parameter. 15/// `FunctionSignature`and current parameter.
15#[derive(Debug)] 16#[derive(Debug)]
@@ -228,9 +229,9 @@ impl FnCallNode {
228 229
229#[cfg(test)] 230#[cfg(test)]
230mod tests { 231mod tests {
232 use crate::RootDatabase;
231 use base_db::{fixture::ChangeFixture, FilePosition}; 233 use base_db::{fixture::ChangeFixture, FilePosition};
232 use expect_test::{expect, Expect}; 234 use expect_test::{expect, Expect};
233 use ide_db::RootDatabase;
234 use test_utils::{mark, RangeOrOffset}; 235 use test_utils::{mark, RangeOrOffset};
235 236
236 /// Creates analysis from a multi-file fixture, returns positions marked with <|>. 237 /// Creates analysis from a multi-file fixture, returns positions marked with <|>.
@@ -249,7 +250,7 @@ mod tests {
249 250
250 fn check(ra_fixture: &str, expect: Expect) { 251 fn check(ra_fixture: &str, expect: Expect) {
251 let (db, position) = position(ra_fixture); 252 let (db, position) = position(ra_fixture);
252 let call_info = crate::call_info(&db, position); 253 let call_info = crate::call_info::call_info(&db, position);
253 let actual = match call_info { 254 let actual = match call_info {
254 Some(call_info) => { 255 Some(call_info) => {
255 let docs = match &call_info.doc { 256 let docs = match &call_info.doc {
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs
index 7eff247c7..38ebdbf79 100644
--- a/crates/ide_db/src/lib.rs
+++ b/crates/ide_db/src/lib.rs
@@ -10,6 +10,9 @@ pub mod defs;
10pub mod search; 10pub mod search;
11pub mod imports_locator; 11pub mod imports_locator;
12pub mod source_change; 12pub mod source_change;
13pub mod ty_filter;
14pub mod traits;
15pub mod call_info;
13 16
14use std::{fmt, sync::Arc}; 17use std::{fmt, sync::Arc};
15 18
@@ -23,6 +26,9 @@ use rustc_hash::FxHashSet;
23 26
24use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; 27use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
25 28
29/// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience.
30pub use base_db;
31
26#[salsa::database( 32#[salsa::database(
27 base_db::SourceDatabaseStorage, 33 base_db::SourceDatabaseStorage,
28 base_db::SourceDatabaseExtStorage, 34 base_db::SourceDatabaseExtStorage,
diff --git a/crates/ide_db/src/traits.rs b/crates/ide_db/src/traits.rs
new file mode 100644
index 000000000..f57b6dd91
--- /dev/null
+++ b/crates/ide_db/src/traits.rs
@@ -0,0 +1,227 @@
1//! Functionality for obtaining data related to traits from the DB.
2
3use crate::RootDatabase;
4use hir::Semantics;
5use rustc_hash::FxHashSet;
6use syntax::{
7 ast::{self, NameOwner},
8 AstNode,
9};
10
11/// Given the `impl` block, attempts to find the trait this `impl` corresponds to.
12pub fn resolve_target_trait(
13 sema: &Semantics<RootDatabase>,
14 impl_def: &ast::Impl,
15) -> Option<hir::Trait> {
16 let ast_path =
17 impl_def.trait_().map(|it| it.syntax().clone()).and_then(ast::PathType::cast)?.path()?;
18
19 match sema.resolve_path(&ast_path) {
20 Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def),
21 _ => None,
22 }
23}
24
25/// Given the `impl` block, returns the list of associated items (e.g. functions or types) that are
26/// missing in this `impl` block.
27pub fn get_missing_assoc_items(
28 sema: &Semantics<RootDatabase>,
29 impl_def: &ast::Impl,
30) -> Vec<hir::AssocItem> {
31 // Names must be unique between constants and functions. However, type aliases
32 // may share the same name as a function or constant.
33 let mut impl_fns_consts = FxHashSet::default();
34 let mut impl_type = FxHashSet::default();
35
36 if let Some(item_list) = impl_def.assoc_item_list() {
37 for item in item_list.assoc_items() {
38 match item {
39 ast::AssocItem::Fn(f) => {
40 if let Some(n) = f.name() {
41 impl_fns_consts.insert(n.syntax().to_string());
42 }
43 }
44
45 ast::AssocItem::TypeAlias(t) => {
46 if let Some(n) = t.name() {
47 impl_type.insert(n.syntax().to_string());
48 }
49 }
50
51 ast::AssocItem::Const(c) => {
52 if let Some(n) = c.name() {
53 impl_fns_consts.insert(n.syntax().to_string());
54 }
55 }
56 ast::AssocItem::MacroCall(_) => (),
57 }
58 }
59 }
60
61 resolve_target_trait(sema, impl_def).map_or(vec![], |target_trait| {
62 target_trait
63 .items(sema.db)
64 .iter()
65 .filter(|i| match i {
66 hir::AssocItem::Function(f) => {
67 !impl_fns_consts.contains(&f.name(sema.db).to_string())
68 }
69 hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db).to_string()),
70 hir::AssocItem::Const(c) => c
71 .name(sema.db)
72 .map(|n| !impl_fns_consts.contains(&n.to_string()))
73 .unwrap_or_default(),
74 })
75 .cloned()
76 .collect()
77 })
78}
79
80#[cfg(test)]
81mod tests {
82 use crate::RootDatabase;
83 use base_db::{fixture::ChangeFixture, FilePosition};
84 use expect_test::{expect, Expect};
85 use hir::Semantics;
86 use syntax::ast::{self, AstNode};
87 use test_utils::RangeOrOffset;
88
89 /// Creates analysis from a multi-file fixture, returns positions marked with <|>.
90 pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
91 let change_fixture = ChangeFixture::parse(ra_fixture);
92 let mut database = RootDatabase::default();
93 database.apply_change(change_fixture.change);
94 let (file_id, range_or_offset) =
95 change_fixture.file_position.expect("expected a marker (<|>)");
96 let offset = match range_or_offset {
97 RangeOrOffset::Range(_) => panic!(),
98 RangeOrOffset::Offset(it) => it,
99 };
100 (database, FilePosition { file_id, offset })
101 }
102
103 fn check_trait(ra_fixture: &str, expect: Expect) {
104 let (db, position) = position(ra_fixture);
105 let sema = Semantics::new(&db);
106 let file = sema.parse(position.file_id);
107 let impl_block: ast::Impl =
108 sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
109 let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
110 let actual = match trait_ {
111 Some(trait_) => trait_.name(&db).to_string(),
112 None => String::new(),
113 };
114 expect.assert_eq(&actual);
115 }
116
117 fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
118 let (db, position) = position(ra_fixture);
119 let sema = Semantics::new(&db);
120 let file = sema.parse(position.file_id);
121 let impl_block: ast::Impl =
122 sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
123 let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
124 let actual = items
125 .into_iter()
126 .map(|item| item.name(&db).unwrap().to_string())
127 .collect::<Vec<_>>()
128 .join("\n");
129 expect.assert_eq(&actual);
130 }
131
132 #[test]
133 fn resolve_trait() {
134 check_trait(
135 r#"
136pub trait Foo {
137 fn bar();
138}
139impl Foo for u8 {
140 <|>
141}
142 "#,
143 expect![["Foo"]],
144 );
145 check_trait(
146 r#"
147pub trait Foo {
148 fn bar();
149}
150impl Foo for u8 {
151 fn bar() {
152 fn baz() {
153 <|>
154 }
155 baz();
156 }
157}
158 "#,
159 expect![["Foo"]],
160 );
161 check_trait(
162 r#"
163pub trait Foo {
164 fn bar();
165}
166pub struct Bar;
167impl Bar {
168 <|>
169}
170 "#,
171 expect![[""]],
172 );
173 }
174
175 #[test]
176 fn missing_assoc_items() {
177 check_missing_assoc(
178 r#"
179pub trait Foo {
180 const FOO: u8;
181 fn bar();
182}
183impl Foo for u8 {
184 <|>
185}"#,
186 expect![[r#"
187 FOO
188 bar"#]],
189 );
190
191 check_missing_assoc(
192 r#"
193pub trait Foo {
194 const FOO: u8;
195 fn bar();
196}
197impl Foo for u8 {
198 const FOO: u8 = 10;
199 <|>
200}"#,
201 expect![[r#"
202 bar"#]],
203 );
204
205 check_missing_assoc(
206 r#"
207pub trait Foo {
208 const FOO: u8;
209 fn bar();
210}
211impl Foo for u8 {
212 const FOO: u8 = 10;
213 fn bar() {<|>}
214}"#,
215 expect![[r#""#]],
216 );
217
218 check_missing_assoc(
219 r#"
220pub struct Foo;
221impl Foo {
222 fn bar() {<|>}
223}"#,
224 expect![[r#""#]],
225 );
226 }
227}
diff --git a/crates/ide_db/src/ty_filter.rs b/crates/ide_db/src/ty_filter.rs
new file mode 100644
index 000000000..63a945282
--- /dev/null
+++ b/crates/ide_db/src/ty_filter.rs
@@ -0,0 +1,58 @@
1//! This module contains structures for filtering the expected types.
2//! Use case for structures in this module is, for example, situation when you need to process
3//! only certain `Enum`s.
4
5use crate::RootDatabase;
6use hir::{Adt, Semantics, Type};
7use std::iter;
8use syntax::ast::{self, make};
9
10/// Enum types that implement `std::ops::Try` trait.
11#[derive(Clone, Copy)]
12pub enum TryEnum {
13 Result,
14 Option,
15}
16
17impl TryEnum {
18 const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
19
20 /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`.
21 pub fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> {
22 let enum_ = match ty.as_adt() {
23 Some(Adt::Enum(it)) => it,
24 _ => return None,
25 };
26 TryEnum::ALL.iter().find_map(|&var| {
27 if &enum_.name(sema.db).to_string() == var.type_name() {
28 return Some(var);
29 }
30 None
31 })
32 }
33
34 pub fn happy_case(self) -> &'static str {
35 match self {
36 TryEnum::Result => "Ok",
37 TryEnum::Option => "Some",
38 }
39 }
40
41 pub fn sad_pattern(self) -> ast::Pat {
42 match self {
43 TryEnum::Result => make::tuple_struct_pat(
44 make::path_unqualified(make::path_segment(make::name_ref("Err"))),
45 iter::once(make::wildcard_pat().into()),
46 )
47 .into(),
48 TryEnum::Option => make::ident_pat(make::name("None")).into(),
49 }
50 }
51
52 fn type_name(self) -> &'static str {
53 match self {
54 TryEnum::Result => "Result",
55 TryEnum::Option => "Option",
56 }
57 }
58}
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 752edc555..2f0fa9726 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -46,7 +46,6 @@ cfg = { path = "../cfg", version = "0.0.0" }
46toolchain = { path = "../toolchain", version = "0.0.0" } 46toolchain = { path = "../toolchain", version = "0.0.0" }
47 47
48# This should only be used in CLI 48# This should only be used in CLI
49base_db = { path = "../base_db", version = "0.0.0" }
50ide_db = { path = "../ide_db", version = "0.0.0" } 49ide_db = { path = "../ide_db", version = "0.0.0" }
51ssr = { path = "../ssr", version = "0.0.0" } 50ssr = { path = "../ssr", version = "0.0.0" }
52hir = { path = "../hir", version = "0.0.0" } 51hir = { path = "../hir", version = "0.0.0" }
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index d1c095ba5..8e33986d5 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -3,13 +3,13 @@
3use std::{env, path::PathBuf, str::FromStr, sync::Arc, time::Instant}; 3use std::{env, path::PathBuf, str::FromStr, sync::Arc, time::Instant};
4 4
5use anyhow::{bail, format_err, Result}; 5use anyhow::{bail, format_err, Result};
6use base_db::{
7 salsa::{Database, Durability},
8 FileId,
9};
10use ide::{ 6use ide::{
11 Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, 7 Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol,
12}; 8};
9use ide_db::base_db::{
10 salsa::{Database, Durability},
11 FileId,
12};
13use vfs::AbsPathBuf; 13use vfs::AbsPathBuf;
14 14
15use crate::{ 15use crate::{
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index fb2b2b000..98ef0cd68 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -6,16 +6,16 @@ use std::{
6 time::{SystemTime, UNIX_EPOCH}, 6 time::{SystemTime, UNIX_EPOCH},
7}; 7};
8 8
9use base_db::{
10 salsa::{self, ParallelDatabase},
11 SourceDatabaseExt,
12};
13use hir::{ 9use hir::{
14 db::{AstDatabase, DefDatabase, HirDatabase}, 10 db::{AstDatabase, DefDatabase, HirDatabase},
15 original_range, AssocItem, Crate, HasSource, HirDisplay, ModuleDef, 11 original_range, AssocItem, Crate, HasSource, HirDisplay, ModuleDef,
16}; 12};
17use hir_def::FunctionId; 13use hir_def::FunctionId;
18use hir_ty::{Ty, TypeWalk}; 14use hir_ty::{Ty, TypeWalk};
15use ide_db::base_db::{
16 salsa::{self, ParallelDatabase},
17 SourceDatabaseExt,
18};
19use itertools::Itertools; 19use itertools::Itertools;
20use oorandom::Rand32; 20use oorandom::Rand32;
21use rayon::prelude::*; 21use rayon::prelude::*;
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index a89993a2b..368f627ac 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -6,9 +6,9 @@ use std::path::Path;
6use anyhow::anyhow; 6use anyhow::anyhow;
7use rustc_hash::FxHashSet; 7use rustc_hash::FxHashSet;
8 8
9use base_db::SourceDatabaseExt;
10use hir::Crate; 9use hir::Crate;
11use ide::{DiagnosticsConfig, Severity}; 10use ide::{DiagnosticsConfig, Severity};
11use ide_db::base_db::SourceDatabaseExt;
12 12
13use crate::cli::{load_cargo::load_cargo, Result}; 13use crate::cli::{load_cargo::load_cargo, Result};
14 14
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 7ae1c9055..ab1e2ab92 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -3,9 +3,9 @@
3use std::{path::Path, sync::Arc}; 3use std::{path::Path, sync::Arc};
4 4
5use anyhow::Result; 5use anyhow::Result;
6use base_db::CrateGraph;
7use crossbeam_channel::{unbounded, Receiver}; 6use crossbeam_channel::{unbounded, Receiver};
8use ide::{AnalysisHost, Change}; 7use ide::{AnalysisHost, Change};
8use ide_db::base_db::CrateGraph;
9use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace}; 9use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace};
10use vfs::{loader::Handle, AbsPath, AbsPathBuf}; 10use vfs::{loader::Handle, AbsPath, AbsPathBuf};
11 11
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index c11e10943..a06631dac 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -4,7 +4,7 @@ use crate::cli::{load_cargo::load_cargo, Result};
4use ssr::{MatchFinder, SsrPattern, SsrRule}; 4use ssr::{MatchFinder, SsrPattern, SsrRule};
5 5
6pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> { 6pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
7 use base_db::SourceDatabaseExt; 7 use ide_db::base_db::SourceDatabaseExt;
8 let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?; 8 let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?;
9 let db = host.raw_database(); 9 let db = host.raw_database();
10 let mut match_finder = MatchFinder::at_first_file(db)?; 10 let mut match_finder = MatchFinder::at_first_file(db)?;
@@ -26,7 +26,7 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
26/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful 26/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
27/// for much else. 27/// for much else.
28pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> { 28pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
29 use base_db::SourceDatabaseExt; 29 use ide_db::base_db::SourceDatabaseExt;
30 use ide_db::symbol_index::SymbolsDatabase; 30 use ide_db::symbol_index::SymbolsDatabase;
31 let (host, _vfs) = load_cargo(&std::env::current_dir()?, true, true)?; 31 let (host, _vfs) = load_cargo(&std::env::current_dir()?, true, true)?;
32 let db = host.raw_database(); 32 let db = host.raw_database();
diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs
index 5b9f52993..aa6b808d6 100644
--- a/crates/rust-analyzer/src/from_proto.rs
+++ b/crates/rust-analyzer/src/from_proto.rs
@@ -1,8 +1,8 @@
1//! Conversion lsp_types types to rust-analyzer specific ones. 1//! Conversion lsp_types types to rust-analyzer specific ones.
2use std::convert::TryFrom; 2use std::convert::TryFrom;
3 3
4use base_db::{FileId, FilePosition, FileRange};
5use ide::{AssistKind, LineCol, LineIndex}; 4use ide::{AssistKind, LineCol, LineIndex};
5use ide_db::base_db::{FileId, FilePosition, FileRange};
6use syntax::{TextRange, TextSize}; 6use syntax::{TextRange, TextSize};
7use vfs::AbsPathBuf; 7use vfs::AbsPathBuf;
8 8
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index dafab6a6a..673a2eebc 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -5,10 +5,10 @@
5 5
6use std::{sync::Arc, time::Instant}; 6use std::{sync::Arc, time::Instant};
7 7
8use base_db::{CrateId, VfsPath};
9use crossbeam_channel::{unbounded, Receiver, Sender}; 8use crossbeam_channel::{unbounded, Receiver, Sender};
10use flycheck::FlycheckHandle; 9use flycheck::FlycheckHandle;
11use ide::{Analysis, AnalysisHost, Change, FileId}; 10use ide::{Analysis, AnalysisHost, Change, FileId};
11use ide_db::base_db::{CrateId, VfsPath};
12use lsp_types::{SemanticTokens, Url}; 12use lsp_types::{SemanticTokens, Url};
13use parking_lot::{Mutex, RwLock}; 13use parking_lot::{Mutex, RwLock};
14use project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; 14use project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index bd888f634..1d271a9d8 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -1,8 +1,8 @@
1//! Utilities for LSP-related boilerplate code. 1//! Utilities for LSP-related boilerplate code.
2use std::{error::Error, ops::Range}; 2use std::{error::Error, ops::Range};
3 3
4use base_db::Canceled;
5use ide::LineIndex; 4use ide::LineIndex;
5use ide_db::base_db::Canceled;
6use lsp_server::Notification; 6use lsp_server::Notification;
7 7
8use crate::{from_proto, global_state::GlobalState}; 8use crate::{from_proto, global_state::GlobalState};
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index fb18f9014..ed5292733 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -5,10 +5,10 @@ use std::{
5 time::{Duration, Instant}, 5 time::{Duration, Instant},
6}; 6};
7 7
8use base_db::VfsPath;
9use crossbeam_channel::{select, Receiver}; 8use crossbeam_channel::{select, Receiver};
10use ide::PrimeCachesProgress; 9use ide::PrimeCachesProgress;
11use ide::{Canceled, FileId}; 10use ide::{Canceled, FileId};
11use ide_db::base_db::VfsPath;
12use lsp_server::{Connection, Notification, Request, Response}; 12use lsp_server::{Connection, Notification, Request, Response};
13use lsp_types::notification::Notification as _; 13use lsp_types::notification::Notification as _;
14use project_model::ProjectWorkspace; 14use project_model::ProjectWorkspace;
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index f7215f129..0eabd51bd 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -1,9 +1,9 @@
1//! Project loading & configuration updates 1//! Project loading & configuration updates
2use std::{mem, sync::Arc}; 2use std::{mem, sync::Arc};
3 3
4use base_db::{CrateGraph, SourceRoot, VfsPath};
5use flycheck::{FlycheckConfig, FlycheckHandle}; 4use flycheck::{FlycheckConfig, FlycheckHandle};
6use ide::Change; 5use ide::Change;
6use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath};
7use project_model::{ProcMacroClient, ProjectWorkspace}; 7use project_model::{ProcMacroClient, ProjectWorkspace};
8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; 8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
9 9
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 0d34970bc..24a658fc6 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -4,13 +4,13 @@ use std::{
4 sync::atomic::{AtomicU32, Ordering}, 4 sync::atomic::{AtomicU32, Ordering},
5}; 5};
6 6
7use base_db::{FileId, FileRange};
8use ide::{ 7use ide::{
9 Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, 8 Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
10 FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange, 9 FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
11 Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, 10 Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget,
12 ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit, 11 ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
13}; 12};
13use ide_db::base_db::{FileId, FileRange};
14use itertools::Itertools; 14use itertools::Itertools;
15use syntax::{SyntaxKind, TextRange, TextSize}; 15use syntax::{SyntaxKind, TextRange, TextSize};
16 16
@@ -809,7 +809,7 @@ mod tests {
809 let completions: Vec<(String, Option<String>)> = analysis 809 let completions: Vec<(String, Option<String>)> = analysis
810 .completions( 810 .completions(
811 &ide::CompletionConfig::default(), 811 &ide::CompletionConfig::default(),
812 base_db::FilePosition { file_id, offset }, 812 ide_db::base_db::FilePosition { file_id, offset },
813 ) 813 )
814 .unwrap() 814 .unwrap()
815 .unwrap() 815 .unwrap()
diff --git a/crates/ssr/Cargo.toml b/crates/ssr/Cargo.toml
index 408140014..98ed25fb6 100644
--- a/crates/ssr/Cargo.toml
+++ b/crates/ssr/Cargo.toml
@@ -16,7 +16,6 @@ itertools = "0.9.0"
16 16
17text_edit = { path = "../text_edit", version = "0.0.0" } 17text_edit = { path = "../text_edit", version = "0.0.0" }
18syntax = { path = "../syntax", version = "0.0.0" } 18syntax = { path = "../syntax", version = "0.0.0" }
19base_db = { path = "../base_db", version = "0.0.0" }
20ide_db = { path = "../ide_db", version = "0.0.0" } 19ide_db = { path = "../ide_db", version = "0.0.0" }
21hir = { path = "../hir", version = "0.0.0" } 20hir = { path = "../hir", version = "0.0.0" }
22test_utils = { path = "../test_utils", version = "0.0.0" } 21test_utils = { path = "../test_utils", version = "0.0.0" }
diff --git a/crates/ssr/src/lib.rs b/crates/ssr/src/lib.rs
index ba669fd56..747ce495d 100644
--- a/crates/ssr/src/lib.rs
+++ b/crates/ssr/src/lib.rs
@@ -73,8 +73,8 @@ use crate::errors::bail;
73pub use crate::errors::SsrError; 73pub use crate::errors::SsrError;
74pub use crate::matching::Match; 74pub use crate::matching::Match;
75use crate::matching::MatchFailureReason; 75use crate::matching::MatchFailureReason;
76use base_db::{FileId, FilePosition, FileRange};
77use hir::Semantics; 76use hir::Semantics;
77use ide_db::base_db::{FileId, FilePosition, FileRange};
78use ide_db::source_change::SourceFileEdit; 78use ide_db::source_change::SourceFileEdit;
79use resolving::ResolvedRule; 79use resolving::ResolvedRule;
80use rustc_hash::FxHashMap; 80use rustc_hash::FxHashMap;
@@ -126,7 +126,7 @@ impl<'db> MatchFinder<'db> {
126 126
127 /// Constructs an instance using the start of the first file in `db` as the lookup context. 127 /// Constructs an instance using the start of the first file in `db` as the lookup context.
128 pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> { 128 pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> {
129 use base_db::SourceDatabaseExt; 129 use ide_db::base_db::SourceDatabaseExt;
130 use ide_db::symbol_index::SymbolsDatabase; 130 use ide_db::symbol_index::SymbolsDatabase;
131 if let Some(first_file_id) = db 131 if let Some(first_file_id) = db
132 .local_roots() 132 .local_roots()
@@ -160,7 +160,7 @@ impl<'db> MatchFinder<'db> {
160 160
161 /// Finds matches for all added rules and returns edits for all found matches. 161 /// Finds matches for all added rules and returns edits for all found matches.
162 pub fn edits(&self) -> Vec<SourceFileEdit> { 162 pub fn edits(&self) -> Vec<SourceFileEdit> {
163 use base_db::SourceDatabaseExt; 163 use ide_db::base_db::SourceDatabaseExt;
164 let mut matches_by_file = FxHashMap::default(); 164 let mut matches_by_file = FxHashMap::default();
165 for m in self.matches().matches { 165 for m in self.matches().matches {
166 matches_by_file 166 matches_by_file
@@ -205,7 +205,7 @@ impl<'db> MatchFinder<'db> {
205 /// them, while recording reasons why they don't match. This API is useful for command 205 /// them, while recording reasons why they don't match. This API is useful for command
206 /// line-based debugging where providing a range is difficult. 206 /// line-based debugging where providing a range is difficult.
207 pub fn debug_where_text_equal(&self, file_id: FileId, snippet: &str) -> Vec<MatchDebugInfo> { 207 pub fn debug_where_text_equal(&self, file_id: FileId, snippet: &str) -> Vec<MatchDebugInfo> {
208 use base_db::SourceDatabaseExt; 208 use ide_db::base_db::SourceDatabaseExt;
209 let file = self.sema.parse(file_id); 209 let file = self.sema.parse(file_id);
210 let mut res = Vec::new(); 210 let mut res = Vec::new();
211 let file_text = self.sema.db.file_text(file_id); 211 let file_text = self.sema.db.file_text(file_id);
diff --git a/crates/ssr/src/matching.rs b/crates/ssr/src/matching.rs
index 948862a77..99b187311 100644
--- a/crates/ssr/src/matching.rs
+++ b/crates/ssr/src/matching.rs
@@ -6,8 +6,8 @@ use crate::{
6 resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo}, 6 resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo},
7 SsrMatches, 7 SsrMatches,
8}; 8};
9use base_db::FileRange;
10use hir::Semantics; 9use hir::Semantics;
10use ide_db::base_db::FileRange;
11use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
12use std::{cell::Cell, iter::Peekable}; 12use std::{cell::Cell, iter::Peekable};
13use syntax::ast::{AstNode, AstToken}; 13use syntax::ast::{AstNode, AstToken};
diff --git a/crates/ssr/src/resolving.rs b/crates/ssr/src/resolving.rs
index 347cc4aad..f5ceb5729 100644
--- a/crates/ssr/src/resolving.rs
+++ b/crates/ssr/src/resolving.rs
@@ -2,7 +2,7 @@
2 2
3use crate::errors::error; 3use crate::errors::error;
4use crate::{parsing, SsrError}; 4use crate::{parsing, SsrError};
5use base_db::FilePosition; 5use ide_db::base_db::FilePosition;
6use parsing::Placeholder; 6use parsing::Placeholder;
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8use syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken}; 8use syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken};
diff --git a/crates/ssr/src/search.rs b/crates/ssr/src/search.rs
index a595fd269..44b5db029 100644
--- a/crates/ssr/src/search.rs
+++ b/crates/ssr/src/search.rs
@@ -5,7 +5,7 @@ use crate::{
5 resolving::{ResolvedPath, ResolvedPattern, ResolvedRule}, 5 resolving::{ResolvedPath, ResolvedPattern, ResolvedRule},
6 Match, MatchFinder, 6 Match, MatchFinder,
7}; 7};
8use base_db::{FileId, FileRange}; 8use ide_db::base_db::{FileId, FileRange};
9use ide_db::{ 9use ide_db::{
10 defs::Definition, 10 defs::Definition,
11 search::{Reference, SearchScope}, 11 search::{Reference, SearchScope},
@@ -145,7 +145,7 @@ impl<'db> MatchFinder<'db> {
145 fn search_files_do(&self, mut callback: impl FnMut(FileId)) { 145 fn search_files_do(&self, mut callback: impl FnMut(FileId)) {
146 if self.restrict_ranges.is_empty() { 146 if self.restrict_ranges.is_empty() {
147 // Unrestricted search. 147 // Unrestricted search.
148 use base_db::SourceDatabaseExt; 148 use ide_db::base_db::SourceDatabaseExt;
149 use ide_db::symbol_index::SymbolsDatabase; 149 use ide_db::symbol_index::SymbolsDatabase;
150 for &root in self.sema.db.local_roots().iter() { 150 for &root in self.sema.db.local_roots().iter() {
151 let sr = self.sema.db.source_root(root); 151 let sr = self.sema.db.source_root(root);
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs
index 20231a9bc..63131f6ca 100644
--- a/crates/ssr/src/tests.rs
+++ b/crates/ssr/src/tests.rs
@@ -1,6 +1,6 @@
1use crate::{MatchFinder, SsrRule}; 1use crate::{MatchFinder, SsrRule};
2use base_db::{salsa::Durability, FileId, FilePosition, FileRange, SourceDatabaseExt};
3use expect_test::{expect, Expect}; 2use expect_test::{expect, Expect};
3use ide_db::base_db::{salsa::Durability, FileId, FilePosition, FileRange, SourceDatabaseExt};
4use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
5use std::sync::Arc; 5use std::sync::Arc;
6use test_utils::{mark, RangeOrOffset}; 6use test_utils::{mark, RangeOrOffset};
@@ -62,7 +62,7 @@ fn parser_undefined_placeholder_in_replacement() {
62/// `code` may optionally contain a cursor marker `<|>`. If it doesn't, then the position will be 62/// `code` may optionally contain a cursor marker `<|>`. If it doesn't, then the position will be
63/// the start of the file. If there's a second cursor marker, then we'll return a single range. 63/// the start of the file. If there's a second cursor marker, then we'll return a single range.
64pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) { 64pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) {
65 use base_db::fixture::WithFixture; 65 use ide_db::base_db::fixture::WithFixture;
66 use ide_db::symbol_index::SymbolsDatabase; 66 use ide_db::symbol_index::SymbolsDatabase;
67 let (mut db, file_id, range_or_offset) = if code.contains(test_utils::CURSOR_MARKER) { 67 let (mut db, file_id, range_or_offset) = if code.contains(test_utils::CURSOR_MARKER) {
68 ide_db::RootDatabase::with_range_or_offset(code) 68 ide_db::RootDatabase::with_range_or_offset(code)
@@ -83,7 +83,7 @@ pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Ve
83 } 83 }
84 } 84 }
85 let mut local_roots = FxHashSet::default(); 85 let mut local_roots = FxHashSet::default();
86 local_roots.insert(base_db::fixture::WORKSPACE); 86 local_roots.insert(ide_db::base_db::fixture::WORKSPACE);
87 db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); 87 db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
88 (db, position, selections) 88 (db, position, selections)
89} 89}
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 50c1c157d..c5cd1c504 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -7,7 +7,7 @@ use itertools::Itertools;
7use parser::SyntaxKind; 7use parser::SyntaxKind;
8 8
9use crate::{ 9use crate::{
10 ast::{self, support, AstNode, NameOwner, SyntaxNode}, 10 ast::{self, support, token_ext::HasStringValue, AstNode, AstToken, NameOwner, SyntaxNode},
11 SmolStr, SyntaxElement, SyntaxToken, T, 11 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 12};
13 13
@@ -53,8 +53,16 @@ impl ast::Attr {
53 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> { 53 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
54 let lit = self.literal()?; 54 let lit = self.literal()?;
55 let key = self.simple_name()?; 55 let key = self.simple_name()?;
56 // FIXME: escape? raw string? 56 let value_token = lit.syntax().first_token()?;
57 let value = lit.syntax().first_token()?.text().trim_matches('"').into(); 57
58 let value: SmolStr = if let Some(s) = ast::String::cast(value_token.clone()) {
59 s.value()?.into()
60 } else if let Some(s) = ast::RawString::cast(value_token) {
61 s.value()?.into()
62 } else {
63 return None;
64 };
65
58 Some((key, value)) 66 Some((key, value))
59 } 67 }
60 68