Reload only the properties that do not affect vfs

This commit is contained in:
Kirill Bulatov 2020-03-20 22:09:23 +02:00
parent 2feaef91bd
commit 332799d914
4 changed files with 89 additions and 60 deletions

View file

@ -138,6 +138,11 @@ impl AnalysisHost {
pub fn new(lru_capacity: Option<usize>) -> AnalysisHost { pub fn new(lru_capacity: Option<usize>) -> AnalysisHost {
AnalysisHost { db: RootDatabase::new(lru_capacity) } AnalysisHost { db: RootDatabase::new(lru_capacity) }
} }
pub fn update_lru_capacity(&mut self, lru_capacity: Option<usize>) {
self.db.update_lru_capacity(lru_capacity);
}
/// 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.
pub fn analysis(&self) -> Analysis { pub fn analysis(&self) -> Analysis {

View file

@ -115,12 +115,16 @@ impl RootDatabase {
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);
db.set_library_roots_with_durability(Default::default(), Durability::HIGH); db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP); db.update_lru_capacity(lru_capacity);
db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
db.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity);
db db
} }
pub fn update_lru_capacity(&mut self, lru_capacity: Option<usize>) {
let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
self.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
self.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
self.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity);
}
} }
impl salsa::ParallelDatabase for RootDatabase { impl salsa::ParallelDatabase for RootDatabase {

View file

@ -17,8 +17,9 @@ use std::{
use crossbeam_channel::{never, select, unbounded, RecvError, Sender}; use crossbeam_channel::{never, select, unbounded, RecvError, Sender};
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
use lsp_types::{ use lsp_types::{
ClientCapabilities, NumberOrString, WorkDoneProgress, WorkDoneProgressBegin, ClientCapabilities, NumberOrString, TextDocumentClientCapabilities, WorkDoneProgress,
WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport, WorkDoneProgressBegin, WorkDoneProgressCreateParams, WorkDoneProgressEnd,
WorkDoneProgressReport,
}; };
use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask}; use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId}; use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId};
@ -64,6 +65,53 @@ impl fmt::Display for LspError {
impl Error for LspError {} impl Error for LspError {}
fn get_feature_flags(config: &ServerConfig, connection: &Connection) -> FeatureFlags {
let mut ff = FeatureFlags::default();
for (flag, &value) in &config.feature_flags {
if ff.set(flag.as_str(), value).is_err() {
log::error!("unknown feature flag: {:?}", flag);
show_message(
req::MessageType::Error,
format!("unknown feature flag: {:?}", flag),
&connection.sender,
);
}
}
log::info!("feature_flags: {:#?}", ff);
ff
}
fn get_options(
config: &ServerConfig,
text_document_caps: Option<&TextDocumentClientCapabilities>,
) -> Options {
Options {
publish_decorations: config.publish_decorations,
supports_location_link: text_document_caps
.and_then(|it| it.definition)
.and_then(|it| it.link_support)
.unwrap_or(false),
line_folding_only: text_document_caps
.and_then(|it| it.folding_range.as_ref())
.and_then(|it| it.line_folding_only)
.unwrap_or(false),
inlay_hints: InlayHintsOptions {
type_hints: config.inlay_hints_type,
parameter_hints: config.inlay_hints_parameter,
chaining_hints: config.inlay_hints_chaining,
max_length: config.inlay_hints_max_length,
},
cargo_watch: CheckOptions {
enable: config.cargo_watch_enable,
args: config.cargo_watch_args.clone(),
command: config.cargo_watch_command.clone(),
all_targets: config.cargo_watch_all_targets,
},
rustfmt_args: config.rustfmt_args.clone(),
vscode_lldb: config.vscode_lldb,
}
}
pub fn main_loop( pub fn main_loop(
ws_roots: Vec<PathBuf>, ws_roots: Vec<PathBuf>,
client_caps: ClientCapabilities, client_caps: ClientCapabilities,
@ -91,23 +139,10 @@ pub fn main_loop(
SetThreadPriority(thread, thread_priority_above_normal); SetThreadPriority(thread, thread_priority_above_normal);
} }
let text_document_caps = client_caps.text_document.as_ref();
let mut loop_state = LoopState::default(); let mut loop_state = LoopState::default();
let mut world_state = { let mut world_state = {
let feature_flags = { let feature_flags = get_feature_flags(&config, &connection);
let mut ff = FeatureFlags::default();
for (flag, value) in config.feature_flags {
if ff.set(flag.as_str(), value).is_err() {
log::error!("unknown feature flag: {:?}", flag);
show_message(
req::MessageType::Error,
format!("unknown feature flag: {:?}", flag),
&connection.sender,
);
}
}
ff
};
log::info!("feature_flags: {:#?}", feature_flags);
// FIXME: support dynamic workspace loading. // FIXME: support dynamic workspace loading.
let workspaces = { let workspaces = {
@ -169,42 +204,13 @@ pub fn main_loop(
connection.sender.send(request.into()).unwrap(); connection.sender.send(request.into()).unwrap();
} }
let options = {
let text_document_caps = client_caps.text_document.as_ref();
Options {
publish_decorations: config.publish_decorations,
supports_location_link: text_document_caps
.and_then(|it| it.definition)
.and_then(|it| it.link_support)
.unwrap_or(false),
line_folding_only: text_document_caps
.and_then(|it| it.folding_range.as_ref())
.and_then(|it| it.line_folding_only)
.unwrap_or(false),
inlay_hints: InlayHintsOptions {
type_hints: config.inlay_hints_type,
parameter_hints: config.inlay_hints_parameter,
chaining_hints: config.inlay_hints_chaining,
max_length: config.inlay_hints_max_length,
},
cargo_watch: CheckOptions {
enable: config.cargo_watch_enable,
args: config.cargo_watch_args,
command: config.cargo_watch_command,
all_targets: config.cargo_watch_all_targets,
},
rustfmt_args: config.rustfmt_args,
vscode_lldb: config.vscode_lldb,
}
};
WorldState::new( WorldState::new(
ws_roots, ws_roots,
workspaces, workspaces,
config.lru_capacity, config.lru_capacity,
&globs, &globs,
Watch(!config.use_client_watching), Watch(!config.use_client_watching),
options, get_options(&config, text_document_caps),
feature_flags, feature_flags,
) )
}; };
@ -243,17 +249,16 @@ pub fn main_loop(
break; break;
}; };
} }
if let Some(new_server_config) = loop_turn( loop_turn(
&pool, &pool,
&task_sender, &task_sender,
&libdata_sender, &libdata_sender,
&connection, &connection,
text_document_caps,
&mut world_state, &mut world_state,
&mut loop_state, &mut loop_state,
event, event,
)? { )?;
dbg!(new_server_config);
}
} }
} }
world_state.analysis_host.request_cancellation(); world_state.analysis_host.request_cancellation();
@ -360,10 +365,11 @@ fn loop_turn(
task_sender: &Sender<Task>, task_sender: &Sender<Task>,
libdata_sender: &Sender<LibraryData>, libdata_sender: &Sender<LibraryData>,
connection: &Connection, connection: &Connection,
text_document_caps: Option<&TextDocumentClientCapabilities>,
world_state: &mut WorldState, world_state: &mut WorldState,
loop_state: &mut LoopState, loop_state: &mut LoopState,
event: Event, event: Event,
) -> Result<Option<ServerConfig>> { ) -> Result<()> {
let loop_start = Instant::now(); let loop_start = Instant::now();
// NOTE: don't count blocking select! call as a loop-turn time // NOTE: don't count blocking select! call as a loop-turn time
@ -374,8 +380,6 @@ fn loop_turn(
log::info!("queued count = {}", queue_count); log::info!("queued count = {}", queue_count);
} }
let mut new_server_config = None;
match event { match event {
Event::Task(task) => { Event::Task(task) => {
on_task(task, &connection.sender, &mut loop_state.pending_requests, world_state); on_task(task, &connection.sender, &mut loop_state.pending_requests, world_state);
@ -411,13 +415,18 @@ fn loop_turn(
} }
if Some(&resp.id) == loop_state.configuration_request_id.as_ref() { if Some(&resp.id) == loop_state.configuration_request_id.as_ref() {
loop_state.configuration_request_id.take(); loop_state.configuration_request_id.take();
// TODO kb unwrap-unwrap-unwrap
let new_config = let new_config =
serde_json::from_value::<Vec<ServerConfig>>(resp.result.unwrap()) serde_json::from_value::<Vec<ServerConfig>>(resp.result.unwrap())
.unwrap() .unwrap()
.first() .first()
.unwrap() .unwrap()
.to_owned(); .to_owned();
new_server_config = Some(new_config); world_state.update_configuration(
new_config.lru_capacity,
get_options(&new_config, text_document_caps),
get_feature_flags(&new_config, connection),
);
} }
} }
}, },
@ -488,7 +497,7 @@ fn loop_turn(
} }
} }
Ok(new_server_config) Ok(())
} }
fn on_task( fn on_task(

View file

@ -199,6 +199,17 @@ impl WorldState {
} }
} }
pub fn update_configuration(
&mut self,
lru_capacity: Option<usize>,
options: Options,
feature_flags: FeatureFlags,
) {
self.feature_flags = Arc::new(feature_flags);
self.analysis_host.update_lru_capacity(lru_capacity);
self.options = options;
}
/// Returns a vec of libraries /// Returns a vec of libraries
/// FIXME: better API here /// FIXME: better API here
pub fn process_changes( pub fn process_changes(