mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Merge #6027
6027: Spawn a flycheck instance per workspace r=matklad a=jonas-schievink Limitations: - All instances are restarted on every file change - There's only one configuration used for all of them Co-authored-by: Jonas Schievink <jonas.schievink@ferrous-systems.com>
This commit is contained in:
commit
ca48c4534b
@ -59,11 +59,12 @@ pub struct FlycheckHandle {
|
|||||||
|
|
||||||
impl FlycheckHandle {
|
impl FlycheckHandle {
|
||||||
pub fn spawn(
|
pub fn spawn(
|
||||||
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(Message) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
) -> FlycheckHandle {
|
) -> FlycheckHandle {
|
||||||
let actor = FlycheckActor::new(sender, config, workspace_root);
|
let actor = FlycheckActor::new(id, sender, config, workspace_root);
|
||||||
let (sender, receiver) = unbounded::<Restart>();
|
let (sender, receiver) = unbounded::<Restart>();
|
||||||
let thread = jod_thread::spawn(move || actor.run(receiver));
|
let thread = jod_thread::spawn(move || actor.run(receiver));
|
||||||
FlycheckHandle { sender, thread }
|
FlycheckHandle { sender, thread }
|
||||||
@ -81,7 +82,11 @@ pub enum Message {
|
|||||||
AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic },
|
AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic },
|
||||||
|
|
||||||
/// Request check progress notification to client
|
/// Request check progress notification to client
|
||||||
Progress(Progress),
|
Progress {
|
||||||
|
/// Flycheck instance ID
|
||||||
|
id: usize,
|
||||||
|
progress: Progress,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -95,6 +100,7 @@ pub enum Progress {
|
|||||||
struct Restart;
|
struct Restart;
|
||||||
|
|
||||||
struct FlycheckActor {
|
struct FlycheckActor {
|
||||||
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(Message) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
@ -113,11 +119,15 @@ enum Event {
|
|||||||
|
|
||||||
impl FlycheckActor {
|
impl FlycheckActor {
|
||||||
fn new(
|
fn new(
|
||||||
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(Message) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
) -> FlycheckActor {
|
) -> FlycheckActor {
|
||||||
FlycheckActor { sender, config, workspace_root, cargo_handle: None }
|
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
|
||||||
|
}
|
||||||
|
fn progress(&self, progress: Progress) {
|
||||||
|
self.send(Message::Progress { id: self.id, progress });
|
||||||
}
|
}
|
||||||
fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
|
fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
|
||||||
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
|
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
|
||||||
@ -139,7 +149,7 @@ impl FlycheckActor {
|
|||||||
command.stdout(Stdio::piped()).stderr(Stdio::null()).stdin(Stdio::null());
|
command.stdout(Stdio::piped()).stderr(Stdio::null()).stdin(Stdio::null());
|
||||||
if let Ok(child) = command.spawn().map(JodChild) {
|
if let Ok(child) = command.spawn().map(JodChild) {
|
||||||
self.cargo_handle = Some(CargoHandle::spawn(child));
|
self.cargo_handle = Some(CargoHandle::spawn(child));
|
||||||
self.send(Message::Progress(Progress::DidStart));
|
self.progress(Progress::DidStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::CheckEvent(None) => {
|
Event::CheckEvent(None) => {
|
||||||
@ -153,11 +163,11 @@ impl FlycheckActor {
|
|||||||
self.check_command()
|
self.check_command()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
self.send(Message::Progress(Progress::DidFinish(res)));
|
self.progress(Progress::DidFinish(res));
|
||||||
}
|
}
|
||||||
Event::CheckEvent(Some(message)) => match message {
|
Event::CheckEvent(Some(message)) => match message {
|
||||||
cargo_metadata::Message::CompilerArtifact(msg) => {
|
cargo_metadata::Message::CompilerArtifact(msg) => {
|
||||||
self.send(Message::Progress(Progress::DidCheckCrate(msg.target.name)));
|
self.progress(Progress::DidCheckCrate(msg.target.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
cargo_metadata::Message::CompilerMessage(msg) => {
|
cargo_metadata::Message::CompilerMessage(msg) => {
|
||||||
@ -179,7 +189,7 @@ impl FlycheckActor {
|
|||||||
}
|
}
|
||||||
fn cancel_check_process(&mut self) {
|
fn cancel_check_process(&mut self) {
|
||||||
if self.cargo_handle.take().is_some() {
|
if self.cargo_handle.take().is_some() {
|
||||||
self.send(Message::Progress(Progress::DidCancel));
|
self.progress(Progress::DidCancel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn check_command(&self) -> Command {
|
fn check_command(&self) -> Command {
|
||||||
|
@ -63,7 +63,7 @@ pub(crate) struct GlobalState {
|
|||||||
req_queue: ReqQueue,
|
req_queue: ReqQueue,
|
||||||
pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
|
pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
|
||||||
pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
|
pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
|
||||||
pub(crate) flycheck: Option<FlycheckHandle>,
|
pub(crate) flycheck: Vec<FlycheckHandle>,
|
||||||
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
||||||
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
|
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
|
||||||
pub(crate) config: Config,
|
pub(crate) config: Config,
|
||||||
@ -115,7 +115,7 @@ impl GlobalState {
|
|||||||
req_queue: ReqQueue::default(),
|
req_queue: ReqQueue::default(),
|
||||||
task_pool,
|
task_pool,
|
||||||
loader,
|
loader,
|
||||||
flycheck: None,
|
flycheck: Vec::new(),
|
||||||
flycheck_sender,
|
flycheck_sender,
|
||||||
flycheck_receiver,
|
flycheck_receiver,
|
||||||
config,
|
config,
|
||||||
|
@ -266,8 +266,8 @@ impl GlobalState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flycheck::Message::Progress(status) => {
|
flycheck::Message::Progress { id, progress } => {
|
||||||
let (state, message) = match status {
|
let (state, message) = match progress {
|
||||||
flycheck::Progress::DidStart => {
|
flycheck::Progress::DidStart => {
|
||||||
self.diagnostics.clear_check();
|
self.diagnostics.clear_check();
|
||||||
(Progress::Begin, None)
|
(Progress::Begin, None)
|
||||||
@ -284,14 +284,21 @@ impl GlobalState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.report_progress("cargo check", state, message, None);
|
// When we're running multiple flychecks, we have to include a disambiguator in
|
||||||
|
// the title, or the editor complains. Note that this is a user-facing string.
|
||||||
|
let title = if self.flycheck.len() == 1 {
|
||||||
|
"cargo check".to_string()
|
||||||
|
} else {
|
||||||
|
format!("cargo check (#{})", id + 1)
|
||||||
|
};
|
||||||
|
self.report_progress(&title, state, message, None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let state_changed = self.process_changes();
|
let state_changed = self.process_changes();
|
||||||
if prev_status == Status::Loading && self.status == Status::Ready {
|
if prev_status == Status::Loading && self.status == Status::Ready {
|
||||||
if let Some(flycheck) = &self.flycheck {
|
for flycheck in &self.flycheck {
|
||||||
flycheck.update();
|
flycheck.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,7 +497,7 @@ impl GlobalState {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})?
|
})?
|
||||||
.on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
|
.on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
|
||||||
if let Some(flycheck) = &this.flycheck {
|
for flycheck in &this.flycheck {
|
||||||
flycheck.update();
|
flycheck.update();
|
||||||
}
|
}
|
||||||
if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) {
|
if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) {
|
||||||
|
@ -235,29 +235,37 @@ impl GlobalState {
|
|||||||
let config = match self.config.flycheck.clone() {
|
let config = match self.config.flycheck.clone() {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => {
|
None => {
|
||||||
self.flycheck = None;
|
self.flycheck = Vec::new();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let sender = self.flycheck_sender.clone();
|
let sender = self.flycheck_sender.clone();
|
||||||
let sender = Box::new(move |msg| sender.send(msg).unwrap());
|
|
||||||
self.flycheck = self
|
self.flycheck = self
|
||||||
.workspaces
|
.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
// FIXME: Figure out the multi-workspace situation
|
.enumerate()
|
||||||
.find_map(|w| match w {
|
.filter_map(|(id, w)| match w {
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some(cargo.workspace_root()),
|
ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some((id, cargo.workspace_root())),
|
||||||
ProjectWorkspace::Json { project, .. } => {
|
ProjectWorkspace::Json { project, .. } => {
|
||||||
// Enable flychecks for json projects if a custom flycheck command was supplied
|
// Enable flychecks for json projects if a custom flycheck command was supplied
|
||||||
// in the workspace configuration.
|
// in the workspace configuration.
|
||||||
match config {
|
match config {
|
||||||
FlycheckConfig::CustomCommand { .. } => Some(project.path()),
|
FlycheckConfig::CustomCommand { .. } => Some((id, project.path())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(move |root| FlycheckHandle::spawn(sender, config, root.to_path_buf().into()))
|
.map(|(id, root)| {
|
||||||
|
let sender = sender.clone();
|
||||||
|
FlycheckHandle::spawn(
|
||||||
|
id,
|
||||||
|
Box::new(move |msg| sender.send(msg).unwrap()),
|
||||||
|
config.clone(),
|
||||||
|
root.to_path_buf().into(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user