aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide/Cargo.toml1
-rw-r--r--crates/ra_ide/src/assists.rs10
-rw-r--r--crates/ra_ide/src/call_hierarchy.rs2
-rw-r--r--crates/ra_ide/src/call_info.rs6
-rw-r--r--crates/ra_ide/src/completion.rs5
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs7
-rw-r--r--crates/ra_ide/src/diagnostics.rs3
-rw-r--r--crates/ra_ide/src/display/function_signature.rs17
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs3
-rw-r--r--crates/ra_ide/src/expand.rs3
-rw-r--r--crates/ra_ide/src/expand_macro.rs25
-rw-r--r--crates/ra_ide/src/extend_selection.rs12
-rw-r--r--crates/ra_ide/src/goto_definition.rs4
-rw-r--r--crates/ra_ide/src/goto_type_definition.rs4
-rw-r--r--crates/ra_ide/src/hover.rs2
-rw-r--r--crates/ra_ide/src/impls.rs3
-rw-r--r--crates/ra_ide/src/imports_locator.rs15
-rw-r--r--crates/ra_ide/src/inlay_hints.rs3
-rw-r--r--crates/ra_ide/src/lib.rs147
-rw-r--r--crates/ra_ide/src/parent_module.rs3
-rw-r--r--crates/ra_ide/src/references.rs5
-rw-r--r--crates/ra_ide/src/references/classify.rs2
-rw-r--r--crates/ra_ide/src/references/name_definition.rs2
-rw-r--r--crates/ra_ide/src/references/rename.rs4
-rw-r--r--crates/ra_ide/src/references/search_scope.rs2
-rw-r--r--crates/ra_ide/src/runnables.rs3
-rw-r--r--crates/ra_ide/src/status.rs10
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs2
-rw-r--r--crates/ra_ide/src/syntax_tree.rs2
-rw-r--r--crates/ra_ide/src/typing.rs3
-rw-r--r--crates/ra_ide_db/Cargo.toml48
-rw-r--r--crates/ra_ide_db/src/change.rs (renamed from crates/ra_ide/src/change.rs)15
-rw-r--r--crates/ra_ide_db/src/feature_flags.rs (renamed from crates/ra_ide/src/feature_flags.rs)2
-rw-r--r--crates/ra_ide_db/src/lib.rs (renamed from crates/ra_ide/src/db.rs)26
-rw-r--r--crates/ra_ide_db/src/line_index.rs (renamed from crates/ra_ide/src/line_index.rs)5
-rw-r--r--crates/ra_ide_db/src/line_index_utils.rs (renamed from crates/ra_ide/src/line_index_utils.rs)164
-rw-r--r--crates/ra_ide_db/src/symbol_index.rs (renamed from crates/ra_ide/src/symbol_index.rs)145
-rw-r--r--crates/ra_ide_db/src/wasm_shims.rs (renamed from crates/ra_ide/src/wasm_shims.rs)2
38 files changed, 397 insertions, 320 deletions
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml
index 53817d1f7..9ace35229 100644
--- a/crates/ra_ide/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -28,6 +28,7 @@ once_cell = "1.2.0"
28ra_syntax = { path = "../ra_syntax" } 28ra_syntax = { path = "../ra_syntax" }
29ra_text_edit = { path = "../ra_text_edit" } 29ra_text_edit = { path = "../ra_text_edit" }
30ra_db = { path = "../ra_db" } 30ra_db = { path = "../ra_db" }
31ra_ide_db = { path = "../ra_ide_db" }
31ra_cfg = { path = "../ra_cfg" } 32ra_cfg = { path = "../ra_cfg" }
32ra_fmt = { path = "../ra_fmt" } 33ra_fmt = { path = "../ra_fmt" }
33ra_prof = { path = "../ra_prof" } 34ra_prof = { path = "../ra_prof" }
diff --git a/crates/ra_ide/src/assists.rs b/crates/ra_ide/src/assists.rs
index c43c45c65..f26047570 100644
--- a/crates/ra_ide/src/assists.rs
+++ b/crates/ra_ide/src/assists.rs
@@ -1,13 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use either::Either;
4use ra_assists::{AssistAction, AssistLabel};
3use ra_db::{FilePosition, FileRange}; 5use ra_db::{FilePosition, FileRange};
6use ra_ide_db::RootDatabase;
7
8use crate::{imports_locator::ImportsLocatorIde, FileId, SourceChange, SourceFileEdit};
4 9
5use crate::{
6 db::RootDatabase, imports_locator::ImportsLocatorIde, FileId, SourceChange, SourceFileEdit,
7};
8use either::Either;
9pub use ra_assists::AssistId; 10pub use ra_assists::AssistId;
10use ra_assists::{AssistAction, AssistLabel};
11 11
12#[derive(Debug)] 12#[derive(Debug)]
13pub struct Assist { 13pub struct Assist {
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
index aa5d60c7b..f984f40ad 100644
--- a/crates/ra_ide/src/call_hierarchy.rs
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -3,6 +3,7 @@
3use indexmap::IndexMap; 3use indexmap::IndexMap;
4 4
5use hir::db::AstDatabase; 5use hir::db::AstDatabase;
6use ra_ide_db::RootDatabase;
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, DocCommentsOwner}, 8 ast::{self, DocCommentsOwner},
8 match_ast, AstNode, TextRange, 9 match_ast, AstNode, TextRange,
@@ -10,7 +11,6 @@ use ra_syntax::{
10 11
11use crate::{ 12use crate::{
12 call_info::FnCallNode, 13 call_info::FnCallNode,
13 db::RootDatabase,
14 display::{ShortLabel, ToNav}, 14 display::{ShortLabel, ToNav},
15 expand::descend_into_macros, 15 expand::descend_into_macros,
16 goto_definition, references, FilePosition, NavigationTarget, RangeInfo, 16 goto_definition, references, FilePosition, NavigationTarget, RangeInfo,
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 72a68522e..f2b29306e 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -1,15 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use hir::db::AstDatabase; 2use hir::db::AstDatabase;
3use ra_ide_db::RootDatabase;
3use ra_syntax::{ 4use ra_syntax::{
4 ast::{self, ArgListOwner}, 5 ast::{self, ArgListOwner},
5 match_ast, AstNode, SyntaxNode, 6 match_ast, AstNode, SyntaxNode,
6}; 7};
7
8use test_utils::tested_by; 8use test_utils::tested_by;
9 9
10use crate::{ 10use crate::{expand::descend_into_macros, CallInfo, FilePosition, FunctionSignature};
11 db::RootDatabase, expand::descend_into_macros, CallInfo, FilePosition, FunctionSignature,
12};
13 11
14/// Computes parameter information for the given call expression. 12/// Computes parameter information for the given call expression.
15pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 13pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index abe1f36ce..fedc02e14 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -17,6 +17,7 @@ mod complete_postfix;
17mod complete_macro_in_item_position; 17mod complete_macro_in_item_position;
18 18
19use ra_db::SourceDatabase; 19use ra_db::SourceDatabase;
20use ra_ide_db::RootDatabase;
20 21
21#[cfg(test)] 22#[cfg(test)]
22use crate::completion::completion_item::do_completion; 23use crate::completion::completion_item::do_completion;
@@ -25,7 +26,7 @@ use crate::{
25 completion_context::CompletionContext, 26 completion_context::CompletionContext,
26 completion_item::{CompletionKind, Completions}, 27 completion_item::{CompletionKind, Completions},
27 }, 28 },
28 db, FilePosition, 29 FilePosition,
29}; 30};
30 31
31pub use crate::completion::completion_item::{ 32pub use crate::completion::completion_item::{
@@ -54,7 +55,7 @@ pub use crate::completion::completion_item::{
54/// `foo` *should* be present among the completion variants. Filtering by 55/// `foo` *should* be present among the completion variants. Filtering by
55/// identifier prefix/fuzzy match should be done higher in the stack, together 56/// identifier prefix/fuzzy match should be done higher in the stack, together
56/// with ordering of completions (currently this is done by the client). 57/// with ordering of completions (currently this is done by the client).
57pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> { 58pub(crate) fn completions(db: &RootDatabase, position: FilePosition) -> Option<Completions> {
58 let original_parse = db.parse(position.file_id); 59 let original_parse = db.parse(position.file_id);
59 let ctx = CompletionContext::new(db, &original_parse, position)?; 60 let ctx = CompletionContext::new(db, &original_parse, position)?;
60 61
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index deaacda6c..5a0407fd7 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -1,5 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_ide_db::RootDatabase;
3use ra_syntax::{ 4use ra_syntax::{
4 algo::{find_covering_element, find_node_at_offset}, 5 algo::{find_covering_element, find_node_at_offset},
5 ast, AstNode, Parse, SourceFile, 6 ast, AstNode, Parse, SourceFile,
@@ -8,13 +9,13 @@ use ra_syntax::{
8}; 9};
9use ra_text_edit::AtomTextEdit; 10use ra_text_edit::AtomTextEdit;
10 11
11use crate::{db, FilePosition}; 12use crate::FilePosition;
12 13
13/// `CompletionContext` is created early during completion to figure out, where 14/// `CompletionContext` is created early during completion to figure out, where
14/// exactly is the cursor, syntax-wise. 15/// exactly is the cursor, syntax-wise.
15#[derive(Debug)] 16#[derive(Debug)]
16pub(crate) struct CompletionContext<'a> { 17pub(crate) struct CompletionContext<'a> {
17 pub(super) db: &'a db::RootDatabase, 18 pub(super) db: &'a RootDatabase,
18 pub(super) analyzer: hir::SourceAnalyzer, 19 pub(super) analyzer: hir::SourceAnalyzer,
19 pub(super) offset: TextUnit, 20 pub(super) offset: TextUnit,
20 pub(super) token: SyntaxToken, 21 pub(super) token: SyntaxToken,
@@ -48,7 +49,7 @@ pub(crate) struct CompletionContext<'a> {
48 49
49impl<'a> CompletionContext<'a> { 50impl<'a> CompletionContext<'a> {
50 pub(super) fn new( 51 pub(super) fn new(
51 db: &'a db::RootDatabase, 52 db: &'a RootDatabase,
52 original_parse: &'a Parse<ast::SourceFile>, 53 original_parse: &'a Parse<ast::SourceFile>,
53 position: FilePosition, 54 position: FilePosition,
54 ) -> Option<CompletionContext<'a>> { 55 ) -> Option<CompletionContext<'a>> {
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index f403b3bcf..22bd49723 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -5,6 +5,7 @@ use std::cell::RefCell;
5use hir::diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSink}; 5use hir::diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSink};
6use itertools::Itertools; 6use itertools::Itertools;
7use ra_db::{RelativePath, SourceDatabase, SourceDatabaseExt}; 7use ra_db::{RelativePath, SourceDatabase, SourceDatabaseExt};
8use ra_ide_db::RootDatabase;
8use ra_prof::profile; 9use ra_prof::profile;
9use ra_syntax::{ 10use ra_syntax::{
10 algo, 11 algo,
@@ -13,7 +14,7 @@ use ra_syntax::{
13}; 14};
14use ra_text_edit::{TextEdit, TextEditBuilder}; 15use ra_text_edit::{TextEdit, TextEditBuilder};
15 16
16use crate::{db::RootDatabase, Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit}; 17use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit};
17 18
18#[derive(Debug, Copy, Clone)] 19#[derive(Debug, Copy, Clone)]
19pub enum Severity { 20pub enum Severity {
diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs
index 1e4a472b4..c23e08e9a 100644
--- a/crates/ra_ide/src/display/function_signature.rs
+++ b/crates/ra_ide/src/display/function_signature.rs
@@ -4,13 +4,11 @@ use std::fmt::{self, Display};
4 4
5use hir::{Docs, Documentation, HasSource, HirDisplay}; 5use hir::{Docs, Documentation, HasSource, HirDisplay};
6use join_to_string::join; 6use join_to_string::join;
7use ra_ide_db::RootDatabase;
7use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; 8use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
8use std::convert::From; 9use std::convert::From;
9 10
10use crate::{ 11use crate::display::{generic_parameters, where_predicates};
11 db,
12 display::{generic_parameters, where_predicates},
13};
14 12
15#[derive(Debug)] 13#[derive(Debug)]
16pub enum CallableKind { 14pub enum CallableKind {
@@ -48,13 +46,13 @@ impl FunctionSignature {
48 self 46 self
49 } 47 }
50 48
51 pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { 49 pub(crate) fn from_hir(db: &RootDatabase, function: hir::Function) -> Self {
52 let doc = function.docs(db); 50 let doc = function.docs(db);
53 let ast_node = function.source(db).value; 51 let ast_node = function.source(db).value;
54 FunctionSignature::from(&ast_node).with_doc_opt(doc) 52 FunctionSignature::from(&ast_node).with_doc_opt(doc)
55 } 53 }
56 54
57 pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Option<Self> { 55 pub(crate) fn from_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> {
58 let node: ast::StructDef = st.source(db).value; 56 let node: ast::StructDef = st.source(db).value;
59 match node.kind() { 57 match node.kind() {
60 ast::StructKind::Record(_) => return None, 58 ast::StructKind::Record(_) => return None,
@@ -86,10 +84,7 @@ impl FunctionSignature {
86 ) 84 )
87 } 85 }
88 86
89 pub(crate) fn from_enum_variant( 87 pub(crate) fn from_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> {
90 db: &db::RootDatabase,
91 variant: hir::EnumVariant,
92 ) -> Option<Self> {
93 let node: ast::EnumVariant = variant.source(db).value; 88 let node: ast::EnumVariant = variant.source(db).value;
94 match node.kind() { 89 match node.kind() {
95 ast::StructKind::Record(_) | ast::StructKind::Unit => return None, 90 ast::StructKind::Record(_) | ast::StructKind::Unit => return None,
@@ -126,7 +121,7 @@ impl FunctionSignature {
126 ) 121 )
127 } 122 }
128 123
129 pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { 124 pub(crate) fn from_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
130 let node: ast::MacroCall = macro_def.source(db).value; 125 let node: ast::MacroCall = macro_def.source(db).value;
131 126
132 let params = vec![]; 127 let params = vec![];
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index b2af3479c..906aab1eb 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -3,6 +3,7 @@
3use either::Either; 3use either::Either;
4use hir::{AssocItem, FieldSource, HasSource, InFile, ModuleSource}; 4use hir::{AssocItem, FieldSource, HasSource, InFile, ModuleSource};
5use ra_db::{FileId, SourceDatabase}; 5use ra_db::{FileId, SourceDatabase};
6use ra_ide_db::RootDatabase;
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, DocCommentsOwner, NameOwner}, 8 ast::{self, DocCommentsOwner, NameOwner},
8 match_ast, AstNode, SmolStr, 9 match_ast, AstNode, SmolStr,
@@ -10,7 +11,7 @@ use ra_syntax::{
10 TextRange, 11 TextRange,
11}; 12};
12 13
13use crate::{db::RootDatabase, expand::original_range, FileSymbol}; 14use crate::{expand::original_range, FileSymbol};
14 15
15use super::short_label::ShortLabel; 16use super::short_label::ShortLabel;
16 17
diff --git a/crates/ra_ide/src/expand.rs b/crates/ra_ide/src/expand.rs
index 831438c09..9f3aaa3a3 100644
--- a/crates/ra_ide/src/expand.rs
+++ b/crates/ra_ide/src/expand.rs
@@ -3,9 +3,10 @@ use std::iter::successors;
3 3
4use hir::{InFile, Origin}; 4use hir::{InFile, Origin};
5use ra_db::FileId; 5use ra_db::FileId;
6use ra_ide_db::RootDatabase;
6use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken, TextRange}; 7use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken, TextRange};
7 8
8use crate::{db::RootDatabase, FileRange}; 9use crate::FileRange;
9 10
10pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange { 11pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange {
11 if let Some((range, Origin::Call)) = original_range_and_origin(db, node) { 12 if let Some((range, Origin::Call)) = original_range_and_origin(db, node) {
diff --git a/crates/ra_ide/src/expand_macro.rs b/crates/ra_ide/src/expand_macro.rs
index 0f7b6e875..af2783bef 100644
--- a/crates/ra_ide/src/expand_macro.rs
+++ b/crates/ra_ide/src/expand_macro.rs
@@ -1,14 +1,15 @@
1//! This modules implements "expand macro" functionality in the IDE 1//! This modules implements "expand macro" functionality in the IDE
2 2
3use crate::{db::RootDatabase, FilePosition};
4use hir::db::AstDatabase; 3use hir::db::AstDatabase;
5use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
6use rustc_hash::FxHashMap; 5use ra_ide_db::RootDatabase;
7
8use ra_syntax::{ 6use ra_syntax::{
9 algo::{find_node_at_offset, replace_descendants}, 7 algo::{find_node_at_offset, replace_descendants},
10 ast, AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, WalkEvent, T, 8 ast, AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, WalkEvent, T,
11}; 9};
10use rustc_hash::FxHashMap;
11
12use crate::FilePosition;
12 13
13pub struct ExpandedMacro { 14pub struct ExpandedMacro {
14 pub name: String, 15 pub name: String,
@@ -185,7 +186,7 @@ fn some_thing() -> u32 {
185 //- /lib.rs 186 //- /lib.rs
186 macro_rules! match_ast { 187 macro_rules! match_ast {
187 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; 188 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
188 189
189 (match ($node:expr) { 190 (match ($node:expr) {
190 $( ast::$ast:ident($it:ident) => $res:block, )* 191 $( ast::$ast:ident($it:ident) => $res:block, )*
191 _ => $catch_all:expr $(,)? 192 _ => $catch_all:expr $(,)?
@@ -193,7 +194,7 @@ fn some_thing() -> u32 {
193 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* 194 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
194 { $catch_all } 195 { $catch_all }
195 }}; 196 }};
196 } 197 }
197 198
198 fn main() { 199 fn main() {
199 mat<|>ch_ast! { 200 mat<|>ch_ast! {
@@ -227,11 +228,11 @@ fn some_thing() -> u32 {
227 r#" 228 r#"
228 //- /lib.rs 229 //- /lib.rs
229 macro_rules! match_ast { 230 macro_rules! match_ast {
230 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; 231 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
231 (match ($node:expr) {}) => {{}}; 232 (match ($node:expr) {}) => {{}};
232 } 233 }
233 234
234 fn main() { 235 fn main() {
235 let p = f(|it| { 236 let p = f(|it| {
236 let res = mat<|>ch_ast! { match c {}}; 237 let res = mat<|>ch_ast! { match c {}};
237 Some(res) 238 Some(res)
@@ -254,9 +255,9 @@ fn some_thing() -> u32 {
254 } 255 }
255 macro_rules! foo { 256 macro_rules! foo {
256 () => {bar!()}; 257 () => {bar!()};
257 } 258 }
258 259
259 fn main() { 260 fn main() {
260 let res = fo<|>o!(); 261 let res = fo<|>o!();
261 } 262 }
262 "#, 263 "#,
@@ -277,9 +278,9 @@ fn some_thing() -> u32 {
277 } 278 }
278 macro_rules! foo { 279 macro_rules! foo {
279 () => {$crate::bar!()}; 280 () => {$crate::bar!()};
280 } 281 }
281 282
282 fn main() { 283 fn main() {
283 let res = fo<|>o!(); 284 let res = fo<|>o!();
284 } 285 }
285 "#, 286 "#,
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 930e0c4c2..726963a33 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -1,6 +1,10 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::iter::successors;
4
5use hir::db::AstDatabase;
3use ra_db::SourceDatabase; 6use ra_db::SourceDatabase;
7use ra_ide_db::RootDatabase;
4use ra_syntax::{ 8use ra_syntax::{
5 algo::find_covering_element, 9 algo::find_covering_element,
6 ast::{self, AstNode, AstToken}, 10 ast::{self, AstNode, AstToken},
@@ -9,9 +13,7 @@ use ra_syntax::{
9 SyntaxNode, SyntaxToken, TextRange, TextUnit, TokenAtOffset, T, 13 SyntaxNode, SyntaxToken, TextRange, TextUnit, TokenAtOffset, T,
10}; 14};
11 15
12use crate::{db::RootDatabase, expand::descend_into_macros, FileId, FileRange}; 16use crate::{expand::descend_into_macros, FileId, FileRange};
13use hir::db::AstDatabase;
14use std::iter::successors;
15 17
16pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { 18pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
17 let src = db.parse(frange.file_id).tree(); 19 let src = db.parse(frange.file_id).tree();
@@ -512,8 +514,8 @@ fn bar(){}
512 fn test_extend_trait_bounds_list_in_where_clause() { 514 fn test_extend_trait_bounds_list_in_where_clause() {
513 do_check( 515 do_check(
514 r#" 516 r#"
515fn foo<R>() 517fn foo<R>()
516 where 518 where
517 R: req::Request + 'static, 519 R: req::Request + 'static,
518 R::Params: DeserializeOwned<|> + panic::UnwindSafe + 'static, 520 R::Params: DeserializeOwned<|> + panic::UnwindSafe + 'static,
519 R::Result: Serialize + 'static, 521 R::Result: Serialize + 'static,
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 5a12a619c..e9329a72c 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::AstDatabase, InFile, SourceBinder}; 3use hir::{db::AstDatabase, InFile, SourceBinder};
4use ra_ide_db::{symbol_index, RootDatabase};
4use ra_syntax::{ 5use ra_syntax::{
5 ast::{self, DocCommentsOwner}, 6 ast::{self, DocCommentsOwner},
6 match_ast, AstNode, 7 match_ast, AstNode,
@@ -9,7 +10,6 @@ use ra_syntax::{
9}; 10};
10 11
11use crate::{ 12use crate::{
12 db::RootDatabase,
13 display::{ShortLabel, ToNav}, 13 display::{ShortLabel, ToNav},
14 expand::descend_into_macros, 14 expand::descend_into_macros,
15 references::{classify_name_ref, NameKind::*}, 15 references::{classify_name_ref, NameKind::*},
@@ -94,7 +94,7 @@ pub(crate) fn reference_definition(
94 }; 94 };
95 95
96 // Fallback index based approach: 96 // Fallback index based approach:
97 let navs = crate::symbol_index::index_resolve(sb.db, name_ref.value) 97 let navs = symbol_index::index_resolve(sb.db, name_ref.value)
98 .into_iter() 98 .into_iter()
99 .map(|s| s.to_nav(sb.db)) 99 .map(|s| s.to_nav(sb.db))
100 .collect(); 100 .collect();
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs
index ce8b6c72a..11ad6d137 100644
--- a/crates/ra_ide/src/goto_type_definition.rs
+++ b/crates/ra_ide/src/goto_type_definition.rs
@@ -1,11 +1,11 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::db::AstDatabase; 3use hir::db::AstDatabase;
4use ra_ide_db::RootDatabase;
4use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; 5use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset};
5 6
6use crate::{ 7use crate::{
7 db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, 8 display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, RangeInfo,
8 RangeInfo,
9}; 9};
10 10
11pub(crate) fn goto_type_definition( 11pub(crate) fn goto_type_definition(
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 6661e5cb2..315b88190 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -2,6 +2,7 @@
2 2
3use hir::{db::AstDatabase, Adt, HasSource, HirDisplay, SourceBinder}; 3use hir::{db::AstDatabase, Adt, HasSource, HirDisplay, SourceBinder};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_ide_db::RootDatabase;
5use ra_syntax::{ 6use ra_syntax::{
6 algo::find_covering_element, 7 algo::find_covering_element,
7 ast::{self, DocCommentsOwner}, 8 ast::{self, DocCommentsOwner},
@@ -11,7 +12,6 @@ use ra_syntax::{
11}; 12};
12 13
13use crate::{ 14use crate::{
14 db::RootDatabase,
15 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, 15 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
16 expand::descend_into_macros, 16 expand::descend_into_macros,
17 references::{classify_name, classify_name_ref, NameKind, NameKind::*}, 17 references::{classify_name, classify_name_ref, NameKind, NameKind::*},
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs
index 9834025d3..64a2dadc8 100644
--- a/crates/ra_ide/src/impls.rs
+++ b/crates/ra_ide/src/impls.rs
@@ -2,9 +2,10 @@
2 2
3use hir::{Crate, ImplBlock, SourceBinder}; 3use hir::{Crate, ImplBlock, SourceBinder};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_ide_db::RootDatabase;
5use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 6use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
6 7
7use crate::{db::RootDatabase, display::ToNav, FilePosition, NavigationTarget, RangeInfo}; 8use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo};
8 9
9pub(crate) fn goto_implementation( 10pub(crate) fn goto_implementation(
10 db: &RootDatabase, 11 db: &RootDatabase,
diff --git a/crates/ra_ide/src/imports_locator.rs b/crates/ra_ide/src/imports_locator.rs
index 9e1a1c1ec..cfd58aafe 100644
--- a/crates/ra_ide/src/imports_locator.rs
+++ b/crates/ra_ide/src/imports_locator.rs
@@ -1,17 +1,20 @@
1//! This module contains an import search funcionality that is provided to the ra_assists module. 1//! This module contains an import search funcionality that is provided to the ra_assists module.
2//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. 2//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module.
3 3
4use crate::{
5 db::RootDatabase,
6 references::{classify_name, NameDefinition, NameKind},
7 symbol_index::{self, FileSymbol},
8 Query,
9};
10use hir::{db::HirDatabase, ModuleDef, SourceBinder}; 4use hir::{db::HirDatabase, ModuleDef, SourceBinder};
11use ra_assists::ImportsLocator; 5use ra_assists::ImportsLocator;
6use ra_ide_db::{
7 symbol_index::{self, FileSymbol},
8 RootDatabase,
9};
12use ra_prof::profile; 10use ra_prof::profile;
13use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; 11use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
14 12
13use crate::{
14 references::{classify_name, NameDefinition, NameKind},
15 Query,
16};
17
15pub(crate) struct ImportsLocatorIde<'a> { 18pub(crate) struct ImportsLocatorIde<'a> {
16 source_binder: SourceBinder<'a, RootDatabase>, 19 source_binder: SourceBinder<'a, RootDatabase>,
17} 20}
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index de447a5aa..6b0d3d996 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -2,13 +2,14 @@
2 2
3use hir::{HirDisplay, SourceAnalyzer, SourceBinder}; 3use hir::{HirDisplay, SourceAnalyzer, SourceBinder};
4use once_cell::unsync::Lazy; 4use once_cell::unsync::Lazy;
5use ra_ide_db::RootDatabase;
5use ra_prof::profile; 6use ra_prof::profile;
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, 8 ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner},
8 match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, 9 match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange,
9}; 10};
10 11
11use crate::{db::RootDatabase, FileId, FunctionSignature}; 12use crate::{FileId, FunctionSignature};
12 13
13#[derive(Debug, PartialEq, Eq)] 14#[derive(Debug, PartialEq, Eq)]
14pub enum InlayKind { 15pub enum InlayKind {
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 03ad6b2c1..5fb111a90 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -10,12 +10,8 @@
10// For proving that RootDatabase is RefUnwindSafe. 10// For proving that RootDatabase is RefUnwindSafe.
11#![recursion_limit = "128"] 11#![recursion_limit = "128"]
12 12
13mod db;
14pub mod mock_analysis; 13pub mod mock_analysis;
15mod symbol_index;
16mod change;
17mod source_change; 14mod source_change;
18mod feature_flags;
19 15
20mod status; 16mod status;
21mod completion; 17mod completion;
@@ -35,14 +31,11 @@ mod assists;
35mod diagnostics; 31mod diagnostics;
36mod syntax_tree; 32mod syntax_tree;
37mod folding_ranges; 33mod folding_ranges;
38mod line_index;
39mod line_index_utils;
40mod join_lines; 34mod join_lines;
41mod typing; 35mod typing;
42mod matching_brace; 36mod matching_brace;
43mod display; 37mod display;
44mod inlay_hints; 38mod inlay_hints;
45mod wasm_shims;
46mod expand; 39mod expand;
47mod expand_macro; 40mod expand_macro;
48 41
@@ -58,24 +51,24 @@ use ra_db::{
58 salsa::{self, ParallelDatabase}, 51 salsa::{self, ParallelDatabase},
59 CheckCanceled, Env, FileLoader, SourceDatabase, 52 CheckCanceled, Env, FileLoader, SourceDatabase,
60}; 53};
54use ra_ide_db::{
55 symbol_index::{self, FileSymbol},
56 LineIndexDatabase,
57};
61use ra_syntax::{SourceFile, TextRange, TextUnit}; 58use ra_syntax::{SourceFile, TextRange, TextUnit};
62 59
63use crate::{db::LineIndexDatabase, display::ToNav, symbol_index::FileSymbol}; 60use crate::display::ToNav;
64 61
65pub use crate::{ 62pub use crate::{
66 assists::{Assist, AssistId}, 63 assists::{Assist, AssistId},
67 call_hierarchy::CallItem, 64 call_hierarchy::CallItem,
68 change::{AnalysisChange, LibraryData},
69 completion::{CompletionItem, CompletionItemKind, InsertTextFormat}, 65 completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
70 diagnostics::Severity, 66 diagnostics::Severity,
71 display::{file_structure, FunctionSignature, NavigationTarget, StructureNode}, 67 display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
72 expand_macro::ExpandedMacro, 68 expand_macro::ExpandedMacro,
73 feature_flags::FeatureFlags,
74 folding_ranges::{Fold, FoldKind}, 69 folding_ranges::{Fold, FoldKind},
75 hover::HoverResult, 70 hover::HoverResult,
76 inlay_hints::{InlayHint, InlayKind}, 71 inlay_hints::{InlayHint, InlayKind},
77 line_index::{LineCol, LineIndex},
78 line_index_utils::translate_offset_with_edit,
79 references::{ 72 references::{
80 Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, SearchScope, 73 Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, SearchScope,
81 }, 74 },
@@ -88,6 +81,14 @@ pub use hir::Documentation;
88pub use ra_db::{ 81pub use ra_db::{
89 Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRootId, 82 Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRootId,
90}; 83};
84pub use ra_ide_db::{
85 change::{AnalysisChange, LibraryData},
86 feature_flags::FeatureFlags,
87 line_index::{LineCol, LineIndex},
88 line_index_utils::translate_offset_with_edit,
89 symbol_index::Query,
90 RootDatabase,
91};
91 92
92pub type Cancelable<T> = Result<T, Canceled>; 93pub type Cancelable<T> = Result<T, Canceled>;
93 94
@@ -99,46 +100,6 @@ pub struct Diagnostic {
99 pub severity: Severity, 100 pub severity: Severity,
100} 101}
101 102
102#[derive(Debug)]
103pub struct Query {
104 query: String,
105 lowercased: String,
106 only_types: bool,
107 libs: bool,
108 exact: bool,
109 limit: usize,
110}
111
112impl Query {
113 pub fn new(query: String) -> Query {
114 let lowercased = query.to_lowercase();
115 Query {
116 query,
117 lowercased,
118 only_types: false,
119 libs: false,
120 exact: false,
121 limit: usize::max_value(),
122 }
123 }
124
125 pub fn only_types(&mut self) {
126 self.only_types = true;
127 }
128
129 pub fn libs(&mut self) {
130 self.libs = true;
131 }
132
133 pub fn exact(&mut self) {
134 self.exact = true;
135 }
136
137 pub fn limit(&mut self, limit: usize) {
138 self.limit = limit
139 }
140}
141
142/// Info associated with a text range. 103/// Info associated with a text range.
143#[derive(Debug)] 104#[derive(Debug)]
144pub struct RangeInfo<T> { 105pub struct RangeInfo<T> {
@@ -163,7 +124,7 @@ pub struct CallInfo {
163/// `AnalysisHost` stores the current state of the world. 124/// `AnalysisHost` stores the current state of the world.
164#[derive(Debug)] 125#[derive(Debug)]
165pub struct AnalysisHost { 126pub struct AnalysisHost {
166 db: db::RootDatabase, 127 db: RootDatabase,
167} 128}
168 129
169impl Default for AnalysisHost { 130impl Default for AnalysisHost {
@@ -174,7 +135,7 @@ impl Default for AnalysisHost {
174 135
175impl AnalysisHost { 136impl AnalysisHost {
176 pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost { 137 pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost {
177 AnalysisHost { db: db::RootDatabase::new(lru_capcity, feature_flags) } 138 AnalysisHost { db: RootDatabase::new(lru_capcity, feature_flags) }
178 } 139 }
179 /// Returns a snapshot of the current state, which you can query for 140 /// Returns a snapshot of the current state, which you can query for
180 /// semantic information. 141 /// semantic information.
@@ -224,7 +185,7 @@ impl AnalysisHost {
224/// `Analysis` are canceled (most method return `Err(Canceled)`). 185/// `Analysis` are canceled (most method return `Err(Canceled)`).
225#[derive(Debug)] 186#[derive(Debug)]
226pub struct Analysis { 187pub struct Analysis {
227 db: salsa::Snapshot<db::RootDatabase>, 188 db: salsa::Snapshot<RootDatabase>,
228} 189}
229 190
230// As a general design guideline, `Analysis` API are intended to be independent 191// As a general design guideline, `Analysis` API are intended to be independent
@@ -505,7 +466,7 @@ impl Analysis {
505 } 466 }
506 467
507 /// Performs an operation on that may be Canceled. 468 /// Performs an operation on that may be Canceled.
508 fn with_db<F: FnOnce(&db::RootDatabase) -> T + std::panic::UnwindSafe, T>( 469 fn with_db<F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, T>(
509 &self, 470 &self,
510 f: F, 471 f: F,
511 ) -> Cancelable<T> { 472 ) -> Cancelable<T> {
@@ -518,3 +479,77 @@ fn analysis_is_send() {
518 fn is_send<T: Send>() {} 479 fn is_send<T: Send>() {}
519 is_send::<Analysis>(); 480 is_send::<Analysis>();
520} 481}
482
483#[cfg(test)]
484mod tests {
485 use crate::{display::NavigationTarget, mock_analysis::single_file, Query};
486 use ra_syntax::{
487 SmolStr,
488 SyntaxKind::{FN_DEF, STRUCT_DEF},
489 };
490
491 #[test]
492 fn test_world_symbols_with_no_container() {
493 let code = r#"
494 enum FooInner { }
495 "#;
496
497 let mut symbols = get_symbols_matching(code, "FooInner");
498
499 let s = symbols.pop().unwrap();
500
501 assert_eq!(s.name(), "FooInner");
502 assert!(s.container_name().is_none());
503 }
504
505 #[test]
506 fn test_world_symbols_include_container_name() {
507 let code = r#"
508fn foo() {
509 enum FooInner { }
510}
511 "#;
512
513 let mut symbols = get_symbols_matching(code, "FooInner");
514
515 let s = symbols.pop().unwrap();
516
517 assert_eq!(s.name(), "FooInner");
518 assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
519
520 let code = r#"
521mod foo {
522 struct FooInner;
523}
524 "#;
525
526 let mut symbols = get_symbols_matching(code, "FooInner");
527
528 let s = symbols.pop().unwrap();
529
530 assert_eq!(s.name(), "FooInner");
531 assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
532 }
533
534 #[test]
535 fn test_world_symbols_are_case_sensitive() {
536 let code = r#"
537fn foo() {}
538
539struct Foo;
540 "#;
541
542 let symbols = get_symbols_matching(code, "Foo");
543
544 let fn_match = symbols.iter().find(|s| s.name() == "foo").map(|s| s.kind());
545 let struct_match = symbols.iter().find(|s| s.name() == "Foo").map(|s| s.kind());
546
547 assert_eq!(fn_match, Some(FN_DEF));
548 assert_eq!(struct_match, Some(STRUCT_DEF));
549 }
550
551 fn get_symbols_matching(text: &str, query: &str) -> Vec<NavigationTarget> {
552 let (analysis, _) = single_file(text);
553 analysis.symbol_search(Query::new(query.into())).unwrap()
554 }
555}
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index 2dbccfc3b..e0332da88 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -1,12 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_db::{CrateId, FileId, FilePosition, SourceDatabase}; 3use ra_db::{CrateId, FileId, FilePosition, SourceDatabase};
4use ra_ide_db::RootDatabase;
4use ra_syntax::{ 5use ra_syntax::{
5 algo::find_node_at_offset, 6 algo::find_node_at_offset,
6 ast::{self, AstNode}, 7 ast::{self, AstNode},
7}; 8};
8 9
9use crate::{db::RootDatabase, NavigationTarget}; 10use crate::NavigationTarget;
10 11
11/// This returns `Vec` because a module may be included from several places. We 12/// This returns `Vec` because a module may be included from several places. We
12/// don't handle this case yet though, so the Vec has length at most one. 13/// don't handle this case yet though, so the Vec has length at most one.
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index ebded715d..b47f8bcd9 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -17,6 +17,7 @@ mod search_scope;
17use hir::{InFile, SourceBinder}; 17use hir::{InFile, SourceBinder};
18use once_cell::unsync::Lazy; 18use once_cell::unsync::Lazy;
19use ra_db::{SourceDatabase, SourceDatabaseExt}; 19use ra_db::{SourceDatabase, SourceDatabaseExt};
20use ra_ide_db::RootDatabase;
20use ra_prof::profile; 21use ra_prof::profile;
21use ra_syntax::{ 22use ra_syntax::{
22 algo::find_node_at_offset, 23 algo::find_node_at_offset,
@@ -24,9 +25,7 @@ use ra_syntax::{
24 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset, 25 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset,
25}; 26};
26 27
27use crate::{ 28use crate::{display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
28 db::RootDatabase, display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo,
29};
30 29
31pub(crate) use self::{ 30pub(crate) use self::{
32 classify::{classify_name, classify_name_ref}, 31 classify::{classify_name, classify_name_ref},
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index 46cba30a3..758ea4e8b 100644
--- a/crates/ra_ide/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -9,7 +9,7 @@ use super::{
9 name_definition::{from_assoc_item, from_module_def, from_struct_field}, 9 name_definition::{from_assoc_item, from_module_def, from_struct_field},
10 NameDefinition, NameKind, 10 NameDefinition, NameKind,
11}; 11};
12use crate::db::RootDatabase; 12use ra_ide_db::RootDatabase;
13 13
14pub(crate) fn classify_name( 14pub(crate) fn classify_name(
15 sb: &mut SourceBinder<RootDatabase>, 15 sb: &mut SourceBinder<RootDatabase>,
diff --git a/crates/ra_ide/src/references/name_definition.rs b/crates/ra_ide/src/references/name_definition.rs
index 1e4226ab9..71565e6d3 100644
--- a/crates/ra_ide/src/references/name_definition.rs
+++ b/crates/ra_ide/src/references/name_definition.rs
@@ -9,7 +9,7 @@ use hir::{
9}; 9};
10use ra_syntax::{ast, ast::VisibilityOwner}; 10use ra_syntax::{ast, ast::VisibilityOwner};
11 11
12use crate::db::RootDatabase; 12use ra_ide_db::RootDatabase;
13 13
14#[derive(Debug, PartialEq, Eq)] 14#[derive(Debug, PartialEq, Eq)]
15pub enum NameKind { 15pub enum NameKind {
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index 9a84c1c88..08e77c01f 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -2,14 +2,14 @@
2 2
3use hir::ModuleSource; 3use hir::ModuleSource;
4use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt}; 4use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt};
5use ra_ide_db::RootDatabase;
5use ra_syntax::{ 6use ra_syntax::{
6 algo::find_node_at_offset, ast, lex_single_valid_syntax_kind, AstNode, SyntaxKind, SyntaxNode, 7 algo::find_node_at_offset, ast, lex_single_valid_syntax_kind, AstNode, SyntaxKind, SyntaxNode,
7}; 8};
8use ra_text_edit::TextEdit; 9use ra_text_edit::TextEdit;
9 10
10use crate::{ 11use crate::{
11 db::RootDatabase, FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, 12 FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, SourceFileEdit, TextRange,
12 SourceFileEdit, TextRange,
13}; 13};
14 14
15use super::find_all_refs; 15use super::find_all_refs;
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index f8211a746..97c65c2cd 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -10,7 +10,7 @@ use ra_prof::profile;
10use ra_syntax::{AstNode, TextRange}; 10use ra_syntax::{AstNode, TextRange};
11use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
12 12
13use crate::db::RootDatabase; 13use ra_ide_db::RootDatabase;
14 14
15use super::{NameDefinition, NameKind}; 15use super::{NameDefinition, NameKind};
16 16
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 8622dd956..b6b0c70f9 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -3,12 +3,13 @@
3use hir::InFile; 3use hir::InFile;
4use itertools::Itertools; 4use itertools::Itertools;
5use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
6use ra_ide_db::RootDatabase;
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, 8 ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner},
8 match_ast, SyntaxNode, TextRange, 9 match_ast, SyntaxNode, TextRange,
9}; 10};
10 11
11use crate::{db::RootDatabase, FileId}; 12use crate::FileId;
12 13
13#[derive(Debug)] 14#[derive(Debug)]
14pub struct Runnable { 15pub struct Runnable {
diff --git a/crates/ra_ide/src/status.rs b/crates/ra_ide/src/status.rs
index 1bb27eb85..30eb5c995 100644
--- a/crates/ra_ide/src/status.rs
+++ b/crates/ra_ide/src/status.rs
@@ -10,14 +10,14 @@ use ra_db::{
10 }, 10 },
11 FileTextQuery, SourceRootId, 11 FileTextQuery, SourceRootId,
12}; 12};
13use ra_ide_db::{
14 symbol_index::{LibrarySymbolsQuery, SymbolIndex},
15 RootDatabase,
16};
13use ra_prof::{memory_usage, Bytes}; 17use ra_prof::{memory_usage, Bytes};
14use ra_syntax::{ast, Parse, SyntaxNode}; 18use ra_syntax::{ast, Parse, SyntaxNode};
15 19
16use crate::{ 20use crate::FileId;
17 db::RootDatabase,
18 symbol_index::{LibrarySymbolsQuery, SymbolIndex},
19 FileId,
20};
21 21
22fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { 22fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
23 db.query(ra_db::ParseQuery).entries::<SyntaxTreeStats>() 23 db.query(ra_db::ParseQuery).entries::<SyntaxTreeStats>()
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 530b984fc..c5d249fe8 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -4,6 +4,7 @@ use rustc_hash::FxHashMap;
4 4
5use hir::{HirFileId, InFile, Name, SourceAnalyzer, SourceBinder}; 5use hir::{HirFileId, InFile, Name, SourceAnalyzer, SourceBinder};
6use ra_db::SourceDatabase; 6use ra_db::SourceDatabase;
7use ra_ide_db::RootDatabase;
7use ra_prof::profile; 8use ra_prof::profile;
8use ra_syntax::{ 9use ra_syntax::{
9 ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, TextRange, 10 ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, TextRange,
@@ -11,7 +12,6 @@ use ra_syntax::{
11}; 12};
12 13
13use crate::{ 14use crate::{
14 db::RootDatabase,
15 expand::descend_into_macros_with_analyzer, 15 expand::descend_into_macros_with_analyzer,
16 references::{ 16 references::{
17 classify_name, classify_name_ref, 17 classify_name, classify_name_ref,
diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index 4d0f0fc47..55966daf3 100644
--- a/crates/ra_ide/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use crate::db::RootDatabase;
4use ra_db::SourceDatabase; 3use ra_db::SourceDatabase;
4use ra_ide_db::RootDatabase;
5use ra_syntax::{ 5use ra_syntax::{
6 algo, AstNode, NodeOrToken, SourceFile, 6 algo, AstNode, NodeOrToken, SourceFile,
7 SyntaxKind::{RAW_STRING, STRING}, 7 SyntaxKind::{RAW_STRING, STRING},
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs
index 21e5be9b3..e5d1779fd 100644
--- a/crates/ra_ide/src/typing.rs
+++ b/crates/ra_ide/src/typing.rs
@@ -15,6 +15,7 @@
15 15
16use ra_db::{FilePosition, SourceDatabase}; 16use ra_db::{FilePosition, SourceDatabase};
17use ra_fmt::leading_indent; 17use ra_fmt::leading_indent;
18use ra_ide_db::RootDatabase;
18use ra_syntax::{ 19use ra_syntax::{
19 algo::find_node_at_offset, 20 algo::find_node_at_offset,
20 ast::{self, AstToken}, 21 ast::{self, AstToken},
@@ -24,7 +25,7 @@ use ra_syntax::{
24}; 25};
25use ra_text_edit::TextEdit; 26use ra_text_edit::TextEdit;
26 27
27use crate::{db::RootDatabase, source_change::SingleFileChange, SourceChange, SourceFileEdit}; 28use crate::{source_change::SingleFileChange, SourceChange, SourceFileEdit};
28 29
29pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { 30pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
30 let parse = db.parse(position.file_id); 31 let parse = db.parse(position.file_id);
diff --git a/crates/ra_ide_db/Cargo.toml b/crates/ra_ide_db/Cargo.toml
new file mode 100644
index 000000000..1b7905eb3
--- /dev/null
+++ b/crates/ra_ide_db/Cargo.toml
@@ -0,0 +1,48 @@
1[package]
2edition = "2018"
3name = "ra_ide_db"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6
7[lib]
8doctest = false
9
10[features]
11wasm = []
12
13[dependencies]
14either = "1.5"
15format-buf = "1.0.0"
16indexmap = "1.3.0"
17itertools = "0.8.0"
18join_to_string = "0.1.3"
19log = "0.4.5"
20rayon = "1.0.2"
21fst = { version = "0.3.1", default-features = false }
22rustc-hash = "1.0"
23unicase = "2.2.0"
24superslice = "1.0.0"
25rand = { version = "0.7.0", features = ["small_rng"] }
26once_cell = "1.2.0"
27
28ra_syntax = { path = "../ra_syntax" }
29ra_text_edit = { path = "../ra_text_edit" }
30ra_db = { path = "../ra_db" }
31ra_cfg = { path = "../ra_cfg" }
32ra_fmt = { path = "../ra_fmt" }
33ra_prof = { path = "../ra_prof" }
34test_utils = { path = "../test_utils" }
35ra_assists = { path = "../ra_assists" }
36
37# ra_ide should depend only on the top-level `hir` package. if you need
38# something from some `hir_xxx` subpackage, reexport the API via `hir`.
39hir = { path = "../ra_hir", package = "ra_hir" }
40
41[dev-dependencies]
42insta = "0.13.0"
43
44[dev-dependencies.proptest]
45version = "0.9.0"
46# Disable `fork` feature to allow compiling on webassembly
47default-features = false
48features = ["std", "bit-set", "break-dead-code"]
diff --git a/crates/ra_ide/src/change.rs b/crates/ra_ide_db/src/change.rs
index 18dad2ea3..4668784d3 100644
--- a/crates/ra_ide/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -1,4 +1,5 @@
1//! FIXME: write short doc here 1//! Defines a unit of change that can applied to a state of IDE to get the next
2//! state. Changes are transactional.
2 3
3use std::{fmt, sync::Arc, time}; 4use std::{fmt, sync::Arc, time};
4 5
@@ -14,8 +15,8 @@ use rayon::prelude::*;
14use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
15 16
16use crate::{ 17use crate::{
17 db::{DebugData, RootDatabase},
18 symbol_index::{SymbolIndex, SymbolsDatabase}, 18 symbol_index::{SymbolIndex, SymbolsDatabase},
19 DebugData, RootDatabase,
19}; 20};
20 21
21#[derive(Default)] 22#[derive(Default)]
@@ -168,12 +169,12 @@ impl LibraryData {
168const GC_COOLDOWN: time::Duration = time::Duration::from_millis(100); 169const GC_COOLDOWN: time::Duration = time::Duration::from_millis(100);
169 170
170impl RootDatabase { 171impl RootDatabase {
171 pub(crate) fn request_cancellation(&mut self) { 172 pub fn request_cancellation(&mut self) {
172 let _p = profile("RootDatabase::request_cancellation"); 173 let _p = profile("RootDatabase::request_cancellation");
173 self.salsa_runtime_mut().synthetic_write(Durability::LOW); 174 self.salsa_runtime_mut().synthetic_write(Durability::LOW);
174 } 175 }
175 176
176 pub(crate) fn apply_change(&mut self, change: AnalysisChange) { 177 pub fn apply_change(&mut self, change: AnalysisChange) {
177 let _p = profile("RootDatabase::apply_change"); 178 let _p = profile("RootDatabase::apply_change");
178 self.request_cancellation(); 179 self.request_cancellation();
179 log::info!("apply_change {:?}", change); 180 log::info!("apply_change {:?}", change);
@@ -245,7 +246,7 @@ impl RootDatabase {
245 self.set_source_root_with_durability(root_id, Arc::new(source_root), durability); 246 self.set_source_root_with_durability(root_id, Arc::new(source_root), durability);
246 } 247 }
247 248
248 pub(crate) fn maybe_collect_garbage(&mut self) { 249 pub fn maybe_collect_garbage(&mut self) {
249 if cfg!(feature = "wasm") { 250 if cfg!(feature = "wasm") {
250 return; 251 return;
251 } 252 }
@@ -255,7 +256,7 @@ impl RootDatabase {
255 } 256 }
256 } 257 }
257 258
258 pub(crate) fn collect_garbage(&mut self) { 259 pub fn collect_garbage(&mut self) {
259 if cfg!(feature = "wasm") { 260 if cfg!(feature = "wasm") {
260 return; 261 return;
261 } 262 }
@@ -282,7 +283,7 @@ impl RootDatabase {
282 self.query(hir::db::BodyQuery).sweep(sweep); 283 self.query(hir::db::BodyQuery).sweep(sweep);
283 } 284 }
284 285
285 pub(crate) fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { 286 pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> {
286 let mut acc: Vec<(String, Bytes)> = vec![]; 287 let mut acc: Vec<(String, Bytes)> = vec![];
287 let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); 288 let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();
288 macro_rules! sweep_each_query { 289 macro_rules! sweep_each_query {
diff --git a/crates/ra_ide/src/feature_flags.rs b/crates/ra_ide_db/src/feature_flags.rs
index 85617640d..1b3cabf4d 100644
--- a/crates/ra_ide/src/feature_flags.rs
+++ b/crates/ra_ide_db/src/feature_flags.rs
@@ -1,4 +1,4 @@
1//! FIXME: write short doc here 1//! See docs for `FeatureFlags`.
2 2
3use rustc_hash::FxHashMap; 3use rustc_hash::FxHashMap;
4 4
diff --git a/crates/ra_ide/src/db.rs b/crates/ra_ide_db/src/lib.rs
index 47d0aed6f..e922d1e5f 100644
--- a/crates/ra_ide/src/db.rs
+++ b/crates/ra_ide_db/src/lib.rs
@@ -1,4 +1,13 @@
1//! FIXME: write short doc here 1//! This crate defines the core datastructure representing IDE state -- `RootDatabase`.
2//!
3//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
4
5pub mod line_index;
6pub mod line_index_utils;
7pub mod feature_flags;
8pub mod symbol_index;
9pub mod change;
10mod wasm_shims;
2 11
3use std::sync::Arc; 12use std::sync::Arc;
4 13
@@ -9,10 +18,7 @@ use ra_db::{
9}; 18};
10use rustc_hash::FxHashMap; 19use rustc_hash::FxHashMap;
11 20
12use crate::{ 21use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::SymbolsDatabase};
13 symbol_index::{self, SymbolsDatabase},
14 FeatureFlags, LineIndex,
15};
16 22
17#[salsa::database( 23#[salsa::database(
18 ra_db::SourceDatabaseStorage, 24 ra_db::SourceDatabaseStorage,
@@ -25,12 +31,12 @@ use crate::{
25 hir::db::HirDatabaseStorage 31 hir::db::HirDatabaseStorage
26)] 32)]
27#[derive(Debug)] 33#[derive(Debug)]
28pub(crate) struct RootDatabase { 34pub struct RootDatabase {
29 runtime: salsa::Runtime<RootDatabase>, 35 runtime: salsa::Runtime<RootDatabase>,
30 pub(crate) feature_flags: Arc<FeatureFlags>, 36 pub feature_flags: Arc<FeatureFlags>,
31 pub(crate) debug_data: Arc<DebugData>, 37 pub(crate) debug_data: Arc<DebugData>,
32 pub(crate) last_gc: crate::wasm_shims::Instant, 38 pub last_gc: crate::wasm_shims::Instant,
33 pub(crate) last_gc_check: crate::wasm_shims::Instant, 39 pub last_gc_check: crate::wasm_shims::Instant,
34} 40}
35 41
36impl FileLoader for RootDatabase { 42impl FileLoader for RootDatabase {
@@ -109,7 +115,7 @@ impl salsa::ParallelDatabase for RootDatabase {
109} 115}
110 116
111#[salsa::query_group(LineIndexDatabaseStorage)] 117#[salsa::query_group(LineIndexDatabaseStorage)]
112pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled { 118pub trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
113 fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; 119 fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
114} 120}
115 121
diff --git a/crates/ra_ide/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs
index 710890d27..452c87ac5 100644
--- a/crates/ra_ide/src/line_index.rs
+++ b/crates/ra_ide_db/src/line_index.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! `LineIndex` maps flat `TextUnit` offsets into `(Line, Column)`
2//! representation.
2 3
3use crate::TextUnit; 4use ra_syntax::TextUnit;
4use rustc_hash::FxHashMap; 5use rustc_hash::FxHashMap;
5use superslice::Ext; 6use superslice::Ext;
6 7
diff --git a/crates/ra_ide/src/line_index_utils.rs b/crates/ra_ide_db/src/line_index_utils.rs
index bd1e08feb..435b06511 100644
--- a/crates/ra_ide/src/line_index_utils.rs
+++ b/crates/ra_ide_db/src/line_index_utils.rs
@@ -1,9 +1,87 @@
1//! FIXME: write short doc here 1//! Code actions can specify desirable final position of the cursor.
2//!
3//! The position is specified as a `TextUnit` in the final file. We need to send
4//! it in `(Line, Column)` coordinate though. However, we only have a LineIndex
5//! for a file pre-edit!
6//!
7//! Code in this module applies this "to (Line, Column) after edit"
8//! transformation.
2 9
3use crate::{line_index::Utf16Char, LineCol, LineIndex};
4use ra_syntax::{TextRange, TextUnit}; 10use ra_syntax::{TextRange, TextUnit};
5use ra_text_edit::{AtomTextEdit, TextEdit}; 11use ra_text_edit::{AtomTextEdit, TextEdit};
6 12
13use crate::line_index::{LineCol, LineIndex, Utf16Char};
14
15pub fn translate_offset_with_edit(
16 line_index: &LineIndex,
17 offset: TextUnit,
18 text_edit: &TextEdit,
19) -> LineCol {
20 let mut state = Edits::from_text_edit(&text_edit);
21
22 let mut res = RunningLineCol::new();
23
24 macro_rules! test_step {
25 ($x:ident) => {
26 match &$x {
27 Step::Newline(n) => {
28 if offset < *n {
29 return res.to_line_col(offset);
30 } else {
31 res.add_line(*n);
32 }
33 }
34 Step::Utf16Char(x) => {
35 if offset < x.end() {
36 // if the offset is inside a multibyte char it's invalid
37 // clamp it to the start of the char
38 let clamp = offset.min(x.start());
39 return res.to_line_col(clamp);
40 } else {
41 res.adjust_col(*x);
42 }
43 }
44 }
45 };
46 }
47
48 for orig_step in LineIndexStepIter::from(line_index) {
49 loop {
50 let translated_step = state.translate_step(&orig_step);
51 match state.next_steps(&translated_step) {
52 NextSteps::Use => {
53 test_step!(translated_step);
54 break;
55 }
56 NextSteps::ReplaceMany(ns) => {
57 for n in ns {
58 test_step!(n);
59 }
60 break;
61 }
62 NextSteps::AddMany(ns) => {
63 for n in ns {
64 test_step!(n);
65 }
66 }
67 }
68 }
69 }
70
71 loop {
72 match state.next_inserted_steps() {
73 None => break,
74 Some(ns) => {
75 for n in ns {
76 test_step!(n);
77 }
78 }
79 }
80 }
81
82 res.to_line_col(offset)
83}
84
7#[derive(Debug, Clone)] 85#[derive(Debug, Clone)]
8enum Step { 86enum Step {
9 Newline(TextUnit), 87 Newline(TextUnit),
@@ -17,7 +95,7 @@ struct LineIndexStepIter<'a> {
17 utf16_chars: Option<(TextUnit, std::slice::Iter<'a, Utf16Char>)>, 95 utf16_chars: Option<(TextUnit, std::slice::Iter<'a, Utf16Char>)>,
18} 96}
19 97
20impl<'a> LineIndexStepIter<'a> { 98impl LineIndexStepIter<'_> {
21 fn from(line_index: &LineIndex) -> LineIndexStepIter { 99 fn from(line_index: &LineIndex) -> LineIndexStepIter {
22 let mut x = LineIndexStepIter { line_index, next_newline_idx: 0, utf16_chars: None }; 100 let mut x = LineIndexStepIter { line_index, next_newline_idx: 0, utf16_chars: None };
23 // skip first newline since it's not real 101 // skip first newline since it's not real
@@ -26,7 +104,7 @@ impl<'a> LineIndexStepIter<'a> {
26 } 104 }
27} 105}
28 106
29impl<'a> Iterator for LineIndexStepIter<'a> { 107impl Iterator for LineIndexStepIter<'_> {
30 type Item = Step; 108 type Item = Step;
31 fn next(&mut self) -> Option<Step> { 109 fn next(&mut self) -> Option<Step> {
32 self.utf16_chars 110 self.utf16_chars
@@ -54,7 +132,7 @@ struct OffsetStepIter<'a> {
54 offset: TextUnit, 132 offset: TextUnit,
55} 133}
56 134
57impl<'a> Iterator for OffsetStepIter<'a> { 135impl Iterator for OffsetStepIter<'_> {
58 type Item = Step; 136 type Item = Step;
59 fn next(&mut self) -> Option<Step> { 137 fn next(&mut self) -> Option<Step> {
60 let (next, next_offset) = self 138 let (next, next_offset) = self
@@ -220,84 +298,16 @@ impl RunningLineCol {
220 } 298 }
221} 299}
222 300
223pub fn translate_offset_with_edit(
224 line_index: &LineIndex,
225 offset: TextUnit,
226 text_edit: &TextEdit,
227) -> LineCol {
228 let mut state = Edits::from_text_edit(&text_edit);
229
230 let mut res = RunningLineCol::new();
231
232 macro_rules! test_step {
233 ($x:ident) => {
234 match &$x {
235 Step::Newline(n) => {
236 if offset < *n {
237 return res.to_line_col(offset);
238 } else {
239 res.add_line(*n);
240 }
241 }
242 Step::Utf16Char(x) => {
243 if offset < x.end() {
244 // if the offset is inside a multibyte char it's invalid
245 // clamp it to the start of the char
246 let clamp = offset.min(x.start());
247 return res.to_line_col(clamp);
248 } else {
249 res.adjust_col(*x);
250 }
251 }
252 }
253 };
254 }
255
256 for orig_step in LineIndexStepIter::from(line_index) {
257 loop {
258 let translated_step = state.translate_step(&orig_step);
259 match state.next_steps(&translated_step) {
260 NextSteps::Use => {
261 test_step!(translated_step);
262 break;
263 }
264 NextSteps::ReplaceMany(ns) => {
265 for n in ns {
266 test_step!(n);
267 }
268 break;
269 }
270 NextSteps::AddMany(ns) => {
271 for n in ns {
272 test_step!(n);
273 }
274 }
275 }
276 }
277 }
278
279 loop {
280 match state.next_inserted_steps() {
281 None => break,
282 Some(ns) => {
283 for n in ns {
284 test_step!(n);
285 }
286 }
287 }
288 }
289
290 res.to_line_col(offset)
291}
292
293#[cfg(test)] 301#[cfg(test)]
294mod test { 302mod test {
295 use super::*;
296 use crate::line_index;
297 use proptest::{prelude::*, proptest}; 303 use proptest::{prelude::*, proptest};
298 use ra_text_edit::test_utils::{arb_offset, arb_text_with_edit}; 304 use ra_text_edit::test_utils::{arb_offset, arb_text_with_edit};
299 use ra_text_edit::TextEdit; 305 use ra_text_edit::TextEdit;
300 306
307 use crate::line_index;
308
309 use super::*;
310
301 #[derive(Debug)] 311 #[derive(Debug)]
302 struct ArbTextWithEditAndOffset { 312 struct ArbTextWithEditAndOffset {
303 text: String, 313 text: String,
diff --git a/crates/ra_ide/src/symbol_index.rs b/crates/ra_ide_db/src/symbol_index.rs
index 5729eb5b3..64ddf2f95 100644
--- a/crates/ra_ide/src/symbol_index.rs
+++ b/crates/ra_ide_db/src/symbol_index.rs
@@ -19,6 +19,7 @@
19//! for each library (which is assumed to never change) and an FST for each Rust 19//! for each library (which is assumed to never change) and an FST for each Rust
20//! file in the current workspace, and run a query against the union of all 20//! file in the current workspace, and run a query against the union of all
21//! those FSTs. 21//! those FSTs.
22
22use std::{ 23use std::{
23 fmt, 24 fmt,
24 hash::{Hash, Hasher}, 25 hash::{Hash, Hasher},
@@ -29,7 +30,7 @@ use std::{
29use fst::{self, Streamer}; 30use fst::{self, Streamer};
30use ra_db::{ 31use ra_db::{
31 salsa::{self, ParallelDatabase}, 32 salsa::{self, ParallelDatabase},
32 SourceDatabaseExt, SourceRootId, 33 FileId, SourceDatabaseExt, SourceRootId,
33}; 34};
34use ra_syntax::{ 35use ra_syntax::{
35 ast::{self, NameOwner}, 36 ast::{self, NameOwner},
@@ -40,10 +41,50 @@ use ra_syntax::{
40#[cfg(not(feature = "wasm"))] 41#[cfg(not(feature = "wasm"))]
41use rayon::prelude::*; 42use rayon::prelude::*;
42 43
43use crate::{db::RootDatabase, FileId, Query}; 44use crate::RootDatabase;
45
46#[derive(Debug)]
47pub struct Query {
48 query: String,
49 lowercased: String,
50 only_types: bool,
51 libs: bool,
52 exact: bool,
53 limit: usize,
54}
55
56impl Query {
57 pub fn new(query: String) -> Query {
58 let lowercased = query.to_lowercase();
59 Query {
60 query,
61 lowercased,
62 only_types: false,
63 libs: false,
64 exact: false,
65 limit: usize::max_value(),
66 }
67 }
68
69 pub fn only_types(&mut self) {
70 self.only_types = true;
71 }
72
73 pub fn libs(&mut self) {
74 self.libs = true;
75 }
76
77 pub fn exact(&mut self) {
78 self.exact = true;
79 }
80
81 pub fn limit(&mut self, limit: usize) {
82 self.limit = limit
83 }
84}
44 85
45#[salsa::query_group(SymbolsDatabaseStorage)] 86#[salsa::query_group(SymbolsDatabaseStorage)]
46pub(crate) trait SymbolsDatabase: hir::db::HirDatabase { 87pub trait SymbolsDatabase: hir::db::HirDatabase {
47 fn file_symbols(&self, file_id: FileId) -> Arc<SymbolIndex>; 88 fn file_symbols(&self, file_id: FileId) -> Arc<SymbolIndex>;
48 #[salsa::input] 89 #[salsa::input]
49 fn library_symbols(&self, id: SourceRootId) -> Arc<SymbolIndex>; 90 fn library_symbols(&self, id: SourceRootId) -> Arc<SymbolIndex>;
@@ -68,7 +109,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
68 Arc::new(SymbolIndex::new(symbols)) 109 Arc::new(SymbolIndex::new(symbols))
69} 110}
70 111
71pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> { 112pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
72 /// Need to wrap Snapshot to provide `Clone` impl for `map_with` 113 /// Need to wrap Snapshot to provide `Clone` impl for `map_with`
73 struct Snap(salsa::Snapshot<RootDatabase>); 114 struct Snap(salsa::Snapshot<RootDatabase>);
74 impl Clone for Snap { 115 impl Clone for Snap {
@@ -110,16 +151,16 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol>
110 query.search(&buf) 151 query.search(&buf)
111} 152}
112 153
113pub(crate) fn index_resolve(db: &RootDatabase, name_ref: &ast::NameRef) -> Vec<FileSymbol> { 154pub fn index_resolve(db: &RootDatabase, name_ref: &ast::NameRef) -> Vec<FileSymbol> {
114 let name = name_ref.text(); 155 let name = name_ref.text();
115 let mut query = Query::new(name.to_string()); 156 let mut query = Query::new(name.to_string());
116 query.exact(); 157 query.exact();
117 query.limit(4); 158 query.limit(4);
118 crate::symbol_index::world_symbols(db, query) 159 world_symbols(db, query)
119} 160}
120 161
121#[derive(Default)] 162#[derive(Default)]
122pub(crate) struct SymbolIndex { 163pub struct SymbolIndex {
123 symbols: Vec<FileSymbol>, 164 symbols: Vec<FileSymbol>,
124 map: fst::Map, 165 map: fst::Map,
125} 166}
@@ -178,11 +219,11 @@ impl SymbolIndex {
178 SymbolIndex { symbols, map } 219 SymbolIndex { symbols, map }
179 } 220 }
180 221
181 pub(crate) fn len(&self) -> usize { 222 pub fn len(&self) -> usize {
182 self.symbols.len() 223 self.symbols.len()
183 } 224 }
184 225
185 pub(crate) fn memory_size(&self) -> usize { 226 pub fn memory_size(&self) -> usize {
186 self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>() 227 self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>()
187 } 228 }
188 229
@@ -262,12 +303,12 @@ fn is_type(kind: SyntaxKind) -> bool {
262/// The actual data that is stored in the index. It should be as compact as 303/// The actual data that is stored in the index. It should be as compact as
263/// possible. 304/// possible.
264#[derive(Debug, Clone, PartialEq, Eq, Hash)] 305#[derive(Debug, Clone, PartialEq, Eq, Hash)]
265pub(crate) struct FileSymbol { 306pub struct FileSymbol {
266 pub(crate) file_id: FileId, 307 pub file_id: FileId,
267 pub(crate) name: SmolStr, 308 pub name: SmolStr,
268 pub(crate) ptr: SyntaxNodePtr, 309 pub ptr: SyntaxNodePtr,
269 pub(crate) name_range: Option<TextRange>, 310 pub name_range: Option<TextRange>,
270 pub(crate) container_name: Option<SmolStr>, 311 pub container_name: Option<SmolStr>,
271} 312}
272 313
273fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> { 314fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> {
@@ -329,77 +370,3 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
329 container_name: None, 370 container_name: None,
330 }) 371 })
331} 372}
332
333#[cfg(test)]
334mod tests {
335 use crate::{display::NavigationTarget, mock_analysis::single_file, Query};
336 use ra_syntax::{
337 SmolStr,
338 SyntaxKind::{FN_DEF, STRUCT_DEF},
339 };
340
341 #[test]
342 fn test_world_symbols_with_no_container() {
343 let code = r#"
344 enum FooInner { }
345 "#;
346
347 let mut symbols = get_symbols_matching(code, "FooInner");
348
349 let s = symbols.pop().unwrap();
350
351 assert_eq!(s.name(), "FooInner");
352 assert!(s.container_name().is_none());
353 }
354
355 #[test]
356 fn test_world_symbols_include_container_name() {
357 let code = r#"
358fn foo() {
359 enum FooInner { }
360}
361 "#;
362
363 let mut symbols = get_symbols_matching(code, "FooInner");
364
365 let s = symbols.pop().unwrap();
366
367 assert_eq!(s.name(), "FooInner");
368 assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
369
370 let code = r#"
371mod foo {
372 struct FooInner;
373}
374 "#;
375
376 let mut symbols = get_symbols_matching(code, "FooInner");
377
378 let s = symbols.pop().unwrap();
379
380 assert_eq!(s.name(), "FooInner");
381 assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
382 }
383
384 #[test]
385 fn test_world_symbols_are_case_sensitive() {
386 let code = r#"
387fn foo() {}
388
389struct Foo;
390 "#;
391
392 let symbols = get_symbols_matching(code, "Foo");
393
394 let fn_match = symbols.iter().find(|s| s.name() == "foo").map(|s| s.kind());
395 let struct_match = symbols.iter().find(|s| s.name() == "Foo").map(|s| s.kind());
396
397 assert_eq!(fn_match, Some(FN_DEF));
398 assert_eq!(struct_match, Some(STRUCT_DEF));
399 }
400
401 fn get_symbols_matching(text: &str, query: &str) -> Vec<NavigationTarget> {
402 let (analysis, _) = single_file(text);
403 analysis.symbol_search(Query::new(query.into())).unwrap()
404 }
405}
diff --git a/crates/ra_ide/src/wasm_shims.rs b/crates/ra_ide_db/src/wasm_shims.rs
index 088cc9be4..7af9f9d9b 100644
--- a/crates/ra_ide/src/wasm_shims.rs
+++ b/crates/ra_ide_db/src/wasm_shims.rs
@@ -1,4 +1,4 @@
1//! FIXME: write short doc here 1//! A version of `std::time::Instant` that doesn't panic in WASM.
2 2
3#[cfg(not(feature = "wasm"))] 3#[cfg(not(feature = "wasm"))]
4pub use std::time::Instant; 4pub use std::time::Instant;