mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
implement feature flags
This commit is contained in:
parent
4dd5afb7fe
commit
69bbe79c50
11 changed files with 150 additions and 36 deletions
|
@ -3,7 +3,7 @@ use std::{collections::HashSet, error::Error, path::Path};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ra_db::{CrateGraph, FileId, SourceRootId};
|
use ra_db::{CrateGraph, FileId, SourceRootId};
|
||||||
use ra_ide_api::{AnalysisChange, AnalysisHost};
|
use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags};
|
||||||
use ra_project_model::{PackageRoot, ProjectWorkspace};
|
use ra_project_model::{PackageRoot, ProjectWorkspace};
|
||||||
use ra_vfs::{RootEntry, Vfs, VfsChange};
|
use ra_vfs::{RootEntry, Vfs, VfsChange};
|
||||||
use ra_vfs_glob::RustPackageFilterBuilder;
|
use ra_vfs_glob::RustPackageFilterBuilder;
|
||||||
|
@ -63,7 +63,7 @@ pub fn load(
|
||||||
vfs: &mut Vfs,
|
vfs: &mut Vfs,
|
||||||
) -> AnalysisHost {
|
) -> AnalysisHost {
|
||||||
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
|
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
|
||||||
let mut host = AnalysisHost::new(lru_cap);
|
let mut host = AnalysisHost::new(lru_cap, FeatureFlags::default());
|
||||||
let mut analysis_change = AnalysisChange::new();
|
let mut analysis_change = AnalysisChange::new();
|
||||||
analysis_change.set_crate_graph(crate_graph);
|
analysis_change.set_crate_graph(crate_graph);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,10 @@ impl Completions {
|
||||||
.set_documentation(func.docs(ctx.db))
|
.set_documentation(func.docs(ctx.db))
|
||||||
.detail(detail);
|
.detail(detail);
|
||||||
// If not an import, add parenthesis automatically.
|
// 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);
|
tested_by!(inserts_parens_for_function_calls);
|
||||||
let snippet =
|
let snippet =
|
||||||
if data.params().is_empty() || data.has_self_param() && data.params().len() == 1 {
|
if data.params().is_empty() || data.has_self_param() && data.params().len() == 1 {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ra_db::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
symbol_index::{self, SymbolsDatabase},
|
symbol_index::{self, SymbolsDatabase},
|
||||||
LineIndex,
|
FeatureFlags, LineIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::database(
|
#[salsa::database(
|
||||||
|
@ -22,6 +22,7 @@ use crate::{
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct RootDatabase {
|
pub(crate) struct RootDatabase {
|
||||||
runtime: salsa::Runtime<RootDatabase>,
|
runtime: salsa::Runtime<RootDatabase>,
|
||||||
|
pub(crate) feature_flags: Arc<FeatureFlags>,
|
||||||
pub(crate) last_gc: time::Instant,
|
pub(crate) last_gc: time::Instant,
|
||||||
pub(crate) last_gc_check: time::Instant,
|
pub(crate) last_gc_check: time::Instant,
|
||||||
}
|
}
|
||||||
|
@ -46,16 +47,17 @@ impl salsa::Database for RootDatabase {
|
||||||
|
|
||||||
impl Default for RootDatabase {
|
impl Default for RootDatabase {
|
||||||
fn default() -> RootDatabase {
|
fn default() -> RootDatabase {
|
||||||
RootDatabase::new(None)
|
RootDatabase::new(None, FeatureFlags::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootDatabase {
|
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 {
|
let mut db = RootDatabase {
|
||||||
runtime: salsa::Runtime::default(),
|
runtime: salsa::Runtime::default(),
|
||||||
last_gc: time::Instant::now(),
|
last_gc: time::Instant::now(),
|
||||||
last_gc_check: 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_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
||||||
db.set_local_roots_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),
|
runtime: self.runtime.snapshot(self),
|
||||||
last_gc: self.last_gc,
|
last_gc: self.last_gc,
|
||||||
last_gc_check: self.last_gc_check,
|
last_gc_check: self.last_gc_check,
|
||||||
|
feature_flags: Arc::clone(&self.feature_flags),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
crates/ra_ide_api/src/feature_flags.rs
Normal file
67
crates/ra_ide_api/src/feature_flags.rs
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ mod db;
|
||||||
pub mod mock_analysis;
|
pub mod mock_analysis;
|
||||||
mod symbol_index;
|
mod symbol_index;
|
||||||
mod change;
|
mod change;
|
||||||
|
mod feature_flags;
|
||||||
|
|
||||||
mod status;
|
mod status;
|
||||||
mod completion;
|
mod completion;
|
||||||
|
@ -63,6 +64,7 @@ pub use crate::{
|
||||||
completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
|
completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
|
||||||
diagnostics::Severity,
|
diagnostics::Severity,
|
||||||
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
|
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
|
||||||
|
feature_flags::FeatureFlags,
|
||||||
folding_ranges::{Fold, FoldKind},
|
folding_ranges::{Fold, FoldKind},
|
||||||
hover::HoverResult,
|
hover::HoverResult,
|
||||||
inlay_hints::{InlayHint, InlayKind},
|
inlay_hints::{InlayHint, InlayKind},
|
||||||
|
@ -247,13 +249,13 @@ pub struct AnalysisHost {
|
||||||
|
|
||||||
impl Default for AnalysisHost {
|
impl Default for AnalysisHost {
|
||||||
fn default() -> AnalysisHost {
|
fn default() -> AnalysisHost {
|
||||||
AnalysisHost::new(None)
|
AnalysisHost::new(None, FeatureFlags::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnalysisHost {
|
impl AnalysisHost {
|
||||||
pub fn new(lru_capcity: Option<usize>) -> AnalysisHost {
|
pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost {
|
||||||
AnalysisHost { db: db::RootDatabase::new(lru_capcity) }
|
AnalysisHost { db: db::RootDatabase::new(lru_capcity, feature_flags) }
|
||||||
}
|
}
|
||||||
/// Returns a snapshot of the current state, which you can query for
|
/// Returns a snapshot of the current state, which you can query for
|
||||||
/// semantic information.
|
/// semantic information.
|
||||||
|
@ -261,6 +263,10 @@ impl AnalysisHost {
|
||||||
Analysis { db: self.db.snapshot() }
|
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
|
/// Applies changes to the current state of the world. If there are
|
||||||
/// outstanding snapshots, they will be canceled.
|
/// outstanding snapshots, they will be canceled.
|
||||||
pub fn apply_change(&mut self, change: AnalysisChange) {
|
pub fn apply_change(&mut self, change: AnalysisChange) {
|
||||||
|
@ -319,6 +325,10 @@ impl Analysis {
|
||||||
(host.analysis(), file_id)
|
(host.analysis(), file_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn feature_flags(&self) -> &FeatureFlags {
|
||||||
|
&self.db.feature_flags
|
||||||
|
}
|
||||||
|
|
||||||
/// Debug info about the current state of the analysis
|
/// Debug info about the current state of the analysis
|
||||||
pub fn status(&self) -> Cancelable<String> {
|
pub fn status(&self) -> Cancelable<String> {
|
||||||
self.with_db(|db| status::status(&*db))
|
self.with_db(|db| status::status(&*db))
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
/// Client provided initialization options
|
/// Client provided initialization options
|
||||||
|
@ -12,12 +14,6 @@ pub struct ServerConfig {
|
||||||
#[serde(deserialize_with = "nullable_bool_false")]
|
#[serde(deserialize_with = "nullable_bool_false")]
|
||||||
pub publish_decorations: bool,
|
pub publish_decorations: bool,
|
||||||
|
|
||||||
/// Whether or not the workspace loaded notification should be sent
|
|
||||||
///
|
|
||||||
/// Defaults to `true`
|
|
||||||
#[serde(deserialize_with = "nullable_bool_true")]
|
|
||||||
pub show_workspace_loaded: bool,
|
|
||||||
|
|
||||||
pub exclude_globs: Vec<String>,
|
pub exclude_globs: Vec<String>,
|
||||||
|
|
||||||
pub lru_capacity: Option<usize>,
|
pub lru_capacity: Option<usize>,
|
||||||
|
@ -25,16 +21,19 @@ pub struct ServerConfig {
|
||||||
/// For internal usage to make integrated tests faster.
|
/// For internal usage to make integrated tests faster.
|
||||||
#[serde(deserialize_with = "nullable_bool_true")]
|
#[serde(deserialize_with = "nullable_bool_true")]
|
||||||
pub with_sysroot: bool,
|
pub with_sysroot: bool,
|
||||||
|
|
||||||
|
/// Fine grained feature flags to disable specific features.
|
||||||
|
pub feature_flags: FxHashMap<String, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
fn default() -> ServerConfig {
|
fn default() -> ServerConfig {
|
||||||
ServerConfig {
|
ServerConfig {
|
||||||
publish_decorations: false,
|
publish_decorations: false,
|
||||||
show_workspace_loaded: true,
|
|
||||||
exclude_globs: Vec::new(),
|
exclude_globs: Vec::new(),
|
||||||
lru_capacity: None,
|
lru_capacity: None,
|
||||||
with_sysroot: true,
|
with_sysroot: true,
|
||||||
|
feature_flags: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use gen_lsp_server::{
|
||||||
handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
|
handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
|
||||||
};
|
};
|
||||||
use lsp_types::{ClientCapabilities, NumberOrString};
|
use lsp_types::{ClientCapabilities, NumberOrString};
|
||||||
use ra_ide_api::{Canceled, FileId, LibraryData};
|
use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_vfs::VfsTask;
|
use ra_vfs::VfsTask;
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
@ -56,7 +56,7 @@ pub fn main_loop(
|
||||||
msg_receiver: &Receiver<RawMessage>,
|
msg_receiver: &Receiver<RawMessage>,
|
||||||
msg_sender: &Sender<RawMessage>,
|
msg_sender: &Sender<RawMessage>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
log::debug!("server_config: {:?}", config);
|
log::info!("server_config: {:#?}", config);
|
||||||
// FIXME: support dynamic workspace loading.
|
// FIXME: support dynamic workspace loading.
|
||||||
let workspaces = {
|
let workspaces = {
|
||||||
let ws_worker = workspace_loader(config.with_sysroot);
|
let ws_worker = workspace_loader(config.with_sysroot);
|
||||||
|
@ -83,6 +83,21 @@ pub fn main_loop(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|glob| ra_vfs_glob::Glob::new(glob))
|
.map(|glob| ra_vfs_glob::Glob::new(glob))
|
||||||
.collect::<std::result::Result<Vec<_>, _>>()?;
|
.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||||
|
let feature_flags = {
|
||||||
|
let mut ff = FeatureFlags::default();
|
||||||
|
for (flag, value) in config.feature_flags {
|
||||||
|
if let Err(_) = ff.set(flag.as_str(), value) {
|
||||||
|
log::error!("unknown feature flag: {:?}", flag);
|
||||||
|
show_message(
|
||||||
|
req::MessageType::Error,
|
||||||
|
format!("unknown feature flag: {:?}", flag),
|
||||||
|
msg_sender,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ff
|
||||||
|
};
|
||||||
|
log::info!("feature_flags: {:#?}", feature_flags);
|
||||||
let mut state = WorldState::new(
|
let mut state = WorldState::new(
|
||||||
ws_roots,
|
ws_roots,
|
||||||
workspaces,
|
workspaces,
|
||||||
|
@ -90,13 +105,13 @@ pub fn main_loop(
|
||||||
&globs,
|
&globs,
|
||||||
Options {
|
Options {
|
||||||
publish_decorations: config.publish_decorations,
|
publish_decorations: config.publish_decorations,
|
||||||
show_workspace_loaded: config.show_workspace_loaded,
|
|
||||||
supports_location_link: client_caps
|
supports_location_link: client_caps
|
||||||
.text_document
|
.text_document
|
||||||
.and_then(|it| it.definition)
|
.and_then(|it| it.definition)
|
||||||
.and_then(|it| it.link_support)
|
.and_then(|it| it.link_support)
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
},
|
},
|
||||||
|
feature_flags,
|
||||||
);
|
);
|
||||||
|
|
||||||
let pool = ThreadPool::new(THREADPOOL_SIZE);
|
let pool = ThreadPool::new(THREADPOOL_SIZE);
|
||||||
|
@ -276,7 +291,7 @@ fn main_loop_inner(
|
||||||
&& in_flight_libraries == 0
|
&& in_flight_libraries == 0
|
||||||
{
|
{
|
||||||
let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum();
|
let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum();
|
||||||
if state.options.show_workspace_loaded {
|
if state.feature_flags().get("notifications.workspace-loaded") {
|
||||||
let msg = format!("workspace loaded, {} rust packages", n_packages);
|
let msg = format!("workspace loaded, {} rust packages", n_packages);
|
||||||
show_message(req::MessageType::Info, msg, msg_sender);
|
show_message(req::MessageType::Info, msg, msg_sender);
|
||||||
}
|
}
|
||||||
|
@ -587,17 +602,20 @@ fn update_file_notifications_on_threadpool(
|
||||||
subscriptions: Vec<FileId>,
|
subscriptions: Vec<FileId>,
|
||||||
) {
|
) {
|
||||||
log::trace!("updating notifications for {:?}", subscriptions);
|
log::trace!("updating notifications for {:?}", subscriptions);
|
||||||
|
let publish_diagnostics = world.feature_flags().get("lsp.diagnostics");
|
||||||
pool.execute(move || {
|
pool.execute(move || {
|
||||||
for file_id in subscriptions {
|
for file_id in subscriptions {
|
||||||
match handlers::publish_diagnostics(&world, file_id) {
|
if publish_diagnostics {
|
||||||
Err(e) => {
|
match handlers::publish_diagnostics(&world, file_id) {
|
||||||
if !is_canceled(&e) {
|
Err(e) => {
|
||||||
log::error!("failed to compute diagnostics: {:?}", e);
|
if !is_canceled(&e) {
|
||||||
|
log::error!("failed to compute diagnostics: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(params) => {
|
||||||
|
let not = RawNotification::new::<req::PublishDiagnostics>(¶ms);
|
||||||
|
sender.send(Task::Notify(not)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Ok(params) => {
|
|
||||||
let not = RawNotification::new::<req::PublishDiagnostics>(¶ms);
|
|
||||||
sender.send(Task::Notify(not)).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if publish_decorations {
|
if publish_decorations {
|
||||||
|
|
|
@ -7,7 +7,8 @@ use gen_lsp_server::ErrorCode;
|
||||||
use lsp_types::Url;
|
use lsp_types::Url;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use ra_ide_api::{
|
use ra_ide_api::{
|
||||||
Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId,
|
Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData,
|
||||||
|
SourceRootId,
|
||||||
};
|
};
|
||||||
use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot};
|
use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot};
|
||||||
use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
|
use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
|
||||||
|
@ -22,7 +23,6 @@ use crate::{
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub publish_decorations: bool,
|
pub publish_decorations: bool,
|
||||||
pub show_workspace_loaded: bool,
|
|
||||||
pub supports_location_link: bool,
|
pub supports_location_link: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ impl WorldState {
|
||||||
lru_capacity: Option<usize>,
|
lru_capacity: Option<usize>,
|
||||||
exclude_globs: &[Glob],
|
exclude_globs: &[Glob],
|
||||||
options: Options,
|
options: Options,
|
||||||
|
feature_flags: FeatureFlags,
|
||||||
) -> WorldState {
|
) -> WorldState {
|
||||||
let mut change = AnalysisChange::new();
|
let mut change = AnalysisChange::new();
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ impl WorldState {
|
||||||
}
|
}
|
||||||
change.set_crate_graph(crate_graph);
|
change.set_crate_graph(crate_graph);
|
||||||
|
|
||||||
let mut analysis_host = AnalysisHost::new(lru_capacity);
|
let mut analysis_host = AnalysisHost::new(lru_capacity, feature_flags);
|
||||||
analysis_host.apply_change(change);
|
analysis_host.apply_change(change);
|
||||||
WorldState {
|
WorldState {
|
||||||
options,
|
options,
|
||||||
|
@ -184,6 +185,10 @@ impl WorldState {
|
||||||
pub fn complete_request(&mut self, request: CompletedRequest) {
|
pub fn complete_request(&mut self, request: CompletedRequest) {
|
||||||
self.latest_requests.write().record(request)
|
self.latest_requests.write().record(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn feature_flags(&self) -> &FeatureFlags {
|
||||||
|
self.analysis_host.feature_flags()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldSnapshot {
|
impl WorldSnapshot {
|
||||||
|
@ -246,4 +251,8 @@ impl WorldSnapshot {
|
||||||
let path = self.vfs.read().file2path(VfsFile(file_id.0));
|
let path = self.vfs.read().file2path(VfsFile(file_id.0));
|
||||||
self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
|
self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn feature_flags(&self) -> &FeatureFlags {
|
||||||
|
self.analysis.feature_flags()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,10 +165,10 @@
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "When highlighting Rust code, use a unique color per identifier"
|
"description": "When highlighting Rust code, use a unique color per identifier"
|
||||||
},
|
},
|
||||||
"rust-analyzer.showWorkspaceLoadedNotification": {
|
"rust-analyzer.featureFlags": {
|
||||||
"type": "boolean",
|
"type": "object",
|
||||||
"default": true,
|
"default": {},
|
||||||
"description": "Show notification when workspace was loaded"
|
"description": "Fine grained feature flags to disable annoying features"
|
||||||
},
|
},
|
||||||
"rust-analyzer.enableEnhancedTyping": {
|
"rust-analyzer.enableEnhancedTyping": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -23,6 +23,7 @@ export class Config {
|
||||||
public lruCapacity: null | number = null;
|
public lruCapacity: null | number = null;
|
||||||
public displayInlayHints = true;
|
public displayInlayHints = true;
|
||||||
public excludeGlobs = [];
|
public excludeGlobs = [];
|
||||||
|
public featureFlags = {};
|
||||||
public cargoWatchOptions: CargoWatchOptions = {
|
public cargoWatchOptions: CargoWatchOptions = {
|
||||||
enableOnStartup: 'ask',
|
enableOnStartup: 'ask',
|
||||||
trace: 'off',
|
trace: 'off',
|
||||||
|
@ -132,5 +133,8 @@ export class Config {
|
||||||
if (config.has('excludeGlobs')) {
|
if (config.has('excludeGlobs')) {
|
||||||
this.excludeGlobs = config.get('excludeGlobs') || [];
|
this.excludeGlobs = config.get('excludeGlobs') || [];
|
||||||
}
|
}
|
||||||
|
if (config.has('featureFlags')) {
|
||||||
|
this.featureFlags = config.get('featureFlags') || {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,8 @@ export class Server {
|
||||||
showWorkspaceLoaded:
|
showWorkspaceLoaded:
|
||||||
Server.config.showWorkspaceLoadedNotification,
|
Server.config.showWorkspaceLoadedNotification,
|
||||||
lruCapacity: Server.config.lruCapacity,
|
lruCapacity: Server.config.lruCapacity,
|
||||||
excludeGlobs: Server.config.excludeGlobs
|
excludeGlobs: Server.config.excludeGlobs,
|
||||||
|
featureFlags: Server.config.featureFlags
|
||||||
},
|
},
|
||||||
traceOutputChannel
|
traceOutputChannel
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue