diff options
Diffstat (limited to 'crates')
23 files changed, 258 insertions, 122 deletions
diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index a30cdfc9c..a82e1761c 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml | |||
@@ -15,6 +15,7 @@ im = "12.0.0" | |||
15 | ra_syntax = { path = "../ra_syntax" } | 15 | ra_syntax = { path = "../ra_syntax" } |
16 | ra_editor = { path = "../ra_editor" } | 16 | ra_editor = { path = "../ra_editor" } |
17 | salsa = { path = "../salsa" } | 17 | salsa = { path = "../salsa" } |
18 | rustc-hash = "1.0" | ||
18 | 19 | ||
19 | [dev-dependencies] | 20 | [dev-dependencies] |
20 | test_utils = { path = "../test_utils" } | 21 | test_utils = { path = "../test_utils" } |
diff --git a/crates/ra_analysis/src/db/imp.rs b/crates/ra_analysis/src/db/imp.rs index f26be1046..36f6cf290 100644 --- a/crates/ra_analysis/src/db/imp.rs +++ b/crates/ra_analysis/src/db/imp.rs | |||
@@ -2,9 +2,10 @@ use std::{ | |||
2 | sync::Arc, | 2 | sync::Arc, |
3 | any::Any, | 3 | any::Any, |
4 | hash::{Hash, Hasher}, | 4 | hash::{Hash, Hasher}, |
5 | collections::hash_map::{DefaultHasher, HashMap}, | 5 | collections::hash_map::{DefaultHasher}, |
6 | iter, | 6 | iter, |
7 | }; | 7 | }; |
8 | use rustc_hash::FxHashMap; | ||
8 | use salsa; | 9 | use salsa; |
9 | use {FileId, imp::FileResolverImp}; | 10 | use {FileId, imp::FileResolverImp}; |
10 | use super::{State, Query, QueryCtx}; | 11 | use super::{State, Query, QueryCtx}; |
@@ -13,7 +14,7 @@ pub(super) type Data = Arc<Any + Send + Sync + 'static>; | |||
13 | 14 | ||
14 | #[derive(Debug)] | 15 | #[derive(Debug)] |
15 | pub(super) struct Db { | 16 | pub(super) struct Db { |
16 | names: Arc<HashMap<salsa::QueryTypeId, &'static str>>, | 17 | names: Arc<FxHashMap<salsa::QueryTypeId, &'static str>>, |
17 | pub(super) imp: salsa::Db<State, Data>, | 18 | pub(super) imp: salsa::Db<State, Data>, |
18 | } | 19 | } |
19 | 20 | ||
@@ -85,7 +86,7 @@ where | |||
85 | 86 | ||
86 | pub(super) struct QueryRegistry { | 87 | pub(super) struct QueryRegistry { |
87 | config: Option<salsa::QueryConfig<State, Data>>, | 88 | config: Option<salsa::QueryConfig<State, Data>>, |
88 | names: HashMap<salsa::QueryTypeId, &'static str>, | 89 | names: FxHashMap<salsa::QueryTypeId, &'static str>, |
89 | } | 90 | } |
90 | 91 | ||
91 | impl QueryRegistry { | 92 | impl QueryRegistry { |
@@ -109,7 +110,7 @@ impl QueryRegistry { | |||
109 | (Arc::new(res), fingerprint) | 110 | (Arc::new(res), fingerprint) |
110 | }) | 111 | }) |
111 | ); | 112 | ); |
112 | let mut names = HashMap::new(); | 113 | let mut names = FxHashMap::default(); |
113 | names.insert(FILE_TEXT, "FILE_TEXT"); | 114 | names.insert(FILE_TEXT, "FILE_TEXT"); |
114 | names.insert(FILE_SET, "FILE_SET"); | 115 | names.insert(FILE_SET, "FILE_SET"); |
115 | QueryRegistry { config: Some(config), names } | 116 | QueryRegistry { config: Some(config), names } |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 517867e86..47bc0032b 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -4,11 +4,12 @@ use std::{ | |||
4 | atomic::{AtomicBool, Ordering::SeqCst}, | 4 | atomic::{AtomicBool, Ordering::SeqCst}, |
5 | }, | 5 | }, |
6 | fmt, | 6 | fmt, |
7 | collections::{HashSet, VecDeque}, | 7 | collections::VecDeque, |
8 | iter, | 8 | iter, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use relative_path::RelativePath; | 11 | use relative_path::RelativePath; |
12 | use rustc_hash::FxHashSet; | ||
12 | use ra_editor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit, resolve_local_name}; | 13 | use ra_editor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit, resolve_local_name}; |
13 | use ra_syntax::{ | 14 | use ra_syntax::{ |
14 | TextUnit, TextRange, SmolStr, File, AstNode, | 15 | TextUnit, TextRange, SmolStr, File, AstNode, |
@@ -84,7 +85,7 @@ impl AnalysisHostImpl { | |||
84 | data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver))); | 85 | data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver))); |
85 | } | 86 | } |
86 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { | 87 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { |
87 | let mut visited = HashSet::new(); | 88 | let mut visited = FxHashSet::default(); |
88 | for &file_id in graph.crate_roots.values() { | 89 | for &file_id in graph.crate_roots.values() { |
89 | if !visited.insert(file_id) { | 90 | if !visited.insert(file_id) { |
90 | panic!("duplicate crate root: {:?}", file_id); | 91 | panic!("duplicate crate root: {:?}", file_id); |
@@ -168,7 +169,7 @@ impl AnalysisImpl { | |||
168 | let mut res = Vec::new(); | 169 | let mut res = Vec::new(); |
169 | let mut work = VecDeque::new(); | 170 | let mut work = VecDeque::new(); |
170 | work.push_back(file_id); | 171 | work.push_back(file_id); |
171 | let mut visited = HashSet::new(); | 172 | let mut visited = FxHashSet::default(); |
172 | while let Some(id) = work.pop_front() { | 173 | while let Some(id) = work.pop_front() { |
173 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { | 174 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { |
174 | res.push(crate_id); | 175 | res.push(crate_id); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index f6ceb7eb2..849fd93e4 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -11,6 +11,7 @@ extern crate relative_path; | |||
11 | extern crate crossbeam_channel; | 11 | extern crate crossbeam_channel; |
12 | extern crate im; | 12 | extern crate im; |
13 | extern crate salsa; | 13 | extern crate salsa; |
14 | extern crate rustc_hash; | ||
14 | 15 | ||
15 | mod symbol_index; | 16 | mod symbol_index; |
16 | mod module_map; | 17 | mod module_map; |
@@ -23,13 +24,13 @@ mod descriptors; | |||
23 | 24 | ||
24 | use std::{ | 25 | use std::{ |
25 | sync::Arc, | 26 | sync::Arc, |
26 | collections::HashMap, | ||
27 | fmt::Debug, | 27 | fmt::Debug, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | use relative_path::{RelativePath, RelativePathBuf}; | 30 | use relative_path::{RelativePath, RelativePathBuf}; |
31 | use ra_syntax::{File, TextRange, TextUnit, AtomEdit}; | 31 | use ra_syntax::{File, TextRange, TextUnit, AtomEdit}; |
32 | use imp::{AnalysisImpl, AnalysisHostImpl, FileResolverImp}; | 32 | use imp::{AnalysisImpl, AnalysisHostImpl, FileResolverImp}; |
33 | use rustc_hash::FxHashMap; | ||
33 | 34 | ||
34 | pub use ra_editor::{ | 35 | pub use ra_editor::{ |
35 | StructureNode, LineIndex, FileSymbol, | 36 | StructureNode, LineIndex, FileSymbol, |
@@ -46,7 +47,7 @@ pub struct CrateId(pub u32); | |||
46 | 47 | ||
47 | #[derive(Debug, Clone, Default)] | 48 | #[derive(Debug, Clone, Default)] |
48 | pub struct CrateGraph { | 49 | pub struct CrateGraph { |
49 | pub crate_roots: HashMap<CrateId, FileId>, | 50 | pub crate_roots: FxHashMap<CrateId, FileId>, |
50 | } | 51 | } |
51 | 52 | ||
52 | pub trait FileResolver: Debug + Send + Sync + 'static { | 53 | pub trait FileResolver: Debug + Send + Sync + 'static { |
diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 1835a9b25..32a8c5bd0 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs | |||
@@ -1,11 +1,11 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | collections::HashMap, | ||
3 | sync::Arc, | 2 | sync::Arc, |
4 | panic, | 3 | panic, |
5 | }; | 4 | }; |
6 | 5 | ||
7 | use once_cell::sync::OnceCell; | 6 | use once_cell::sync::OnceCell; |
8 | use rayon::prelude::*; | 7 | use rayon::prelude::*; |
8 | use rustc_hash::FxHashMap; | ||
9 | use ra_editor::LineIndex; | 9 | use ra_editor::LineIndex; |
10 | use ra_syntax::File; | 10 | use ra_syntax::File; |
11 | 11 | ||
@@ -118,7 +118,7 @@ impl FileData { | |||
118 | #[derive(Debug)] | 118 | #[derive(Debug)] |
119 | pub(crate) struct ReadonlySourceRoot { | 119 | pub(crate) struct ReadonlySourceRoot { |
120 | symbol_index: Arc<SymbolIndex>, | 120 | symbol_index: Arc<SymbolIndex>, |
121 | file_map: HashMap<FileId, FileData>, | 121 | file_map: FxHashMap<FileId, FileData>, |
122 | module_tree: Arc<ModuleTreeDescriptor>, | 122 | module_tree: Arc<ModuleTreeDescriptor>, |
123 | } | 123 | } |
124 | 124 | ||
@@ -139,7 +139,7 @@ impl ReadonlySourceRoot { | |||
139 | let symbol_index = SymbolIndex::for_files( | 139 | let symbol_index = SymbolIndex::for_files( |
140 | modules.par_iter().map(|it| (it.0, it.1.clone())) | 140 | modules.par_iter().map(|it| (it.0, it.1.clone())) |
141 | ); | 141 | ); |
142 | let file_map: HashMap<FileId, FileData> = files | 142 | let file_map: FxHashMap<FileId, FileData> = files |
143 | .into_iter() | 143 | .into_iter() |
144 | .map(|(id, text)| (id, FileData::new(text))) | 144 | .map(|(id, text)| (id, FileData::new(text))) |
145 | .collect(); | 145 | .collect(); |
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 334dc5e48..a886cd0ff 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs | |||
@@ -1,12 +1,13 @@ | |||
1 | extern crate relative_path; | 1 | extern crate relative_path; |
2 | extern crate ra_analysis; | 2 | extern crate ra_analysis; |
3 | extern crate rustc_hash; | ||
3 | extern crate test_utils; | 4 | extern crate test_utils; |
4 | 5 | ||
5 | use std::{ | 6 | use std::{ |
6 | sync::Arc, | 7 | sync::Arc, |
7 | collections::HashMap, | ||
8 | }; | 8 | }; |
9 | 9 | ||
10 | use rustc_hash::FxHashMap; | ||
10 | use relative_path::{RelativePath, RelativePathBuf}; | 11 | use relative_path::{RelativePath, RelativePathBuf}; |
11 | use ra_analysis::{Analysis, AnalysisHost, FileId, FileResolver, JobHandle, CrateGraph, CrateId}; | 12 | use ra_analysis::{Analysis, AnalysisHost, FileId, FileResolver, JobHandle, CrateGraph, CrateId}; |
12 | use test_utils::assert_eq_dbg; | 13 | use test_utils::assert_eq_dbg; |
@@ -131,7 +132,7 @@ fn test_resolve_crate_root() { | |||
131 | 132 | ||
132 | let crate_graph = CrateGraph { | 133 | let crate_graph = CrateGraph { |
133 | crate_roots: { | 134 | crate_roots: { |
134 | let mut m = HashMap::new(); | 135 | let mut m = FxHashMap::default(); |
135 | m.insert(CrateId(1), FileId(1)); | 136 | m.insert(CrateId(1), FileId(1)); |
136 | m | 137 | m |
137 | }, | 138 | }, |
diff --git a/crates/ra_editor/Cargo.toml b/crates/ra_editor/Cargo.toml index 40e3254ff..91cefc8d7 100644 --- a/crates/ra_editor/Cargo.toml +++ b/crates/ra_editor/Cargo.toml | |||
@@ -8,6 +8,7 @@ publish = false | |||
8 | itertools = "0.7.8" | 8 | itertools = "0.7.8" |
9 | superslice = "0.1.0" | 9 | superslice = "0.1.0" |
10 | join_to_string = "0.1.1" | 10 | join_to_string = "0.1.1" |
11 | rustc-hash = "1.0" | ||
11 | 12 | ||
12 | ra_syntax = { path = "../ra_syntax" } | 13 | ra_syntax = { path = "../ra_syntax" } |
13 | 14 | ||
diff --git a/crates/ra_editor/src/completion.rs b/crates/ra_editor/src/completion.rs index 570d72d66..20b8484b3 100644 --- a/crates/ra_editor/src/completion.rs +++ b/crates/ra_editor/src/completion.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::collections::{HashSet, HashMap}; | 1 | use rustc_hash::{FxHashMap, FxHashSet}; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*, | 4 | File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*, |
@@ -96,7 +96,7 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi | |||
96 | } | 96 | } |
97 | 97 | ||
98 | fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { | 98 | fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { |
99 | let mut params = HashMap::new(); | 99 | let mut params = FxHashMap::default(); |
100 | for node in ctx.ancestors() { | 100 | for node in ctx.ancestors() { |
101 | let _ = visitor_ctx(&mut params) | 101 | let _ = visitor_ctx(&mut params) |
102 | .visit::<ast::Root, _>(process) | 102 | .visit::<ast::Root, _>(process) |
@@ -114,7 +114,7 @@ fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { | |||
114 | }) | 114 | }) |
115 | }); | 115 | }); |
116 | 116 | ||
117 | fn process<'a, N: ast::FnDefOwner<'a>>(node: N, params: &mut HashMap<String, (u32, ast::Param<'a>)>) { | 117 | fn process<'a, N: ast::FnDefOwner<'a>>(node: N, params: &mut FxHashMap<String, (u32, ast::Param<'a>)>) { |
118 | node.functions() | 118 | node.functions() |
119 | .filter_map(|it| it.param_list()) | 119 | .filter_map(|it| it.param_list()) |
120 | .flat_map(|it| it.params()) | 120 | .flat_map(|it| it.params()) |
@@ -232,7 +232,7 @@ fn complete_mod_item_snippets(acc: &mut Vec<CompletionItem>) { | |||
232 | } | 232 | } |
233 | 233 | ||
234 | fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) { | 234 | fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) { |
235 | let mut shadowed = HashSet::new(); | 235 | let mut shadowed = FxHashSet::default(); |
236 | acc.extend( | 236 | acc.extend( |
237 | scopes.scope_chain(name_ref.syntax()) | 237 | scopes.scope_chain(name_ref.syntax()) |
238 | .flat_map(|scope| scopes.entries(scope).iter()) | 238 | .flat_map(|scope| scopes.entries(scope).iter()) |
diff --git a/crates/ra_editor/src/folding_ranges.rs b/crates/ra_editor/src/folding_ranges.rs index 733512368..3aabd54ae 100644 --- a/crates/ra_editor/src/folding_ranges.rs +++ b/crates/ra_editor/src/folding_ranges.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::collections::HashSet; | 1 | use rustc_hash::FxHashSet; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | File, TextRange, SyntaxNodeRef, | 4 | File, TextRange, SyntaxNodeRef, |
@@ -20,7 +20,7 @@ pub struct Fold { | |||
20 | 20 | ||
21 | pub fn folding_ranges(file: &File) -> Vec<Fold> { | 21 | pub fn folding_ranges(file: &File) -> Vec<Fold> { |
22 | let mut res = vec![]; | 22 | let mut res = vec![]; |
23 | let mut visited = HashSet::new(); | 23 | let mut visited = FxHashSet::default(); |
24 | 24 | ||
25 | for node in file.syntax().descendants() { | 25 | for node in file.syntax().descendants() { |
26 | if visited.contains(&node) { | 26 | if visited.contains(&node) { |
@@ -56,7 +56,7 @@ pub fn folding_ranges(file: &File) -> Vec<Fold> { | |||
56 | fn contiguous_range_for<'a>( | 56 | fn contiguous_range_for<'a>( |
57 | kind: SyntaxKind, | 57 | kind: SyntaxKind, |
58 | node: SyntaxNodeRef<'a>, | 58 | node: SyntaxNodeRef<'a>, |
59 | visited: &mut HashSet<SyntaxNodeRef<'a>>, | 59 | visited: &mut FxHashSet<SyntaxNodeRef<'a>>, |
60 | ) -> Option<TextRange> { | 60 | ) -> Option<TextRange> { |
61 | visited.insert(node); | 61 | visited.insert(node); |
62 | 62 | ||
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index fe0045378..710afc65d 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs | |||
@@ -2,6 +2,7 @@ extern crate ra_syntax; | |||
2 | extern crate superslice; | 2 | extern crate superslice; |
3 | extern crate itertools; | 3 | extern crate itertools; |
4 | extern crate join_to_string; | 4 | extern crate join_to_string; |
5 | extern crate rustc_hash; | ||
5 | #[cfg(test)] | 6 | #[cfg(test)] |
6 | #[macro_use] | 7 | #[macro_use] |
7 | extern crate test_utils as _test_utils; | 8 | extern crate test_utils as _test_utils; |
@@ -88,7 +89,6 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> { | |||
88 | let mut res = Vec::new(); | 89 | let mut res = Vec::new(); |
89 | for node in file.syntax().descendants() { | 90 | for node in file.syntax().descendants() { |
90 | let tag = match node.kind() { | 91 | let tag = match node.kind() { |
91 | ERROR => "error", | ||
92 | COMMENT | DOC_COMMENT => "comment", | 92 | COMMENT | DOC_COMMENT => "comment", |
93 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | 93 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", |
94 | ATTR => "attribute", | 94 | ATTR => "attribute", |
@@ -108,21 +108,10 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { | 110 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { |
111 | let mut res = Vec::new(); | 111 | file.errors().into_iter().map(|err| Diagnostic { |
112 | |||
113 | for node in file.syntax().descendants() { | ||
114 | if node.kind() == ERROR { | ||
115 | res.push(Diagnostic { | ||
116 | range: node.range(), | ||
117 | msg: "Syntax Error".to_string(), | ||
118 | }); | ||
119 | } | ||
120 | } | ||
121 | res.extend(file.errors().into_iter().map(|err| Diagnostic { | ||
122 | range: TextRange::offset_len(err.offset, 1.into()), | 112 | range: TextRange::offset_len(err.offset, 1.into()), |
123 | msg: err.msg, | 113 | msg: "Syntax Error: ".to_string() + &err.msg, |
124 | })); | 114 | }).collect() |
125 | res | ||
126 | } | 115 | } |
127 | 116 | ||
128 | pub fn syntax_tree(file: &File) -> String { | 117 | pub fn syntax_tree(file: &File) -> String { |
diff --git a/crates/ra_editor/src/scope/fn_scope.rs b/crates/ra_editor/src/scope/fn_scope.rs index 65d85279f..9a48bda02 100644 --- a/crates/ra_editor/src/scope/fn_scope.rs +++ b/crates/ra_editor/src/scope/fn_scope.rs | |||
@@ -1,7 +1,5 @@ | |||
1 | use std::{ | 1 | use std::fmt; |
2 | fmt, | 2 | use rustc_hash::FxHashMap; |
3 | collections::HashMap, | ||
4 | }; | ||
5 | 3 | ||
6 | use ra_syntax::{ | 4 | use ra_syntax::{ |
7 | SyntaxNodeRef, SyntaxNode, SmolStr, AstNode, | 5 | SyntaxNodeRef, SyntaxNode, SmolStr, AstNode, |
@@ -15,7 +13,7 @@ type ScopeId = usize; | |||
15 | pub struct FnScopes { | 13 | pub struct FnScopes { |
16 | pub self_param: Option<SyntaxNode>, | 14 | pub self_param: Option<SyntaxNode>, |
17 | scopes: Vec<ScopeData>, | 15 | scopes: Vec<ScopeData>, |
18 | scope_for: HashMap<SyntaxNode, ScopeId>, | 16 | scope_for: FxHashMap<SyntaxNode, ScopeId>, |
19 | } | 17 | } |
20 | 18 | ||
21 | impl FnScopes { | 19 | impl FnScopes { |
@@ -25,7 +23,7 @@ impl FnScopes { | |||
25 | .and_then(|it| it.self_param()) | 23 | .and_then(|it| it.self_param()) |
26 | .map(|it| it.syntax().owned()), | 24 | .map(|it| it.syntax().owned()), |
27 | scopes: Vec::new(), | 25 | scopes: Vec::new(), |
28 | scope_for: HashMap::new() | 26 | scope_for: FxHashMap::default() |
29 | }; | 27 | }; |
30 | let root = scopes.root_scope(); | 28 | let root = scopes.root_scope(); |
31 | scopes.add_params_bindings(root, fn_def.param_list()); | 29 | scopes.add_params_bindings(root, fn_def.param_list()); |
@@ -242,9 +240,9 @@ struct ScopeData { | |||
242 | } | 240 | } |
243 | 241 | ||
244 | pub fn resolve_local_name<'a>(name_ref: ast::NameRef, scopes: &'a FnScopes) -> Option<&'a ScopeEntry> { | 242 | pub fn resolve_local_name<'a>(name_ref: ast::NameRef, scopes: &'a FnScopes) -> Option<&'a ScopeEntry> { |
245 | use std::collections::HashSet; | 243 | use rustc_hash::FxHashSet; |
246 | 244 | ||
247 | let mut shadowed = HashSet::new(); | 245 | let mut shadowed = FxHashSet::default(); |
248 | let ret = scopes.scope_chain(name_ref.syntax()) | 246 | let ret = scopes.scope_chain(name_ref.syntax()) |
249 | .flat_map(|scope| scopes.entries(scope).iter()) | 247 | .flat_map(|scope| scopes.entries(scope).iter()) |
250 | .filter(|entry| shadowed.insert(entry.name())) | 248 | .filter(|entry| shadowed.insert(entry.name())) |
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs index 3384389d1..1dc658f9b 100644 --- a/crates/ra_editor/src/typing.rs +++ b/crates/ra_editor/src/typing.rs | |||
@@ -30,6 +30,7 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit { | |||
30 | } else { | 30 | } else { |
31 | range | 31 | range |
32 | }; | 32 | }; |
33 | |||
33 | let node = find_covering_node(file.syntax(), range); | 34 | let node = find_covering_node(file.syntax(), range); |
34 | let mut edit = EditBuilder::new(); | 35 | let mut edit = EditBuilder::new(); |
35 | for node in node.descendants() { | 36 | for node in node.descendants() { |
@@ -57,14 +58,19 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit { | |||
57 | } | 58 | } |
58 | 59 | ||
59 | pub fn on_enter(file: &File, offset: TextUnit) -> Option<LocalEdit> { | 60 | pub fn on_enter(file: &File, offset: TextUnit) -> Option<LocalEdit> { |
60 | let comment = find_leaf_at_offset(file.syntax(), offset).left_biased().filter(|it| it.kind() == COMMENT)?; | 61 | let comment = find_leaf_at_offset(file.syntax(), offset).left_biased().and_then(|it| ast::Comment::cast(it))?; |
61 | let prefix = comment_preffix(comment)?; | 62 | |
62 | if offset < comment.range().start() + TextUnit::of_str(prefix) { | 63 | if let ast::CommentFlavor::Multiline = comment.flavor() { |
64 | return None; | ||
65 | } | ||
66 | |||
67 | let prefix = comment.prefix(); | ||
68 | if offset < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) { | ||
63 | return None; | 69 | return None; |
64 | } | 70 | } |
65 | 71 | ||
66 | let indent = node_indent(file, comment)?; | 72 | let indent = node_indent(file, comment.syntax())?; |
67 | let inserted = format!("\n{}{}", indent, prefix); | 73 | let inserted = format!("\n{}{} ", indent, prefix); |
68 | let cursor_position = offset + TextUnit::of_str(&inserted); | 74 | let cursor_position = offset + TextUnit::of_str(&inserted); |
69 | let mut edit = EditBuilder::new(); | 75 | let mut edit = EditBuilder::new(); |
70 | edit.insert(offset, inserted); | 76 | edit.insert(offset, inserted); |
@@ -74,20 +80,6 @@ pub fn on_enter(file: &File, offset: TextUnit) -> Option<LocalEdit> { | |||
74 | }) | 80 | }) |
75 | } | 81 | } |
76 | 82 | ||
77 | fn comment_preffix(comment: SyntaxNodeRef) -> Option<&'static str> { | ||
78 | let text = comment.leaf_text().unwrap(); | ||
79 | let res = if text.starts_with("///") { | ||
80 | "/// " | ||
81 | } else if text.starts_with("//!") { | ||
82 | "//! " | ||
83 | } else if text.starts_with("//") { | ||
84 | "// " | ||
85 | } else { | ||
86 | return None; | ||
87 | }; | ||
88 | Some(res) | ||
89 | } | ||
90 | |||
91 | fn node_indent<'a>(file: &'a File, node: SyntaxNodeRef) -> Option<&'a str> { | 83 | fn node_indent<'a>(file: &'a File, node: SyntaxNodeRef) -> Option<&'a str> { |
92 | let ws = match find_leaf_at_offset(file.syntax(), node.range().start()) { | 84 | let ws = match find_leaf_at_offset(file.syntax(), node.range().start()) { |
93 | LeafAtOffset::Between(l, r) => { | 85 | LeafAtOffset::Between(l, r) => { |
@@ -139,41 +131,60 @@ fn remove_newline( | |||
139 | node_text: &str, | 131 | node_text: &str, |
140 | offset: TextUnit, | 132 | offset: TextUnit, |
141 | ) { | 133 | ) { |
142 | if node.kind() == WHITESPACE && node_text.bytes().filter(|&b| b == b'\n').count() == 1 { | 134 | if node.kind() != WHITESPACE || node_text.bytes().filter(|&b| b == b'\n').count() != 1 { |
143 | if join_single_expr_block(edit, node).is_some() { | 135 | // The node is either the first or the last in the file |
144 | return | 136 | let suff = &node_text[TextRange::from_to( |
145 | } | 137 | offset - node.range().start() + TextUnit::of_char('\n'), |
146 | match (node.prev_sibling(), node.next_sibling()) { | 138 | TextUnit::of_str(node_text), |
147 | (Some(prev), Some(next)) => { | 139 | )]; |
148 | let range = TextRange::from_to(prev.range().start(), node.range().end()); | 140 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); |
149 | if is_trailing_comma(prev.kind(), next.kind()) { | 141 | |
150 | edit.delete(range); | 142 | edit.replace( |
151 | } else if no_space_required(prev.kind(), next.kind()) { | 143 | TextRange::offset_len(offset, ((spaces + 1) as u32).into()), |
152 | edit.delete(node.range()); | 144 | " ".to_string(), |
153 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { | 145 | ); |
154 | edit.replace(range, " ".to_string()); | 146 | return; |
155 | } else { | ||
156 | edit.replace( | ||
157 | node.range(), | ||
158 | compute_ws(prev, next).to_string(), | ||
159 | ); | ||
160 | } | ||
161 | return; | ||
162 | } | ||
163 | _ => (), | ||
164 | } | ||
165 | } | 147 | } |
166 | 148 | ||
167 | let suff = &node_text[TextRange::from_to( | 149 | // Special case that turns something like: |
168 | offset - node.range().start() + TextUnit::of_char('\n'), | 150 | // |
169 | TextUnit::of_str(node_text), | 151 | // ``` |
170 | )]; | 152 | // my_function({<|> |
171 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); | 153 | // <some-expr> |
154 | // }) | ||
155 | // ``` | ||
156 | // | ||
157 | // into `my_function(<some-expr>)` | ||
158 | if join_single_expr_block(edit, node).is_some() { | ||
159 | return | ||
160 | } | ||
172 | 161 | ||
173 | edit.replace( | 162 | // The node is between two other nodes |
174 | TextRange::offset_len(offset, ((spaces + 1) as u32).into()), | 163 | let prev = node.prev_sibling().unwrap(); |
175 | " ".to_string(), | 164 | let next = node.next_sibling().unwrap(); |
176 | ); | 165 | if is_trailing_comma(prev.kind(), next.kind()) { |
166 | // Removes: trailing comma, newline (incl. surrounding whitespace) | ||
167 | edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); | ||
168 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { | ||
169 | // Removes: comma, newline (incl. surrounding whitespace) | ||
170 | // Adds: a single whitespace | ||
171 | edit.replace( | ||
172 | TextRange::from_to(prev.range().start(), node.range().end()), | ||
173 | " ".to_string() | ||
174 | ); | ||
175 | } else if let (Some(_), Some(next)) = (ast::Comment::cast(prev), ast::Comment::cast(next)) { | ||
176 | // Removes: newline (incl. surrounding whitespace), start of the next comment | ||
177 | edit.delete(TextRange::from_to( | ||
178 | node.range().start(), | ||
179 | next.syntax().range().start() + TextUnit::of_str(next.prefix()) | ||
180 | )); | ||
181 | } else { | ||
182 | // Remove newline but add a computed amount of whitespace characters | ||
183 | edit.replace( | ||
184 | node.range(), | ||
185 | compute_ws(prev, next).to_string(), | ||
186 | ); | ||
187 | } | ||
177 | } | 188 | } |
178 | 189 | ||
179 | fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { | 190 | fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { |
@@ -183,13 +194,6 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { | |||
183 | } | 194 | } |
184 | } | 195 | } |
185 | 196 | ||
186 | fn no_space_required(left: SyntaxKind, right: SyntaxKind) -> bool { | ||
187 | match (left, right) { | ||
188 | (_, DOT) => true, | ||
189 | _ => false | ||
190 | } | ||
191 | } | ||
192 | |||
193 | fn join_single_expr_block( | 197 | fn join_single_expr_block( |
194 | edit: &mut EditBuilder, | 198 | edit: &mut EditBuilder, |
195 | node: SyntaxNodeRef, | 199 | node: SyntaxNodeRef, |
@@ -231,6 +235,7 @@ fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { | |||
231 | } | 235 | } |
232 | match right.kind() { | 236 | match right.kind() { |
233 | R_PAREN | R_BRACK => return "", | 237 | R_PAREN | R_BRACK => return "", |
238 | DOT => return "", | ||
234 | _ => (), | 239 | _ => (), |
235 | } | 240 | } |
236 | " " | 241 | " " |
@@ -291,6 +296,80 @@ fn foo() { | |||
291 | }"); | 296 | }"); |
292 | } | 297 | } |
293 | 298 | ||
299 | #[test] | ||
300 | fn test_join_lines_normal_comments() { | ||
301 | check_join_lines(r" | ||
302 | fn foo() { | ||
303 | // Hello<|> | ||
304 | // world! | ||
305 | } | ||
306 | ", r" | ||
307 | fn foo() { | ||
308 | // Hello<|> world! | ||
309 | } | ||
310 | "); | ||
311 | } | ||
312 | |||
313 | #[test] | ||
314 | fn test_join_lines_doc_comments() { | ||
315 | check_join_lines(r" | ||
316 | fn foo() { | ||
317 | /// Hello<|> | ||
318 | /// world! | ||
319 | } | ||
320 | ", r" | ||
321 | fn foo() { | ||
322 | /// Hello<|> world! | ||
323 | } | ||
324 | "); | ||
325 | } | ||
326 | |||
327 | #[test] | ||
328 | fn test_join_lines_mod_comments() { | ||
329 | check_join_lines(r" | ||
330 | fn foo() { | ||
331 | //! Hello<|> | ||
332 | //! world! | ||
333 | } | ||
334 | ", r" | ||
335 | fn foo() { | ||
336 | //! Hello<|> world! | ||
337 | } | ||
338 | "); | ||
339 | } | ||
340 | |||
341 | #[test] | ||
342 | fn test_join_lines_multiline_comments_1() { | ||
343 | check_join_lines(r" | ||
344 | fn foo() { | ||
345 | // Hello<|> | ||
346 | /* world! */ | ||
347 | } | ||
348 | ", r" | ||
349 | fn foo() { | ||
350 | // Hello<|> world! */ | ||
351 | } | ||
352 | "); | ||
353 | } | ||
354 | |||
355 | #[test] | ||
356 | fn test_join_lines_multiline_comments_2() { | ||
357 | check_join_lines(r" | ||
358 | fn foo() { | ||
359 | // The<|> | ||
360 | /* quick | ||
361 | brown | ||
362 | fox! */ | ||
363 | } | ||
364 | ", r" | ||
365 | fn foo() { | ||
366 | // The<|> quick | ||
367 | brown | ||
368 | fox! */ | ||
369 | } | ||
370 | "); | ||
371 | } | ||
372 | |||
294 | fn check_join_lines_sel(before: &str, after: &str) { | 373 | fn check_join_lines_sel(before: &str, after: &str) { |
295 | let (sel, before) = extract_range(before); | 374 | let (sel, before) = extract_range(before); |
296 | let file = File::parse(&before); | 375 | let file = File::parse(&before); |
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 32463e499..1fe6b2ebe 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -21,6 +21,7 @@ im = "12.0.0" | |||
21 | cargo_metadata = "0.6.0" | 21 | cargo_metadata = "0.6.0" |
22 | text_unit = { version = "0.1.2", features = ["serde"] } | 22 | text_unit = { version = "0.1.2", features = ["serde"] } |
23 | smol_str = { version = "0.1.5", features = ["serde"] } | 23 | smol_str = { version = "0.1.5", features = ["serde"] } |
24 | rustc-hash = "1.0" | ||
24 | 25 | ||
25 | ra_syntax = { path = "../ra_syntax" } | 26 | ra_syntax = { path = "../ra_syntax" } |
26 | ra_editor = { path = "../ra_editor" } | 27 | ra_editor = { path = "../ra_editor" } |
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index d2f76972f..60652d55e 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs | |||
@@ -16,6 +16,7 @@ extern crate walkdir; | |||
16 | extern crate im; | 16 | extern crate im; |
17 | extern crate relative_path; | 17 | extern crate relative_path; |
18 | extern crate cargo_metadata; | 18 | extern crate cargo_metadata; |
19 | extern crate rustc_hash; | ||
19 | 20 | ||
20 | extern crate gen_lsp_server; | 21 | extern crate gen_lsp_server; |
21 | extern crate ra_editor; | 22 | extern crate ra_editor; |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 725036cc7..ab8be15e9 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::collections::{HashMap}; | 1 | use rustc_hash::FxHashMap; |
2 | 2 | ||
3 | use languageserver_types::{ | 3 | use languageserver_types::{ |
4 | Diagnostic, DiagnosticSeverity, DocumentSymbol, | 4 | Diagnostic, DiagnosticSeverity, DocumentSymbol, |
@@ -267,7 +267,7 @@ pub fn handle_runnables( | |||
267 | bin: "cargo".to_string(), | 267 | bin: "cargo".to_string(), |
268 | args, | 268 | args, |
269 | env: { | 269 | env: { |
270 | let mut m = HashMap::new(); | 270 | let mut m = FxHashMap::default(); |
271 | m.insert( | 271 | m.insert( |
272 | "RUST_BACKTRACE".to_string(), | 272 | "RUST_BACKTRACE".to_string(), |
273 | "short".to_string(), | 273 | "short".to_string(), |
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index 53c6f1dff..402615e42 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs | |||
@@ -3,7 +3,6 @@ mod subscriptions; | |||
3 | 3 | ||
4 | use std::{ | 4 | use std::{ |
5 | path::PathBuf, | 5 | path::PathBuf, |
6 | collections::{HashMap}, | ||
7 | }; | 6 | }; |
8 | 7 | ||
9 | use serde::{Serialize, de::DeserializeOwned}; | 8 | use serde::{Serialize, de::DeserializeOwned}; |
@@ -15,6 +14,7 @@ use gen_lsp_server::{ | |||
15 | RawRequest, RawNotification, RawMessage, RawResponse, ErrorCode, | 14 | RawRequest, RawNotification, RawMessage, RawResponse, ErrorCode, |
16 | handle_shutdown, | 15 | handle_shutdown, |
17 | }; | 16 | }; |
17 | use rustc_hash::FxHashMap; | ||
18 | 18 | ||
19 | use { | 19 | use { |
20 | req, | 20 | req, |
@@ -50,7 +50,7 @@ pub fn main_loop( | |||
50 | info!("server initialized, serving requests"); | 50 | info!("server initialized, serving requests"); |
51 | let mut state = ServerWorldState::new(); | 51 | let mut state = ServerWorldState::new(); |
52 | 52 | ||
53 | let mut pending_requests = HashMap::new(); | 53 | let mut pending_requests = FxHashMap::default(); |
54 | let mut subs = Subscriptions::new(); | 54 | let mut subs = Subscriptions::new(); |
55 | let main_res = main_loop_inner( | 55 | let main_res = main_loop_inner( |
56 | internal_mode, | 56 | internal_mode, |
@@ -95,7 +95,7 @@ fn main_loop_inner( | |||
95 | fs_worker: Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, | 95 | fs_worker: Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, |
96 | ws_worker: Worker<PathBuf, Result<CargoWorkspace>>, | 96 | ws_worker: Worker<PathBuf, Result<CargoWorkspace>>, |
97 | state: &mut ServerWorldState, | 97 | state: &mut ServerWorldState, |
98 | pending_requests: &mut HashMap<u64, JobHandle>, | 98 | pending_requests: &mut FxHashMap<u64, JobHandle>, |
99 | subs: &mut Subscriptions, | 99 | subs: &mut Subscriptions, |
100 | ) -> Result<()> { | 100 | ) -> Result<()> { |
101 | let (libdata_sender, libdata_receiver) = unbounded(); | 101 | let (libdata_sender, libdata_receiver) = unbounded(); |
@@ -213,7 +213,7 @@ fn main_loop_inner( | |||
213 | fn on_task( | 213 | fn on_task( |
214 | task: Task, | 214 | task: Task, |
215 | msg_sender: &Sender<RawMessage>, | 215 | msg_sender: &Sender<RawMessage>, |
216 | pending_requests: &mut HashMap<u64, JobHandle>, | 216 | pending_requests: &mut FxHashMap<u64, JobHandle>, |
217 | ) { | 217 | ) { |
218 | match task { | 218 | match task { |
219 | Task::Respond(response) => { | 219 | Task::Respond(response) => { |
@@ -229,7 +229,7 @@ fn on_task( | |||
229 | 229 | ||
230 | fn on_request( | 230 | fn on_request( |
231 | world: &mut ServerWorldState, | 231 | world: &mut ServerWorldState, |
232 | pending_requests: &mut HashMap<u64, JobHandle>, | 232 | pending_requests: &mut FxHashMap<u64, JobHandle>, |
233 | pool: &ThreadPool, | 233 | pool: &ThreadPool, |
234 | sender: &Sender<Task>, | 234 | sender: &Sender<Task>, |
235 | req: RawRequest, | 235 | req: RawRequest, |
@@ -269,7 +269,7 @@ fn on_request( | |||
269 | fn on_notification( | 269 | fn on_notification( |
270 | msg_sender: &Sender<RawMessage>, | 270 | msg_sender: &Sender<RawMessage>, |
271 | state: &mut ServerWorldState, | 271 | state: &mut ServerWorldState, |
272 | pending_requests: &mut HashMap<u64, JobHandle>, | 272 | pending_requests: &mut FxHashMap<u64, JobHandle>, |
273 | subs: &mut Subscriptions, | 273 | subs: &mut Subscriptions, |
274 | not: RawNotification, | 274 | not: RawNotification, |
275 | ) -> Result<()> { | 275 | ) -> Result<()> { |
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index 27f92cc9a..310153382 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs | |||
@@ -1,13 +1,13 @@ | |||
1 | use std::collections::HashSet; | 1 | use rustc_hash::FxHashSet; |
2 | use ra_analysis::FileId; | 2 | use ra_analysis::FileId; |
3 | 3 | ||
4 | pub struct Subscriptions { | 4 | pub struct Subscriptions { |
5 | subs: HashSet<FileId>, | 5 | subs: FxHashSet<FileId>, |
6 | } | 6 | } |
7 | 7 | ||
8 | impl Subscriptions { | 8 | impl Subscriptions { |
9 | pub fn new() -> Subscriptions { | 9 | pub fn new() -> Subscriptions { |
10 | Subscriptions { subs: HashSet::new() } | 10 | Subscriptions { subs: FxHashSet::default() } |
11 | } | 11 | } |
12 | pub fn add_sub(&mut self, file_id: FileId) { | 12 | pub fn add_sub(&mut self, file_id: FileId) { |
13 | self.subs.insert(file_id); | 13 | self.subs.insert(file_id); |
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 5db34e3e5..43e4fd654 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | collections::{HashMap, HashSet}, | ||
3 | path::{Path, PathBuf}, | 2 | path::{Path, PathBuf}, |
4 | }; | 3 | }; |
4 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
5 | use cargo_metadata::{metadata_run, CargoOpt}; | 5 | use cargo_metadata::{metadata_run, CargoOpt}; |
6 | use ra_syntax::SmolStr; | 6 | use ra_syntax::SmolStr; |
7 | 7 | ||
@@ -80,11 +80,11 @@ impl CargoWorkspace { | |||
80 | true, | 80 | true, |
81 | Some(CargoOpt::AllFeatures) | 81 | Some(CargoOpt::AllFeatures) |
82 | ).map_err(|e| format_err!("cargo metadata failed: {}", e))?; | 82 | ).map_err(|e| format_err!("cargo metadata failed: {}", e))?; |
83 | let mut pkg_by_id = HashMap::new(); | 83 | let mut pkg_by_id = FxHashMap::default(); |
84 | let mut packages = Vec::new(); | 84 | let mut packages = Vec::new(); |
85 | let mut targets = Vec::new(); | 85 | let mut targets = Vec::new(); |
86 | 86 | ||
87 | let ws_members: HashSet<String> = meta.workspace_members | 87 | let ws_members: FxHashSet<String> = meta.workspace_members |
88 | .into_iter() | 88 | .into_iter() |
89 | .map(|it| it.raw) | 89 | .map(|it| it.raw) |
90 | .collect(); | 90 | .collect(); |
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 458c79ea9..f80957589 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::collections::HashMap; | 1 | use rustc_hash::FxHashMap; |
2 | use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; | 2 | use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; |
3 | use url_serde; | 3 | use url_serde; |
4 | 4 | ||
@@ -149,7 +149,7 @@ pub struct Runnable { | |||
149 | pub label: String, | 149 | pub label: String, |
150 | pub bin: String, | 150 | pub bin: String, |
151 | pub args: Vec<String>, | 151 | pub args: Vec<String>, |
152 | pub env: HashMap<String, String>, | 152 | pub env: FxHashMap<String, String>, |
153 | } | 153 | } |
154 | 154 | ||
155 | #[derive(Serialize, Debug)] | 155 | #[derive(Serialize, Debug)] |
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 865f7c491..c4cdf83d4 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | fs, | 2 | fs, |
3 | path::{PathBuf, Path}, | 3 | path::{PathBuf, Path}, |
4 | collections::HashMap, | ||
5 | sync::Arc, | 4 | sync::Arc, |
6 | }; | 5 | }; |
7 | 6 | ||
7 | use rustc_hash::FxHashMap; | ||
8 | use languageserver_types::Url; | 8 | use languageserver_types::Url; |
9 | use ra_analysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryData, FileResolver}; | 9 | use ra_analysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryData, FileResolver}; |
10 | 10 | ||
@@ -20,7 +20,7 @@ pub struct ServerWorldState { | |||
20 | pub workspaces: Arc<Vec<CargoWorkspace>>, | 20 | pub workspaces: Arc<Vec<CargoWorkspace>>, |
21 | pub analysis_host: AnalysisHost, | 21 | pub analysis_host: AnalysisHost, |
22 | pub path_map: PathMap, | 22 | pub path_map: PathMap, |
23 | pub mem_map: HashMap<FileId, Option<String>>, | 23 | pub mem_map: FxHashMap<FileId, Option<String>>, |
24 | } | 24 | } |
25 | 25 | ||
26 | #[derive(Clone)] | 26 | #[derive(Clone)] |
@@ -36,7 +36,7 @@ impl ServerWorldState { | |||
36 | workspaces: Arc::new(Vec::new()), | 36 | workspaces: Arc::new(Vec::new()), |
37 | analysis_host: AnalysisHost::new(), | 37 | analysis_host: AnalysisHost::new(), |
38 | path_map: PathMap::new(), | 38 | path_map: PathMap::new(), |
39 | mem_map: HashMap::new(), | 39 | mem_map: FxHashMap::default(), |
40 | } | 40 | } |
41 | } | 41 | } |
42 | pub fn apply_fs_changes(&mut self, events: Vec<FileEvent>) { | 42 | pub fn apply_fs_changes(&mut self, events: Vec<FileEvent>) { |
@@ -121,7 +121,7 @@ impl ServerWorldState { | |||
121 | Ok(file_id) | 121 | Ok(file_id) |
122 | } | 122 | } |
123 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { | 123 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { |
124 | let mut crate_roots = HashMap::new(); | 124 | let mut crate_roots = FxHashMap::default(); |
125 | ws.iter() | 125 | ws.iter() |
126 | .flat_map(|ws| { | 126 | .flat_map(|ws| { |
127 | ws.packages() | 127 | ws.packages() |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index f27093291..ef7b5b1a1 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -231,6 +231,24 @@ impl<'a> AstNode<'a> for CastExpr<'a> { | |||
231 | 231 | ||
232 | impl<'a> CastExpr<'a> {} | 232 | impl<'a> CastExpr<'a> {} |
233 | 233 | ||
234 | // Comment | ||
235 | #[derive(Debug, Clone, Copy)] | ||
236 | pub struct Comment<'a> { | ||
237 | syntax: SyntaxNodeRef<'a>, | ||
238 | } | ||
239 | |||
240 | impl<'a> AstNode<'a> for Comment<'a> { | ||
241 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
242 | match syntax.kind() { | ||
243 | COMMENT => Some(Comment { syntax }), | ||
244 | _ => None, | ||
245 | } | ||
246 | } | ||
247 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
248 | } | ||
249 | |||
250 | impl<'a> Comment<'a> {} | ||
251 | |||
234 | // Condition | 252 | // Condition |
235 | #[derive(Debug, Clone, Copy)] | 253 | #[derive(Debug, Clone, Copy)] |
236 | pub struct Condition<'a> { | 254 | pub struct Condition<'a> { |
diff --git a/crates/ra_syntax/src/ast/mod.rs b/crates/ra_syntax/src/ast/mod.rs index c1570b868..10dac72e5 100644 --- a/crates/ra_syntax/src/ast/mod.rs +++ b/crates/ra_syntax/src/ast/mod.rs | |||
@@ -99,6 +99,49 @@ impl<'a> Lifetime<'a> { | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | impl<'a> Comment<'a> { | ||
103 | pub fn text(&self) -> SmolStr { | ||
104 | self.syntax().leaf_text().unwrap().clone() | ||
105 | } | ||
106 | |||
107 | pub fn flavor(&self) -> CommentFlavor { | ||
108 | let text = self.text(); | ||
109 | if text.starts_with("///") { | ||
110 | CommentFlavor::Doc | ||
111 | } else if text.starts_with("//!") { | ||
112 | CommentFlavor::ModuleDoc | ||
113 | } else if text.starts_with("//") { | ||
114 | CommentFlavor::Line | ||
115 | } else { | ||
116 | CommentFlavor::Multiline | ||
117 | } | ||
118 | } | ||
119 | |||
120 | pub fn prefix(&self) -> &'static str { | ||
121 | self.flavor().prefix() | ||
122 | } | ||
123 | } | ||
124 | |||
125 | #[derive(Debug)] | ||
126 | pub enum CommentFlavor { | ||
127 | Line, | ||
128 | Doc, | ||
129 | ModuleDoc, | ||
130 | Multiline | ||
131 | } | ||
132 | |||
133 | impl CommentFlavor { | ||
134 | pub fn prefix(&self) -> &'static str { | ||
135 | use self::CommentFlavor::*; | ||
136 | match *self { | ||
137 | Line => "//", | ||
138 | Doc => "///", | ||
139 | ModuleDoc => "//!", | ||
140 | Multiline => "/*" | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
102 | impl<'a> Name<'a> { | 145 | impl<'a> Name<'a> { |
103 | pub fn text(&self) -> SmolStr { | 146 | pub fn text(&self) -> SmolStr { |
104 | let ident = self.syntax().first_child() | 147 | let ident = self.syntax().first_child() |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 4b990fd8d..9da0c2c13 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -537,5 +537,6 @@ Grammar( | |||
537 | "PathSegment": ( | 537 | "PathSegment": ( |
538 | options: [ "NameRef" ] | 538 | options: [ "NameRef" ] |
539 | ), | 539 | ), |
540 | "Comment": (), | ||
540 | }, | 541 | }, |
541 | ) | 542 | ) |