aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db')
-rw-r--r--crates/ra_ide_db/src/feature_flags.rs73
-rw-r--r--crates/ra_ide_db/src/lib.rs10
-rw-r--r--crates/ra_ide_db/src/search.rs28
3 files changed, 26 insertions, 85 deletions
diff --git a/crates/ra_ide_db/src/feature_flags.rs b/crates/ra_ide_db/src/feature_flags.rs
deleted file mode 100644
index 968415072..000000000
--- a/crates/ra_ide_db/src/feature_flags.rs
+++ /dev/null
@@ -1,73 +0,0 @@
1//! See docs for `FeatureFlags`.
2
3use rustc_hash::FxHashMap;
4
5/// Feature flags hold fine-grained toggles for all *user-visible* features of
6/// rust-analyzer.
7///
8/// The exists such that users are able to disable any annoying feature (and,
9/// with many users and many features, some features are bound to be annoying
10/// for some users)
11///
12/// Note that we purposefully use run-time checked strings, and not something
13/// checked at compile time, to keep things simple and flexible.
14///
15/// Also note that, at the moment, `FeatureFlags` also store features for
16/// `rust-analyzer`. This should be benign layering violation.
17#[derive(Debug)]
18pub struct FeatureFlags {
19 flags: FxHashMap<String, bool>,
20}
21
22impl FeatureFlags {
23 fn new(flags: &[(&str, bool)]) -> FeatureFlags {
24 let flags = flags
25 .iter()
26 .map(|&(name, value)| {
27 check_flag_name(name);
28 (name.to_string(), value)
29 })
30 .collect();
31 FeatureFlags { flags }
32 }
33
34 pub fn set(&mut self, flag: &str, value: bool) -> Result<(), ()> {
35 match self.flags.get_mut(flag) {
36 None => Err(()),
37 Some(slot) => {
38 *slot = value;
39 Ok(())
40 }
41 }
42 }
43
44 pub fn get(&self, flag: &str) -> bool {
45 match self.flags.get(flag) {
46 None => panic!("unknown flag: {:?}", flag),
47 Some(value) => *value,
48 }
49 }
50}
51
52impl Default for FeatureFlags {
53 fn default() -> FeatureFlags {
54 FeatureFlags::new(&[
55 ("lsp.diagnostics", true),
56 ("completion.insertion.add-call-parenthesis", true),
57 ("completion.insertion.add-argument-snippets", true),
58 ("completion.enable-postfix", true),
59 ("call-info.full", true),
60 ("notifications.workspace-loaded", true),
61 ("notifications.cargo-toml-not-found", true),
62 ])
63 }
64}
65
66fn check_flag_name(flag: &str) {
67 for c in flag.bytes() {
68 match c {
69 b'a'..=b'z' | b'-' | b'.' => (),
70 _ => panic!("flag name does not match conventions: {:?}", flag),
71 }
72 }
73}
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs
index 74408d3d7..fc1b19def 100644
--- a/crates/ra_ide_db/src/lib.rs
+++ b/crates/ra_ide_db/src/lib.rs
@@ -5,7 +5,6 @@
5pub mod marks; 5pub mod marks;
6pub mod line_index; 6pub mod line_index;
7pub mod line_index_utils; 7pub mod line_index_utils;
8pub mod feature_flags;
9pub mod symbol_index; 8pub mod symbol_index;
10pub mod change; 9pub mod change;
11pub mod defs; 10pub mod defs;
@@ -22,7 +21,7 @@ use ra_db::{
22}; 21};
23use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
24 23
25use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::SymbolsDatabase}; 24use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
26 25
27#[salsa::database( 26#[salsa::database(
28 ra_db::SourceDatabaseStorage, 27 ra_db::SourceDatabaseStorage,
@@ -37,7 +36,6 @@ use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::Sy
37#[derive(Debug)] 36#[derive(Debug)]
38pub struct RootDatabase { 37pub struct RootDatabase {
39 runtime: salsa::Runtime<RootDatabase>, 38 runtime: salsa::Runtime<RootDatabase>,
40 pub feature_flags: Arc<FeatureFlags>,
41 pub(crate) debug_data: Arc<DebugData>, 39 pub(crate) debug_data: Arc<DebugData>,
42 pub last_gc: crate::wasm_shims::Instant, 40 pub last_gc: crate::wasm_shims::Instant,
43 pub last_gc_check: crate::wasm_shims::Instant, 41 pub last_gc_check: crate::wasm_shims::Instant,
@@ -89,17 +87,16 @@ impl salsa::Database for RootDatabase {
89 87
90impl Default for RootDatabase { 88impl Default for RootDatabase {
91 fn default() -> RootDatabase { 89 fn default() -> RootDatabase {
92 RootDatabase::new(None, FeatureFlags::default()) 90 RootDatabase::new(None)
93 } 91 }
94} 92}
95 93
96impl RootDatabase { 94impl RootDatabase {
97 pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase { 95 pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
98 let mut db = RootDatabase { 96 let mut db = RootDatabase {
99 runtime: salsa::Runtime::default(), 97 runtime: salsa::Runtime::default(),
100 last_gc: crate::wasm_shims::Instant::now(), 98 last_gc: crate::wasm_shims::Instant::now(),
101 last_gc_check: crate::wasm_shims::Instant::now(), 99 last_gc_check: crate::wasm_shims::Instant::now(),
102 feature_flags: Arc::new(feature_flags),
103 debug_data: Default::default(), 100 debug_data: Default::default(),
104 }; 101 };
105 db.set_crate_graph_with_durability(Default::default(), Durability::HIGH); 102 db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
@@ -119,7 +116,6 @@ impl salsa::ParallelDatabase for RootDatabase {
119 runtime: self.runtime.snapshot(self), 116 runtime: self.runtime.snapshot(self),
120 last_gc: self.last_gc, 117 last_gc: self.last_gc,
121 last_gc_check: self.last_gc_check, 118 last_gc_check: self.last_gc_check,
122 feature_flags: Arc::clone(&self.feature_flags),
123 debug_data: Arc::clone(&self.debug_data), 119 debug_data: Arc::clone(&self.debug_data),
124 }) 120 })
125 } 121 }
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs
index 6f198df04..cf78d3e41 100644
--- a/crates/ra_ide_db/src/search.rs
+++ b/crates/ra_ide_db/src/search.rs
@@ -17,7 +17,7 @@ use rustc_hash::FxHashMap;
17use test_utils::tested_by; 17use test_utils::tested_by;
18 18
19use crate::{ 19use crate::{
20 defs::{classify_name_ref, Definition}, 20 defs::{classify_name_ref, Definition, NameRefClass},
21 RootDatabase, 21 RootDatabase,
22}; 22};
23 23
@@ -30,6 +30,8 @@ pub struct Reference {
30 30
31#[derive(Debug, Clone, PartialEq)] 31#[derive(Debug, Clone, PartialEq)]
32pub enum ReferenceKind { 32pub enum ReferenceKind {
33 StructFieldShorthandForField,
34 StructFieldShorthandForLocal,
33 StructLiteral, 35 StructLiteral,
34 Other, 36 Other,
35} 37}
@@ -237,9 +239,8 @@ impl Definition {
237 // FIXME: reuse sb 239 // FIXME: reuse sb
238 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 240 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
239 241
240 if let Some(d) = classify_name_ref(&sema, &name_ref) { 242 match classify_name_ref(&sema, &name_ref) {
241 let d = d.definition(); 243 Some(NameRefClass::Definition(def)) if &def == self => {
242 if &d == self {
243 let kind = if is_record_lit_name_ref(&name_ref) 244 let kind = if is_record_lit_name_ref(&name_ref)
244 || is_call_expr_name_ref(&name_ref) 245 || is_call_expr_name_ref(&name_ref)
245 { 246 {
@@ -252,9 +253,26 @@ impl Definition {
252 refs.push(Reference { 253 refs.push(Reference {
253 file_range, 254 file_range,
254 kind, 255 kind,
255 access: reference_access(&d, &name_ref), 256 access: reference_access(&def, &name_ref),
256 }); 257 });
257 } 258 }
259 Some(NameRefClass::FieldShorthand { local, field }) => {
260 match self {
261 Definition::StructField(_) if &field == self => refs.push(Reference {
262 file_range: sema.original_range(name_ref.syntax()),
263 kind: ReferenceKind::StructFieldShorthandForField,
264 access: reference_access(&field, &name_ref),
265 }),
266 Definition::Local(l) if &local == l => refs.push(Reference {
267 file_range: sema.original_range(name_ref.syntax()),
268 kind: ReferenceKind::StructFieldShorthandForLocal,
269 access: reference_access(&Definition::Local(local), &name_ref),
270 }),
271
272 _ => {} // not a usage
273 };
274 }
275 _ => {} // not a usage
258 } 276 }
259 } 277 }
260 } 278 }