mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Split up flycheck module
This commit is contained in:
parent
085e4126e6
commit
6bb29b1b54
9 changed files with 195 additions and 204 deletions
|
@ -74,106 +74,6 @@ pub struct ProjectJson {
|
|||
runnables: Vec<Runnable>,
|
||||
}
|
||||
|
||||
/// A crate points to the root module of a crate and lists the dependencies of the crate. This is
|
||||
/// useful in creating the crate graph.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Crate {
|
||||
pub(crate) display_name: Option<CrateDisplayName>,
|
||||
pub root_module: AbsPathBuf,
|
||||
pub(crate) edition: Edition,
|
||||
pub(crate) version: Option<String>,
|
||||
pub(crate) deps: Vec<Dep>,
|
||||
pub(crate) cfg: Vec<CfgAtom>,
|
||||
pub(crate) target: Option<String>,
|
||||
pub(crate) env: FxHashMap<String, String>,
|
||||
pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
|
||||
pub(crate) is_workspace_member: bool,
|
||||
pub(crate) include: Vec<AbsPathBuf>,
|
||||
pub(crate) exclude: Vec<AbsPathBuf>,
|
||||
pub(crate) is_proc_macro: bool,
|
||||
pub(crate) repository: Option<String>,
|
||||
pub build: Option<Build>,
|
||||
}
|
||||
|
||||
/// Additional, build-specific data about a crate.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Build {
|
||||
/// The name associated with this crate.
|
||||
///
|
||||
/// This is determined by the build system that produced
|
||||
/// the `rust-project.json` in question. For instance, if buck were used,
|
||||
/// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
|
||||
///
|
||||
/// Do not attempt to parse the contents of this string; it is a build system-specific
|
||||
/// identifier similar to [`Crate::display_name`].
|
||||
pub label: String,
|
||||
/// Path corresponding to the build system-specific file defining the crate.
|
||||
///
|
||||
/// It is roughly analogous to [`ManifestPath`], but it should *not* be used with
|
||||
/// [`crate::ProjectManifest::from_manifest_file`], as the build file may not be
|
||||
/// be in the `rust-project.json`.
|
||||
pub build_file: Utf8PathBuf,
|
||||
/// The kind of target.
|
||||
///
|
||||
/// Examples (non-exhaustively) include [`TargetKind::Bin`], [`TargetKind::Lib`],
|
||||
/// and [`TargetKind::Test`]. This information is used to determine what sort
|
||||
/// of runnable codelens to provide, if any.
|
||||
pub target_kind: TargetKind,
|
||||
}
|
||||
|
||||
/// A template-like structure for describing runnables.
|
||||
///
|
||||
/// These are used for running and debugging binaries and tests without encoding
|
||||
/// build system-specific knowledge into rust-analyzer.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Below is an example of a test runnable. `{label}` and `{test_id}`
|
||||
/// are explained in [`Runnable::args`]'s documentation.
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "program": "buck",
|
||||
/// "args": [
|
||||
/// "test",
|
||||
/// "{label}",
|
||||
/// "--",
|
||||
/// "{test_id}",
|
||||
/// "--print-passing-details"
|
||||
/// ],
|
||||
/// "cwd": "/home/user/repo-root/",
|
||||
/// "kind": "testOne"
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Runnable {
|
||||
/// The program invoked by the runnable.
|
||||
///
|
||||
/// For example, this might be `cargo`, `buck`, or `bazel`.
|
||||
pub program: String,
|
||||
/// The arguments passed to [`Runnable::program`].
|
||||
///
|
||||
/// The args can contain two template strings: `{label}` and `{test_id}`.
|
||||
/// rust-analyzer will find and replace `{label}` with [`Build::label`] and
|
||||
/// `{test_id}` with the test name.
|
||||
pub args: Vec<String>,
|
||||
/// The current working directory of the runnable.
|
||||
pub cwd: Utf8PathBuf,
|
||||
pub kind: RunnableKind,
|
||||
}
|
||||
|
||||
/// The kind of runnable.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RunnableKind {
|
||||
Check,
|
||||
|
||||
/// Can run a binary.
|
||||
Run,
|
||||
|
||||
/// Run a single test.
|
||||
TestOne,
|
||||
}
|
||||
|
||||
impl ProjectJson {
|
||||
/// Create a new ProjectJson instance.
|
||||
///
|
||||
|
@ -302,6 +202,106 @@ impl ProjectJson {
|
|||
}
|
||||
}
|
||||
|
||||
/// A crate points to the root module of a crate and lists the dependencies of the crate. This is
|
||||
/// useful in creating the crate graph.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Crate {
|
||||
pub(crate) display_name: Option<CrateDisplayName>,
|
||||
pub root_module: AbsPathBuf,
|
||||
pub(crate) edition: Edition,
|
||||
pub(crate) version: Option<String>,
|
||||
pub(crate) deps: Vec<Dep>,
|
||||
pub(crate) cfg: Vec<CfgAtom>,
|
||||
pub(crate) target: Option<String>,
|
||||
pub(crate) env: FxHashMap<String, String>,
|
||||
pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
|
||||
pub(crate) is_workspace_member: bool,
|
||||
pub(crate) include: Vec<AbsPathBuf>,
|
||||
pub(crate) exclude: Vec<AbsPathBuf>,
|
||||
pub(crate) is_proc_macro: bool,
|
||||
pub(crate) repository: Option<String>,
|
||||
pub build: Option<Build>,
|
||||
}
|
||||
|
||||
/// Additional, build-specific data about a crate.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Build {
|
||||
/// The name associated with this crate.
|
||||
///
|
||||
/// This is determined by the build system that produced
|
||||
/// the `rust-project.json` in question. For instance, if buck were used,
|
||||
/// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
|
||||
///
|
||||
/// Do not attempt to parse the contents of this string; it is a build system-specific
|
||||
/// identifier similar to [`Crate::display_name`].
|
||||
pub label: String,
|
||||
/// Path corresponding to the build system-specific file defining the crate.
|
||||
///
|
||||
/// It is roughly analogous to [`ManifestPath`], but it should *not* be used with
|
||||
/// [`crate::ProjectManifest::from_manifest_file`], as the build file may not be
|
||||
/// be in the `rust-project.json`.
|
||||
pub build_file: Utf8PathBuf,
|
||||
/// The kind of target.
|
||||
///
|
||||
/// Examples (non-exhaustively) include [`TargetKind::Bin`], [`TargetKind::Lib`],
|
||||
/// and [`TargetKind::Test`]. This information is used to determine what sort
|
||||
/// of runnable codelens to provide, if any.
|
||||
pub target_kind: TargetKind,
|
||||
}
|
||||
|
||||
/// A template-like structure for describing runnables.
|
||||
///
|
||||
/// These are used for running and debugging binaries and tests without encoding
|
||||
/// build system-specific knowledge into rust-analyzer.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Below is an example of a test runnable. `{label}` and `{test_id}`
|
||||
/// are explained in [`Runnable::args`]'s documentation.
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "program": "buck",
|
||||
/// "args": [
|
||||
/// "test",
|
||||
/// "{label}",
|
||||
/// "--",
|
||||
/// "{test_id}",
|
||||
/// "--print-passing-details"
|
||||
/// ],
|
||||
/// "cwd": "/home/user/repo-root/",
|
||||
/// "kind": "testOne"
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Runnable {
|
||||
/// The program invoked by the runnable.
|
||||
///
|
||||
/// For example, this might be `cargo`, `buck`, or `bazel`.
|
||||
pub program: String,
|
||||
/// The arguments passed to [`Runnable::program`].
|
||||
///
|
||||
/// The args can contain two template strings: `{label}` and `{test_id}`.
|
||||
/// rust-analyzer will find and replace `{label}` with [`Build::label`] and
|
||||
/// `{test_id}` with the test name.
|
||||
pub args: Vec<String>,
|
||||
/// The current working directory of the runnable.
|
||||
pub cwd: Utf8PathBuf,
|
||||
pub kind: RunnableKind,
|
||||
}
|
||||
|
||||
/// The kind of runnable.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RunnableKind {
|
||||
Check,
|
||||
|
||||
/// Can run a binary.
|
||||
Run,
|
||||
|
||||
/// Run a single test.
|
||||
TestOne,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ProjectJsonData {
|
||||
sysroot: Option<Utf8PathBuf>,
|
||||
|
@ -407,6 +407,29 @@ pub enum TargetKindData {
|
|||
Lib,
|
||||
Test,
|
||||
}
|
||||
/// Identifies a crate by position in the crates array.
|
||||
///
|
||||
/// This will differ from `CrateId` when multiple `ProjectJson`
|
||||
/// workspaces are loaded.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
#[serde(transparent)]
|
||||
pub struct CrateArrayIdx(pub usize);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) struct Dep {
|
||||
/// Identifies a crate by position in the crates array.
|
||||
#[serde(rename = "crate")]
|
||||
pub(crate) krate: CrateArrayIdx,
|
||||
#[serde(serialize_with = "serialize_crate_name")]
|
||||
#[serde(deserialize_with = "deserialize_crate_name")]
|
||||
pub(crate) name: CrateName,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
struct CrateSource {
|
||||
include_dirs: Vec<Utf8PathBuf>,
|
||||
exclude_dirs: Vec<Utf8PathBuf>,
|
||||
}
|
||||
|
||||
impl From<TargetKindData> for TargetKind {
|
||||
fn from(data: TargetKindData) -> Self {
|
||||
|
@ -445,30 +468,6 @@ impl From<RunnableKindData> for RunnableKind {
|
|||
}
|
||||
}
|
||||
|
||||
/// Identifies a crate by position in the crates array.
|
||||
///
|
||||
/// This will differ from `CrateId` when multiple `ProjectJson`
|
||||
/// workspaces are loaded.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
#[serde(transparent)]
|
||||
pub struct CrateArrayIdx(pub usize);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) struct Dep {
|
||||
/// Identifies a crate by position in the crates array.
|
||||
#[serde(rename = "crate")]
|
||||
pub(crate) krate: CrateArrayIdx,
|
||||
#[serde(serialize_with = "serialize_crate_name")]
|
||||
#[serde(deserialize_with = "deserialize_crate_name")]
|
||||
pub(crate) name: CrateName,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
struct CrateSource {
|
||||
include_dirs: Vec<Utf8PathBuf>,
|
||||
exclude_dirs: Vec<Utf8PathBuf>,
|
||||
}
|
||||
|
||||
fn deserialize_crate_name<'de, D>(de: D) -> std::result::Result<CrateName, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread and
|
||||
//! parse its stdout/stderr.
|
||||
//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread
|
||||
//! and parse its stdout/stderr.
|
||||
|
||||
use std::{
|
||||
ffi::OsString,
|
|
@ -1,4 +1,5 @@
|
|||
//! A `cargo-metadata`-equivalent for non-Cargo build systems.
|
||||
//! Infrastructure for lazy project discovery. Currently only support rust-project.json discovery
|
||||
//! via a custom discover command.
|
||||
use std::{io, process::Command};
|
||||
|
||||
use crossbeam_channel::Sender;
|
||||
|
@ -7,14 +8,14 @@ use project_model::ProjectJsonData;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::flycheck::{CommandHandle, ParseFromLine};
|
||||
use crate::command::{CommandHandle, ParseFromLine};
|
||||
|
||||
pub(crate) const ARG_PLACEHOLDER: &str = "{arg}";
|
||||
|
||||
/// A command wrapper for getting a `rust-project.json`.
|
||||
///
|
||||
/// This is analogous to `cargo-metadata`, but for non-Cargo build systems.
|
||||
pub(crate) struct Discover {
|
||||
/// This is analogous to discovering a cargo project + running `cargo-metadata` on it, but for non-Cargo build systems.
|
||||
pub(crate) struct DiscoverCommand {
|
||||
command: Vec<String>,
|
||||
sender: Sender<DiscoverProjectMessage>,
|
||||
}
|
||||
|
@ -34,8 +35,8 @@ where
|
|||
se.serialize_str(path.as_str())
|
||||
}
|
||||
|
||||
impl Discover {
|
||||
/// Create a new [Discover].
|
||||
impl DiscoverCommand {
|
||||
/// Create a new [DiscoverCommand].
|
||||
pub(crate) fn new(sender: Sender<DiscoverProjectMessage>, command: Vec<String>) -> Self {
|
||||
Self { sender, command }
|
||||
}
|
|
@ -1,11 +1,6 @@
|
|||
//! Flycheck provides the functionality needed to run `cargo check` or
|
||||
//! another compatible command (f.x. clippy) in a background thread and provide
|
||||
//! Flycheck provides the functionality needed to run `cargo check` to provide
|
||||
//! LSP diagnostics based on the output of the command.
|
||||
|
||||
// FIXME: This crate now handles running `cargo test` needed in the test explorer in
|
||||
// addition to `cargo check`. Either split it into 3 crates (one for test, one for check
|
||||
// and one common utilities) or change its name and docs to reflect the current state.
|
||||
|
||||
use std::{fmt, io, process::Command, time::Duration};
|
||||
|
||||
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
|
||||
|
@ -18,12 +13,7 @@ pub(crate) use cargo_metadata::diagnostic::{
|
|||
};
|
||||
use toolchain::Tool;
|
||||
|
||||
mod command;
|
||||
pub(crate) mod project_json;
|
||||
mod test_runner;
|
||||
|
||||
use command::{CommandHandle, ParseFromLine};
|
||||
pub(crate) use test_runner::{CargoTestHandle, CargoTestMessage, TestState, TestTarget};
|
||||
use crate::command::{CommandHandle, ParseFromLine};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub(crate) enum InvocationStrategy {
|
||||
|
@ -52,7 +42,7 @@ pub(crate) struct CargoOptions {
|
|||
}
|
||||
|
||||
impl CargoOptions {
|
||||
fn apply_on_command(&self, cmd: &mut Command) {
|
||||
pub(crate) fn apply_on_command(&self, cmd: &mut Command) {
|
||||
for target in &self.target_triples {
|
||||
cmd.args(["--target", target.as_str()]);
|
||||
}
|
||||
|
@ -119,7 +109,7 @@ pub(crate) struct FlycheckHandle {
|
|||
impl FlycheckHandle {
|
||||
pub(crate) fn spawn(
|
||||
id: usize,
|
||||
sender: Box<dyn Fn(Message) + Send>,
|
||||
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||
config: FlycheckConfig,
|
||||
sysroot_root: Option<AbsPathBuf>,
|
||||
workspace_root: AbsPathBuf,
|
||||
|
@ -157,7 +147,7 @@ impl FlycheckHandle {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) enum Message {
|
||||
pub(crate) enum FlycheckMessage {
|
||||
/// Request adding a diagnostic with fixes included to a file
|
||||
AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic },
|
||||
|
||||
|
@ -172,19 +162,19 @@ pub(crate) enum Message {
|
|||
},
|
||||
}
|
||||
|
||||
impl fmt::Debug for Message {
|
||||
impl fmt::Debug for FlycheckMessage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Message::AddDiagnostic { id, workspace_root, diagnostic } => f
|
||||
FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f
|
||||
.debug_struct("AddDiagnostic")
|
||||
.field("id", id)
|
||||
.field("workspace_root", workspace_root)
|
||||
.field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
|
||||
.finish(),
|
||||
Message::ClearDiagnostics { id } => {
|
||||
FlycheckMessage::ClearDiagnostics { id } => {
|
||||
f.debug_struct("ClearDiagnostics").field("id", id).finish()
|
||||
}
|
||||
Message::Progress { id, progress } => {
|
||||
FlycheckMessage::Progress { id, progress } => {
|
||||
f.debug_struct("Progress").field("id", id).field("progress", progress).finish()
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +199,7 @@ enum StateChange {
|
|||
struct FlycheckActor {
|
||||
/// The workspace id of this flycheck instance.
|
||||
id: usize,
|
||||
sender: Box<dyn Fn(Message) + Send>,
|
||||
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||
config: FlycheckConfig,
|
||||
manifest_path: Option<AbsPathBuf>,
|
||||
/// Either the workspace root of the workspace we are flychecking,
|
||||
|
@ -245,7 +235,7 @@ pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
|
|||
impl FlycheckActor {
|
||||
fn new(
|
||||
id: usize,
|
||||
sender: Box<dyn Fn(Message) + Send>,
|
||||
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||
config: FlycheckConfig,
|
||||
sysroot_root: Option<AbsPathBuf>,
|
||||
workspace_root: AbsPathBuf,
|
||||
|
@ -266,7 +256,7 @@ impl FlycheckActor {
|
|||
}
|
||||
|
||||
fn report_progress(&self, progress: Progress) {
|
||||
self.send(Message::Progress { id: self.id, progress });
|
||||
self.send(FlycheckMessage::Progress { id: self.id, progress });
|
||||
}
|
||||
|
||||
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
|
||||
|
@ -339,7 +329,7 @@ impl FlycheckActor {
|
|||
);
|
||||
}
|
||||
if self.status == FlycheckStatus::Started {
|
||||
self.send(Message::ClearDiagnostics { id: self.id });
|
||||
self.send(FlycheckMessage::ClearDiagnostics { id: self.id });
|
||||
}
|
||||
self.report_progress(Progress::DidFinish(res));
|
||||
self.status = FlycheckStatus::Finished;
|
||||
|
@ -361,9 +351,9 @@ impl FlycheckActor {
|
|||
"diagnostic received"
|
||||
);
|
||||
if self.status == FlycheckStatus::Started {
|
||||
self.send(Message::ClearDiagnostics { id: self.id });
|
||||
self.send(FlycheckMessage::ClearDiagnostics { id: self.id });
|
||||
}
|
||||
self.send(Message::AddDiagnostic {
|
||||
self.send(FlycheckMessage::AddDiagnostic {
|
||||
id: self.id,
|
||||
workspace_root: self.root.clone(),
|
||||
diagnostic: msg,
|
||||
|
@ -488,7 +478,7 @@ impl FlycheckActor {
|
|||
Some(cmd)
|
||||
}
|
||||
|
||||
fn send(&self, check_task: Message) {
|
||||
fn send(&self, check_task: FlycheckMessage) {
|
||||
(self.sender)(check_task);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
use std::{ops::Not as _, time::Instant};
|
||||
|
||||
use crate::flycheck::{self, project_json, FlycheckHandle};
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use hir::ChangeWithProcMacros;
|
||||
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
|
||||
|
@ -28,6 +27,8 @@ use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs, VfsPath};
|
|||
use crate::{
|
||||
config::{Config, ConfigChange, ConfigErrors, RatomlFileKind},
|
||||
diagnostics::{CheckFixes, DiagnosticCollection},
|
||||
discover,
|
||||
flycheck::{FlycheckHandle, FlycheckMessage},
|
||||
line_index::{LineEndings, LineIndex},
|
||||
lsp::{from_proto, to_proto::url_from_abs_path},
|
||||
lsp_ext,
|
||||
|
@ -37,6 +38,7 @@ use crate::{
|
|||
reload,
|
||||
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
|
||||
task_pool::{TaskPool, TaskQueue},
|
||||
test_runner::{CargoTestHandle, CargoTestMessage},
|
||||
};
|
||||
|
||||
pub(crate) struct FetchWorkspaceRequest {
|
||||
|
@ -88,20 +90,20 @@ pub(crate) struct GlobalState {
|
|||
|
||||
// Flycheck
|
||||
pub(crate) flycheck: Arc<[FlycheckHandle]>,
|
||||
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
||||
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
|
||||
pub(crate) flycheck_sender: Sender<FlycheckMessage>,
|
||||
pub(crate) flycheck_receiver: Receiver<FlycheckMessage>,
|
||||
pub(crate) last_flycheck_error: Option<String>,
|
||||
|
||||
// Test explorer
|
||||
pub(crate) test_run_session: Option<Vec<flycheck::CargoTestHandle>>,
|
||||
pub(crate) test_run_sender: Sender<flycheck::CargoTestMessage>,
|
||||
pub(crate) test_run_receiver: Receiver<flycheck::CargoTestMessage>,
|
||||
pub(crate) test_run_session: Option<Vec<CargoTestHandle>>,
|
||||
pub(crate) test_run_sender: Sender<CargoTestMessage>,
|
||||
pub(crate) test_run_receiver: Receiver<CargoTestMessage>,
|
||||
pub(crate) test_run_remaining_jobs: usize,
|
||||
|
||||
// Project loading
|
||||
pub(crate) discover_handle: Option<project_json::DiscoverHandle>,
|
||||
pub(crate) discover_sender: Sender<project_json::DiscoverProjectMessage>,
|
||||
pub(crate) discover_receiver: Receiver<project_json::DiscoverProjectMessage>,
|
||||
pub(crate) discover_handle: Option<discover::DiscoverHandle>,
|
||||
pub(crate) discover_sender: Sender<discover::DiscoverProjectMessage>,
|
||||
pub(crate) discover_receiver: Receiver<discover::DiscoverProjectMessage>,
|
||||
|
||||
// VFS
|
||||
pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
|
||||
|
|
|
@ -51,6 +51,7 @@ use crate::{
|
|||
FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
|
||||
},
|
||||
target_spec::{CargoTargetSpec, TargetSpec},
|
||||
test_runner::{CargoTestHandle, TestTarget},
|
||||
};
|
||||
|
||||
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
|
||||
|
@ -246,15 +247,15 @@ pub(crate) fn handle_run_test(
|
|||
if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind {
|
||||
let test_target = if let Some(namespace_root) = namespace_root {
|
||||
if let Some(package_name) = find_package_name(namespace_root, cargo) {
|
||||
crate::flycheck::TestTarget::Package(package_name)
|
||||
TestTarget::Package(package_name)
|
||||
} else {
|
||||
crate::flycheck::TestTarget::Workspace
|
||||
TestTarget::Workspace
|
||||
}
|
||||
} else {
|
||||
crate::flycheck::TestTarget::Workspace
|
||||
TestTarget::Workspace
|
||||
};
|
||||
|
||||
let handle = crate::flycheck::CargoTestHandle::new(
|
||||
let handle = CargoTestHandle::new(
|
||||
test_path,
|
||||
state.config.cargo_test_options(),
|
||||
cargo.workspace_root(),
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
pub mod cli;
|
||||
|
||||
mod capabilities;
|
||||
mod command;
|
||||
mod diagnostics;
|
||||
mod diff;
|
||||
mod discover;
|
||||
mod dispatch;
|
||||
mod flycheck;
|
||||
mod hack_recover_crate_name;
|
||||
|
@ -24,6 +26,7 @@ mod op_queue;
|
|||
mod reload;
|
||||
mod target_spec;
|
||||
mod task_pool;
|
||||
mod test_runner;
|
||||
mod version;
|
||||
|
||||
mod handlers {
|
||||
|
|
|
@ -19,8 +19,9 @@ use vfs::{loader::LoadingProgress, AbsPathBuf, FileId};
|
|||
use crate::{
|
||||
config::Config,
|
||||
diagnostics::{fetch_native_diagnostics, DiagnosticsGeneration, NativeDiagnosticsFetchKind},
|
||||
discover::{DiscoverArgument, DiscoverCommand, DiscoverProjectMessage},
|
||||
dispatch::{NotificationDispatcher, RequestDispatcher},
|
||||
flycheck::{self, project_json},
|
||||
flycheck::{self, FlycheckMessage},
|
||||
global_state::{file_id_to_url, url_to_file_id, FetchWorkspaceRequest, GlobalState},
|
||||
hack_recover_crate_name,
|
||||
lsp::{
|
||||
|
@ -29,6 +30,7 @@ use crate::{
|
|||
},
|
||||
lsp_ext,
|
||||
reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
|
||||
test_runner::{CargoTestMessage, TestState},
|
||||
};
|
||||
|
||||
pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> {
|
||||
|
@ -61,9 +63,9 @@ enum Event {
|
|||
Task(Task),
|
||||
QueuedTask(QueuedTask),
|
||||
Vfs(vfs::loader::Message),
|
||||
Flycheck(flycheck::Message),
|
||||
TestResult(flycheck::CargoTestMessage),
|
||||
DiscoverProject(project_json::DiscoverProjectMessage),
|
||||
Flycheck(FlycheckMessage),
|
||||
TestResult(CargoTestMessage),
|
||||
DiscoverProject(DiscoverProjectMessage),
|
||||
}
|
||||
|
||||
impl fmt::Display for Event {
|
||||
|
@ -689,8 +691,7 @@ impl GlobalState {
|
|||
// `self.report_progress` is called later
|
||||
let title = &cfg.progress_label.clone();
|
||||
let command = cfg.command.clone();
|
||||
let discover =
|
||||
project_json::Discover::new(self.discover_sender.clone(), command);
|
||||
let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
|
||||
|
||||
self.report_progress(title, Progress::Begin, None, None, None);
|
||||
self.discover_workspace_queue
|
||||
|
@ -698,12 +699,8 @@ impl GlobalState {
|
|||
let _ = self.discover_workspace_queue.should_start_op();
|
||||
|
||||
let arg = match arg {
|
||||
DiscoverProjectParam::Buildfile(it) => {
|
||||
project_json::DiscoverArgument::Buildfile(it)
|
||||
}
|
||||
DiscoverProjectParam::Path(it) => {
|
||||
project_json::DiscoverArgument::Path(it)
|
||||
}
|
||||
DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
|
||||
DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
|
||||
};
|
||||
|
||||
let handle = discover.spawn(arg).unwrap();
|
||||
|
@ -852,14 +849,14 @@ impl GlobalState {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_discover_msg(&mut self, message: project_json::DiscoverProjectMessage) {
|
||||
fn handle_discover_msg(&mut self, message: DiscoverProjectMessage) {
|
||||
let title = self
|
||||
.config
|
||||
.discover_workspace_config()
|
||||
.map(|cfg| cfg.progress_label.clone())
|
||||
.expect("No title could be found; this is a bug");
|
||||
match message {
|
||||
project_json::DiscoverProjectMessage::Finished { project, buildfile } => {
|
||||
DiscoverProjectMessage::Finished { project, buildfile } => {
|
||||
self.report_progress(&title, Progress::End, None, None, None);
|
||||
self.discover_workspace_queue.op_completed(());
|
||||
|
||||
|
@ -867,10 +864,10 @@ impl GlobalState {
|
|||
config.add_linked_projects(project, buildfile);
|
||||
self.update_configuration(config);
|
||||
}
|
||||
project_json::DiscoverProjectMessage::Progress { message } => {
|
||||
DiscoverProjectMessage::Progress { message } => {
|
||||
self.report_progress(&title, Progress::Report, Some(message), None, None)
|
||||
}
|
||||
project_json::DiscoverProjectMessage::Error { error, source } => {
|
||||
DiscoverProjectMessage::Error { error, source } => {
|
||||
let message = format!("Project discovery failed: {error}");
|
||||
self.discover_workspace_queue.op_completed(());
|
||||
self.show_and_log_error(message.clone(), source);
|
||||
|
@ -879,16 +876,14 @@ impl GlobalState {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_cargo_test_msg(&mut self, message: flycheck::CargoTestMessage) {
|
||||
fn handle_cargo_test_msg(&mut self, message: CargoTestMessage) {
|
||||
match message {
|
||||
flycheck::CargoTestMessage::Test { name, state } => {
|
||||
CargoTestMessage::Test { name, state } => {
|
||||
let state = match state {
|
||||
flycheck::TestState::Started => lsp_ext::TestState::Started,
|
||||
flycheck::TestState::Ignored => lsp_ext::TestState::Skipped,
|
||||
flycheck::TestState::Ok => lsp_ext::TestState::Passed,
|
||||
flycheck::TestState::Failed { stdout } => {
|
||||
lsp_ext::TestState::Failed { message: stdout }
|
||||
}
|
||||
TestState::Started => lsp_ext::TestState::Started,
|
||||
TestState::Ignored => lsp_ext::TestState::Skipped,
|
||||
TestState::Ok => lsp_ext::TestState::Passed,
|
||||
TestState::Failed { stdout } => lsp_ext::TestState::Failed { message: stdout },
|
||||
};
|
||||
let Some(test_id) = hack_recover_crate_name::lookup_name(name) else {
|
||||
return;
|
||||
|
@ -897,23 +892,23 @@ impl GlobalState {
|
|||
lsp_ext::ChangeTestStateParams { test_id, state },
|
||||
);
|
||||
}
|
||||
flycheck::CargoTestMessage::Suite => (),
|
||||
flycheck::CargoTestMessage::Finished => {
|
||||
CargoTestMessage::Suite => (),
|
||||
CargoTestMessage::Finished => {
|
||||
self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1);
|
||||
if self.test_run_remaining_jobs == 0 {
|
||||
self.send_notification::<lsp_ext::EndRunTest>(());
|
||||
self.test_run_session = None;
|
||||
}
|
||||
}
|
||||
flycheck::CargoTestMessage::Custom { text } => {
|
||||
CargoTestMessage::Custom { text } => {
|
||||
self.send_notification::<lsp_ext::AppendOutputToRunTest>(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_flycheck_msg(&mut self, message: flycheck::Message) {
|
||||
fn handle_flycheck_msg(&mut self, message: FlycheckMessage) {
|
||||
match message {
|
||||
flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
|
||||
FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => {
|
||||
let snap = self.snapshot();
|
||||
let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
|
||||
&self.config.diagnostics_map(),
|
||||
|
@ -939,9 +934,9 @@ impl GlobalState {
|
|||
}
|
||||
}
|
||||
|
||||
flycheck::Message::ClearDiagnostics { id } => self.diagnostics.clear_check(id),
|
||||
FlycheckMessage::ClearDiagnostics { id } => self.diagnostics.clear_check(id),
|
||||
|
||||
flycheck::Message::Progress { id, progress } => {
|
||||
FlycheckMessage::Progress { id, progress } => {
|
||||
let (state, message) = match progress {
|
||||
flycheck::Progress::DidStart => (Progress::Begin, None),
|
||||
flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
|
||||
|
|
|
@ -8,9 +8,9 @@ use paths::AbsPath;
|
|||
use serde::Deserialize;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::flycheck::{
|
||||
use crate::{
|
||||
command::{CommandHandle, ParseFromLine},
|
||||
CargoOptions,
|
||||
flycheck::CargoOptions,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
Loading…
Reference in a new issue