1715: Feature flags r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-08-22 12:17:21 +00:00 committed by GitHub
commit 0a612fad02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 44 deletions

View file

@ -118,7 +118,10 @@ impl Completions {
.set_documentation(func.docs(ctx.db))
.detail(detail);
// If not an import, add parenthesis automatically.
if ctx.use_item_syntax.is_none() && !ctx.is_call {
if ctx.use_item_syntax.is_none()
&& !ctx.is_call
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
{
tested_by!(inserts_parens_for_function_calls);
let snippet =
if data.params().is_empty() || data.has_self_param() && data.params().len() == 1 {

View file

@ -7,7 +7,7 @@ use ra_db::{
use crate::{
symbol_index::{self, SymbolsDatabase},
LineIndex,
FeatureFlags, LineIndex,
};
#[salsa::database(
@ -22,6 +22,7 @@ use crate::{
#[derive(Debug)]
pub(crate) struct RootDatabase {
runtime: salsa::Runtime<RootDatabase>,
pub(crate) feature_flags: Arc<FeatureFlags>,
pub(crate) last_gc: time::Instant,
pub(crate) last_gc_check: time::Instant,
}
@ -46,16 +47,17 @@ impl salsa::Database for RootDatabase {
impl Default for RootDatabase {
fn default() -> RootDatabase {
RootDatabase::new(None)
RootDatabase::new(None, FeatureFlags::default())
}
}
impl RootDatabase {
pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase {
let mut db = RootDatabase {
runtime: salsa::Runtime::default(),
last_gc: time::Instant::now(),
last_gc_check: time::Instant::now(),
feature_flags: Arc::new(feature_flags),
};
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
@ -74,6 +76,7 @@ impl salsa::ParallelDatabase for RootDatabase {
runtime: self.runtime.snapshot(self),
last_gc: self.last_gc,
last_gc_check: self.last_gc_check,
feature_flags: Arc::clone(&self.feature_flags),
})
}
}

View file

@ -0,0 +1,67 @@
use rustc_hash::FxHashMap;
/// Feature flags hold fine-grained toggles for all *user-visible* features of
/// rust-analyzer.
///
/// The exists such that users are able to disable any annoying feature (and,
/// with many users and many features, some features are bound to be annoying
/// for some users)
///
/// Note that we purposefully use run-time checked strings, and not something
/// checked at compile time, to keep things simple and flexible.
///
/// Also note that, at the moment, `FeatureFlags` also store features for
/// `ra_lsp_server`. This should be benign layering violation.
#[derive(Debug)]
pub struct FeatureFlags {
flags: FxHashMap<String, bool>,
}
impl FeatureFlags {
fn new(flags: &[(&str, bool)]) -> FeatureFlags {
let flags = flags
.iter()
.map(|&(name, value)| {
check_flag_name(name);
(name.to_string(), value)
})
.collect();
FeatureFlags { flags }
}
pub fn set(&mut self, flag: &str, value: bool) -> Result<(), ()> {
match self.flags.get_mut(flag) {
None => Err(()),
Some(slot) => {
*slot = value;
Ok(())
}
}
}
pub fn get(&self, flag: &str) -> bool {
match self.flags.get(flag) {
None => panic!("unknown flag: {:?}", flag),
Some(value) => *value,
}
}
}
impl Default for FeatureFlags {
fn default() -> FeatureFlags {
FeatureFlags::new(&[
("lsp.diagnostics", true),
("completion.insertion.add-call-parenthesis", true),
("notifications.workspace-loaded", true),
])
}
}
fn check_flag_name(flag: &str) {
for c in flag.bytes() {
match c {
b'a'..=b'z' | b'-' | b'.' => (),
_ => panic!("flag name does not match conventions: {:?}", flag),
}
}
}

View file

@ -14,6 +14,7 @@ mod db;
pub mod mock_analysis;
mod symbol_index;
mod change;
mod feature_flags;
mod status;
mod completion;
@ -63,6 +64,7 @@ pub use crate::{
completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
diagnostics::Severity,
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
feature_flags::FeatureFlags,
folding_ranges::{Fold, FoldKind},
hover::HoverResult,
inlay_hints::{InlayHint, InlayKind},
@ -247,13 +249,13 @@ pub struct AnalysisHost {
impl Default for AnalysisHost {
fn default() -> AnalysisHost {
AnalysisHost::new(None)
AnalysisHost::new(None, FeatureFlags::default())
}
}
impl AnalysisHost {
pub fn new(lru_capcity: Option<usize>) -> AnalysisHost {
AnalysisHost { db: db::RootDatabase::new(lru_capcity) }
pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost {
AnalysisHost { db: db::RootDatabase::new(lru_capcity, feature_flags) }
}
/// Returns a snapshot of the current state, which you can query for
/// semantic information.
@ -261,6 +263,10 @@ impl AnalysisHost {
Analysis { db: self.db.snapshot() }
}
pub fn feature_flags(&self) -> &FeatureFlags {
&self.db.feature_flags
}
/// Applies changes to the current state of the world. If there are
/// outstanding snapshots, they will be canceled.
pub fn apply_change(&mut self, change: AnalysisChange) {
@ -319,6 +325,10 @@ impl Analysis {
(host.analysis(), file_id)
}
pub fn feature_flags(&self) -> &FeatureFlags {
&self.db.feature_flags
}
/// Debug info about the current state of the analysis
pub fn status(&self) -> Cancelable<String> {
self.with_db(|db| status::status(&*db))