Skip to content

Commit

Permalink
LS: Proc macro disable option in config
Browse files Browse the repository at this point in the history
commit-id:175cfb33
  • Loading branch information
Draggu committed Nov 19, 2024
1 parent 662e069 commit 66ee879
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
19 changes: 19 additions & 0 deletions crates/cairo-lang-language-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ pub struct Config {
/// The property is set by the user under the `cairo1.traceMacroDiagnostics` key in client
/// configuration.
pub trace_macro_diagnostics: bool,
/// Whether to resolve procedural macros or ignore them.
///
/// The property is set by the user under the `cairo1.disableProcMacros` key in client
/// configuration.
///
/// - `false`: Procedural macro server will start.
/// - `true`: Procedural macro server will **not** start.
/// - `None`: Temporarily behaves like `false` until the configuration is loaded from the
/// client. This prevents the server from starting prematurely.
pub disable_proc_macros: Option<bool>,
}

impl Config {
Expand All @@ -61,6 +71,10 @@ impl Config {
scope_uri: None,
section: Some("cairo1.traceMacroDiagnostics".to_owned()),
},
ConfigurationItem {
scope_uri: None,
section: Some("cairo1.disableProcMacros".to_owned()),
},
];
let expected_len = items.len();

Expand All @@ -86,8 +100,13 @@ impl Config {
.map(Into::into);
state.config.trace_macro_diagnostics =
response.pop_front().as_ref().and_then(Value::as_bool).unwrap_or_default();
state.config.disable_proc_macros = Some(
response.pop_front().as_ref().and_then(Value::as_bool).unwrap_or_default(),
);

debug!("reloaded configuration: {:#?}", state.config);

state.proc_macro_controller.initialize_once(&mut state.db, &state.config);
})
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use tracing::error;
use super::client::connection::ProcMacroServerConnection;
use super::client::status::ClientStatus;
use super::client::{ProcMacroClient, RequestParams};
use crate::config::Config;
use crate::lang::db::AnalysisDatabase;
use crate::lang::proc_macros::db::ProcMacroGroup;
use crate::lang::proc_macros::plugins::proc_macro_plugin_suite;
Expand Down Expand Up @@ -60,20 +61,24 @@ impl ProcMacroClientController {
}
}

/// Start proc-macro-server.
/// Start proc-macro-server after config reload.
/// Note that this will only try to go from `ClientStatus::Uninitialized` to
/// `ClientStatus::Initializing`.
pub fn initialize_once(&mut self, db: &mut AnalysisDatabase) {
/// `ClientStatus::Initializing` if config allows this.
pub fn initialize_once(&mut self, db: &mut AnalysisDatabase, config: &Config) {
if db.proc_macro_client_status().is_uninitialized() {
self.try_initialize(db);
self.try_initialize(db, config);
}
}

/// Tries starting proc-macro-server initialization process.
/// Tries starting proc-macro-server initialization process, if allowed by config.
///
/// Returns value indicating if initialization was attempted.
pub fn try_initialize(&mut self, db: &mut AnalysisDatabase) -> bool {
let initialize = self.initialization_retries.check().is_ok();
pub fn try_initialize(&mut self, db: &mut AnalysisDatabase, config: &Config) -> bool {
// Do not initialize if not yet received client config (None) or received `true`.
// Keep the rate limiter check as second condition when config doesn't allow it to make
// sure it is not impacted.
let initialize = config.disable_proc_macros == Some(false)
&& self.initialization_retries.check().is_ok();

if initialize {
self.spawn_server(db);
Expand Down Expand Up @@ -111,19 +116,19 @@ impl ProcMacroClientController {
self.notifier.notify::<ProcMacroServerInitializationFailed>(());
}

pub fn handle_error(&mut self, db: &mut AnalysisDatabase) {
if !self.try_initialize(db) {
pub fn handle_error(&mut self, db: &mut AnalysisDatabase, config: &Config) {
if !self.try_initialize(db, config) {
self.fatal_failed(db);
}
}

/// Check if there was error reported, if so try to restart.
/// If client is ready applies all available responses.
pub fn on_response(&mut self, db: &mut AnalysisDatabase) {
pub fn on_response(&mut self, db: &mut AnalysisDatabase, config: &Config) {
match db.proc_macro_client_status() {
ClientStatus::Initializing(client) => {
let Ok(defined_macros) = client.finish_initialize() else {
self.handle_error(db);
self.handle_error(db, config);

return;
};
Expand All @@ -143,14 +148,19 @@ impl ProcMacroClientController {
// possible with salsa public api. if there are snapshots running we
// can skip this job, this will lead to more updates at once later
// and less cancellation.
self.apply_responses(db, &client);
self.apply_responses(db, config, &client);
}
_ => {}
}
}

/// Process proc-macro-server responses by updating resolutions.
pub fn apply_responses(&mut self, db: &mut AnalysisDatabase, client: &ProcMacroClient) {
pub fn apply_responses(
&mut self,
db: &mut AnalysisDatabase,
config: &Config,
client: &ProcMacroClient,
) {
let mut attribute_resolutions = db.attribute_macro_resolution();
let mut attribute_resolutions_changed = false;

Expand Down Expand Up @@ -185,7 +195,7 @@ impl ProcMacroClientController {
Err(error) => {
error!("{error:#?}");

self.handle_error(db)
self.handle_error(db, config)
}
}
});
Expand Down
6 changes: 2 additions & 4 deletions crates/cairo-lang-language-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,6 @@ impl Backend {
event_loop_thread(move || {
let Self { mut state, connection } = self;

state.proc_macro_controller.initialize_once(&mut state.db);

let mut scheduler = Scheduler::new(&mut state, connection.make_sender());

Self::dispatch_setup_tasks(&mut scheduler);
Expand Down Expand Up @@ -394,13 +392,13 @@ impl Backend {
/// Calls [`lang::proc_macros::controller::ProcMacroClientController::handle_error`] to do its
/// work.
fn on_proc_macro_error(state: &mut State, _: Notifier, _: &mut Requester<'_>, _: Responder) {
state.proc_macro_controller.handle_error(&mut state.db);
state.proc_macro_controller.handle_error(&mut state.db, &state.config);
}

/// Calls [`lang::proc_macros::controller::ProcMacroClientController::on_response`] to do its
/// work.
fn on_proc_macro_response(state: &mut State, _: Notifier, _: &mut Requester<'_>, _: Responder) {
state.proc_macro_controller.on_response(&mut state.db);
state.proc_macro_controller.on_response(&mut state.db, &state.config);
}

/// Calls [`lang::db::AnalysisDatabaseSwapper::maybe_swap`] to do its work.
Expand Down

0 comments on commit 66ee879

Please sign in to comment.