mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #17831 - Veykril:flycheck-move-to-rust-analyzer, r=Veykril
internal: Move and split flycheck crate into rust-analyzer main crate The crate no longer is about flychecking, it mainly hosts common command process handling shared by flycheck, test explorer and now project discovery. This re-organizes that into the main crate.
This commit is contained in:
commit
34d9409211
16 changed files with 252 additions and 303 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -423,23 +423,6 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "flycheck"
|
|
||||||
version = "0.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"cargo_metadata",
|
|
||||||
"crossbeam-channel",
|
|
||||||
"paths",
|
|
||||||
"process-wrap",
|
|
||||||
"project-model",
|
|
||||||
"rustc-hash",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"stdx",
|
|
||||||
"toolchain",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -1650,12 +1633,12 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"always-assert",
|
"always-assert",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"cargo_metadata",
|
||||||
"cfg",
|
"cfg",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dirs",
|
"dirs",
|
||||||
"dissimilar",
|
"dissimilar",
|
||||||
"expect-test",
|
"expect-test",
|
||||||
"flycheck",
|
|
||||||
"hir",
|
"hir",
|
||||||
"hir-def",
|
"hir-def",
|
||||||
"hir-ty",
|
"hir-ty",
|
||||||
|
@ -1676,6 +1659,7 @@ dependencies = [
|
||||||
"parser",
|
"parser",
|
||||||
"paths",
|
"paths",
|
||||||
"proc-macro-api",
|
"proc-macro-api",
|
||||||
|
"process-wrap",
|
||||||
"profile",
|
"profile",
|
||||||
"project-model",
|
"project-model",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
|
|
@ -52,7 +52,6 @@ debug = 2
|
||||||
# local crates
|
# local crates
|
||||||
base-db = { path = "./crates/base-db", version = "0.0.0" }
|
base-db = { path = "./crates/base-db", version = "0.0.0" }
|
||||||
cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
|
cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
|
||||||
flycheck = { path = "./crates/flycheck", version = "0.0.0" }
|
|
||||||
hir = { path = "./crates/hir", version = "0.0.0" }
|
hir = { path = "./crates/hir", version = "0.0.0" }
|
||||||
hir-def = { path = "./crates/hir-def", version = "0.0.0" }
|
hir-def = { path = "./crates/hir-def", version = "0.0.0" }
|
||||||
hir-expand = { path = "./crates/hir-expand", version = "0.0.0" }
|
hir-expand = { path = "./crates/hir-expand", version = "0.0.0" }
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "flycheck"
|
|
||||||
version = "0.0.0"
|
|
||||||
repository.workspace = true
|
|
||||||
description = "Functionality needed for rust-analyzer to run `cargo` commands in a background thread."
|
|
||||||
|
|
||||||
authors.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
rust-version.workspace = true
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
doctest = false
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
cargo_metadata.workspace = true
|
|
||||||
crossbeam-channel.workspace = true
|
|
||||||
tracing.workspace = true
|
|
||||||
rustc-hash.workspace = true
|
|
||||||
serde_json.workspace = true
|
|
||||||
serde.workspace = true
|
|
||||||
process-wrap.workspace = true
|
|
||||||
|
|
||||||
# local deps
|
|
||||||
paths.workspace = true
|
|
||||||
stdx.workspace = true
|
|
||||||
toolchain.workspace = true
|
|
||||||
project-model.workspace = true
|
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
|
@ -74,106 +74,6 @@ pub struct ProjectJson {
|
||||||
runnables: Vec<Runnable>,
|
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 {
|
impl ProjectJson {
|
||||||
/// Create a new ProjectJson instance.
|
/// 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)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct ProjectJsonData {
|
pub struct ProjectJsonData {
|
||||||
sysroot: Option<Utf8PathBuf>,
|
sysroot: Option<Utf8PathBuf>,
|
||||||
|
@ -407,6 +407,29 @@ pub enum TargetKindData {
|
||||||
Lib,
|
Lib,
|
||||||
Test,
|
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 {
|
impl From<TargetKindData> for TargetKind {
|
||||||
fn from(data: TargetKindData) -> Self {
|
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>
|
fn deserialize_crate_name<'de, D>(de: D) -> std::result::Result<CrateName, D::Error>
|
||||||
where
|
where
|
||||||
D: de::Deserializer<'de>,
|
D: de::Deserializer<'de>,
|
||||||
|
|
|
@ -47,9 +47,10 @@ always-assert = "0.2.0"
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
semver.workspace = true
|
semver.workspace = true
|
||||||
memchr = "2.7.1"
|
memchr = "2.7.1"
|
||||||
|
cargo_metadata.workspace = true
|
||||||
|
process-wrap.workspace = true
|
||||||
|
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
flycheck.workspace = true
|
|
||||||
hir-def.workspace = true
|
hir-def.workspace = true
|
||||||
hir-ty.workspace = true
|
hir-ty.workspace = true
|
||||||
hir.workspace = true
|
hir.workspace = true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread and
|
//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread
|
||||||
//! parse its stdout/stderr.
|
//! and parse its stdout/stderr.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsString,
|
ffi::OsString,
|
|
@ -7,7 +7,6 @@ use std::{fmt, iter, ops::Not, sync::OnceLock};
|
||||||
|
|
||||||
use cfg::{CfgAtom, CfgDiff};
|
use cfg::{CfgAtom, CfgDiff};
|
||||||
use dirs::config_dir;
|
use dirs::config_dir;
|
||||||
use flycheck::{CargoOptions, FlycheckConfig};
|
|
||||||
use hir::Symbol;
|
use hir::Symbol;
|
||||||
use ide::{
|
use ide::{
|
||||||
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
|
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
|
||||||
|
@ -37,6 +36,7 @@ use vfs::{AbsPath, AbsPathBuf, VfsPath};
|
||||||
use crate::{
|
use crate::{
|
||||||
capabilities::ClientCapabilities,
|
capabilities::ClientCapabilities,
|
||||||
diagnostics::DiagnosticsMapConfig,
|
diagnostics::DiagnosticsMapConfig,
|
||||||
|
flycheck::{CargoOptions, FlycheckConfig},
|
||||||
lsp_ext::{WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope},
|
lsp_ext::{WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1899,7 +1899,7 @@ impl Config {
|
||||||
*self.check_workspace(None)
|
*self.check_workspace(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cargo_test_options(&self) -> CargoOptions {
|
pub(crate) fn cargo_test_options(&self) -> CargoOptions {
|
||||||
CargoOptions {
|
CargoOptions {
|
||||||
target_triples: self.cargo_target(None).clone().into_iter().collect(),
|
target_triples: self.cargo_target(None).clone().into_iter().collect(),
|
||||||
all_targets: false,
|
all_targets: false,
|
||||||
|
@ -1915,7 +1915,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flycheck(&self) -> FlycheckConfig {
|
pub(crate) fn flycheck(&self) -> FlycheckConfig {
|
||||||
match &self.check_overrideCommand(None) {
|
match &self.check_overrideCommand(None) {
|
||||||
Some(args) if !args.is_empty() => {
|
Some(args) if !args.is_empty() => {
|
||||||
let mut args = args.clone();
|
let mut args = args.clone();
|
||||||
|
@ -1925,16 +1925,18 @@ impl Config {
|
||||||
args,
|
args,
|
||||||
extra_env: self.check_extra_env(),
|
extra_env: self.check_extra_env(),
|
||||||
invocation_strategy: match self.check_invocationStrategy(None) {
|
invocation_strategy: match self.check_invocationStrategy(None) {
|
||||||
InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
|
InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once,
|
||||||
InvocationStrategy::PerWorkspace => {
|
InvocationStrategy::PerWorkspace => {
|
||||||
flycheck::InvocationStrategy::PerWorkspace
|
crate::flycheck::InvocationStrategy::PerWorkspace
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
invocation_location: match self.check_invocationLocation(None) {
|
invocation_location: match self.check_invocationLocation(None) {
|
||||||
InvocationLocation::Root => {
|
InvocationLocation::Root => {
|
||||||
flycheck::InvocationLocation::Root(self.root_path.clone())
|
crate::flycheck::InvocationLocation::Root(self.root_path.clone())
|
||||||
|
}
|
||||||
|
InvocationLocation::Workspace => {
|
||||||
|
crate::flycheck::InvocationLocation::Workspace
|
||||||
}
|
}
|
||||||
InvocationLocation::Workspace => flycheck::InvocationLocation::Workspace,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! This module provides the functionality needed to convert diagnostics from
|
//! This module provides the functionality needed to convert diagnostics from
|
||||||
//! `cargo check` json format to the LSP diagnostic format.
|
//! `cargo check` json format to the LSP diagnostic format.
|
||||||
|
|
||||||
use flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
|
use crate::flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
@ -17,8 +17,8 @@ use super::{DiagnosticsMapConfig, Fix};
|
||||||
/// Determines the LSP severity from a diagnostic
|
/// Determines the LSP severity from a diagnostic
|
||||||
fn diagnostic_severity(
|
fn diagnostic_severity(
|
||||||
config: &DiagnosticsMapConfig,
|
config: &DiagnosticsMapConfig,
|
||||||
level: flycheck::DiagnosticLevel,
|
level: crate::flycheck::DiagnosticLevel,
|
||||||
code: Option<flycheck::DiagnosticCode>,
|
code: Option<crate::flycheck::DiagnosticCode>,
|
||||||
) -> Option<lsp_types::DiagnosticSeverity> {
|
) -> Option<lsp_types::DiagnosticSeverity> {
|
||||||
let res = match level {
|
let res = match level {
|
||||||
DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::ERROR,
|
DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::ERROR,
|
||||||
|
@ -181,7 +181,7 @@ enum MappedRustChildDiagnostic {
|
||||||
fn map_rust_child_diagnostic(
|
fn map_rust_child_diagnostic(
|
||||||
config: &DiagnosticsMapConfig,
|
config: &DiagnosticsMapConfig,
|
||||||
workspace_root: &AbsPath,
|
workspace_root: &AbsPath,
|
||||||
rd: &flycheck::Diagnostic,
|
rd: &crate::flycheck::Diagnostic,
|
||||||
snap: &GlobalStateSnapshot,
|
snap: &GlobalStateSnapshot,
|
||||||
) -> MappedRustChildDiagnostic {
|
) -> MappedRustChildDiagnostic {
|
||||||
let spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect();
|
let spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect();
|
||||||
|
@ -284,7 +284,7 @@ pub(crate) struct MappedRustDiagnostic {
|
||||||
/// If the diagnostic has no primary span this will return `None`
|
/// If the diagnostic has no primary span this will return `None`
|
||||||
pub(crate) fn map_rust_diagnostic_to_lsp(
|
pub(crate) fn map_rust_diagnostic_to_lsp(
|
||||||
config: &DiagnosticsMapConfig,
|
config: &DiagnosticsMapConfig,
|
||||||
rd: &flycheck::Diagnostic,
|
rd: &crate::flycheck::Diagnostic,
|
||||||
workspace_root: &AbsPath,
|
workspace_root: &AbsPath,
|
||||||
snap: &GlobalStateSnapshot,
|
snap: &GlobalStateSnapshot,
|
||||||
) -> Vec<MappedRustDiagnostic> {
|
) -> Vec<MappedRustDiagnostic> {
|
||||||
|
@ -537,7 +537,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_with_config(config: DiagnosticsMapConfig, diagnostics_json: &str, expect: ExpectFile) {
|
fn check_with_config(config: DiagnosticsMapConfig, diagnostics_json: &str, expect: ExpectFile) {
|
||||||
let diagnostic: flycheck::Diagnostic = serde_json::from_str(diagnostics_json).unwrap();
|
let diagnostic: crate::flycheck::Diagnostic =
|
||||||
|
serde_json::from_str(diagnostics_json).unwrap();
|
||||||
let workspace_root: &AbsPath = Utf8Path::new("/test/").try_into().unwrap();
|
let workspace_root: &AbsPath = Utf8Path::new("/test/").try_into().unwrap();
|
||||||
let (sender, _) = crossbeam_channel::unbounded();
|
let (sender, _) = crossbeam_channel::unbounded();
|
||||||
let state = GlobalState::new(
|
let state = GlobalState::new(
|
||||||
|
|
|
@ -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 std::{io, process::Command};
|
||||||
|
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
|
@ -9,19 +10,19 @@ use serde_json::Value;
|
||||||
|
|
||||||
use crate::command::{CommandHandle, ParseFromLine};
|
use crate::command::{CommandHandle, ParseFromLine};
|
||||||
|
|
||||||
pub const ARG_PLACEHOLDER: &str = "{arg}";
|
pub(crate) const ARG_PLACEHOLDER: &str = "{arg}";
|
||||||
|
|
||||||
/// A command wrapper for getting a `rust-project.json`.
|
/// A command wrapper for getting a `rust-project.json`.
|
||||||
///
|
///
|
||||||
/// This is analogous to `cargo-metadata`, but for non-Cargo build systems.
|
/// This is analogous to discovering a cargo project + running `cargo-metadata` on it, but for non-Cargo build systems.
|
||||||
pub struct Discover {
|
pub(crate) struct DiscoverCommand {
|
||||||
command: Vec<String>,
|
command: Vec<String>,
|
||||||
sender: Sender<DiscoverProjectMessage>,
|
sender: Sender<DiscoverProjectMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug, Serialize)]
|
#[derive(PartialEq, Clone, Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum DiscoverArgument {
|
pub(crate) enum DiscoverArgument {
|
||||||
Path(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
|
Path(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
|
||||||
Buildfile(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
|
Buildfile(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
|
||||||
}
|
}
|
||||||
|
@ -34,14 +35,14 @@ where
|
||||||
se.serialize_str(path.as_str())
|
se.serialize_str(path.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Discover {
|
impl DiscoverCommand {
|
||||||
/// Create a new [Discover].
|
/// Create a new [DiscoverCommand].
|
||||||
pub fn new(sender: Sender<DiscoverProjectMessage>, command: Vec<String>) -> Self {
|
pub(crate) fn new(sender: Sender<DiscoverProjectMessage>, command: Vec<String>) -> Self {
|
||||||
Self { sender, command }
|
Self { sender, command }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn the command inside [Discover] and report progress, if any.
|
/// Spawn the command inside [Discover] and report progress, if any.
|
||||||
pub fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result<DiscoverHandle> {
|
pub(crate) fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result<DiscoverHandle> {
|
||||||
let command = &self.command[0];
|
let command = &self.command[0];
|
||||||
let args = &self.command[1..];
|
let args = &self.command[1..];
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ impl Discover {
|
||||||
|
|
||||||
/// A handle to a spawned [Discover].
|
/// A handle to a spawned [Discover].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DiscoverHandle {
|
pub(crate) struct DiscoverHandle {
|
||||||
_handle: CommandHandle<DiscoverProjectMessage>,
|
_handle: CommandHandle<DiscoverProjectMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ enum DiscoverProjectData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum DiscoverProjectMessage {
|
pub(crate) enum DiscoverProjectMessage {
|
||||||
Finished { project: ProjectJsonData, buildfile: AbsPathBuf },
|
Finished { project: ProjectJsonData, buildfile: AbsPathBuf },
|
||||||
Error { error: String, source: Option<String> },
|
Error { error: String, source: Option<String> },
|
||||||
Progress { message: String },
|
Progress { message: String },
|
|
@ -1,11 +1,6 @@
|
||||||
//! Flycheck provides the functionality needed to run `cargo check` or
|
//! Flycheck provides the functionality needed to run `cargo check` to provide
|
||||||
//! another compatible command (f.x. clippy) in a background thread and provide
|
|
||||||
//! LSP diagnostics based on the output of the command.
|
//! 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 std::{fmt, io, process::Command, time::Duration};
|
||||||
|
|
||||||
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
|
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
|
||||||
|
@ -13,47 +8,41 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub use cargo_metadata::diagnostic::{
|
pub(crate) use cargo_metadata::diagnostic::{
|
||||||
Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
|
Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
|
||||||
DiagnosticSpanMacroExpansion,
|
|
||||||
};
|
};
|
||||||
use toolchain::Tool;
|
use toolchain::Tool;
|
||||||
|
|
||||||
mod command;
|
use crate::command::{CommandHandle, ParseFromLine};
|
||||||
pub mod project_json;
|
|
||||||
mod test_runner;
|
|
||||||
|
|
||||||
use command::{CommandHandle, ParseFromLine};
|
|
||||||
pub use test_runner::{CargoTestHandle, CargoTestMessage, TestState, TestTarget};
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub enum InvocationStrategy {
|
pub(crate) enum InvocationStrategy {
|
||||||
Once,
|
Once,
|
||||||
#[default]
|
#[default]
|
||||||
PerWorkspace,
|
PerWorkspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub enum InvocationLocation {
|
pub(crate) enum InvocationLocation {
|
||||||
Root(AbsPathBuf),
|
Root(AbsPathBuf),
|
||||||
#[default]
|
#[default]
|
||||||
Workspace,
|
Workspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct CargoOptions {
|
pub(crate) struct CargoOptions {
|
||||||
pub target_triples: Vec<String>,
|
pub(crate) target_triples: Vec<String>,
|
||||||
pub all_targets: bool,
|
pub(crate) all_targets: bool,
|
||||||
pub no_default_features: bool,
|
pub(crate) no_default_features: bool,
|
||||||
pub all_features: bool,
|
pub(crate) all_features: bool,
|
||||||
pub features: Vec<String>,
|
pub(crate) features: Vec<String>,
|
||||||
pub extra_args: Vec<String>,
|
pub(crate) extra_args: Vec<String>,
|
||||||
pub extra_env: FxHashMap<String, String>,
|
pub(crate) extra_env: FxHashMap<String, String>,
|
||||||
pub target_dir: Option<Utf8PathBuf>,
|
pub(crate) target_dir: Option<Utf8PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
for target in &self.target_triples {
|
||||||
cmd.args(["--target", target.as_str()]);
|
cmd.args(["--target", target.as_str()]);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +68,7 @@ impl CargoOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum FlycheckConfig {
|
pub(crate) enum FlycheckConfig {
|
||||||
CargoCommand {
|
CargoCommand {
|
||||||
command: String,
|
command: String,
|
||||||
options: CargoOptions,
|
options: CargoOptions,
|
||||||
|
@ -110,7 +99,7 @@ impl fmt::Display for FlycheckConfig {
|
||||||
/// diagnostics based on the output.
|
/// diagnostics based on the output.
|
||||||
/// The spawned thread is shut down when this struct is dropped.
|
/// The spawned thread is shut down when this struct is dropped.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FlycheckHandle {
|
pub(crate) struct FlycheckHandle {
|
||||||
// XXX: drop order is significant
|
// XXX: drop order is significant
|
||||||
sender: Sender<StateChange>,
|
sender: Sender<StateChange>,
|
||||||
_thread: stdx::thread::JoinHandle,
|
_thread: stdx::thread::JoinHandle,
|
||||||
|
@ -118,9 +107,9 @@ pub struct FlycheckHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlycheckHandle {
|
impl FlycheckHandle {
|
||||||
pub fn spawn(
|
pub(crate) fn spawn(
|
||||||
id: usize,
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
sysroot_root: Option<AbsPathBuf>,
|
sysroot_root: Option<AbsPathBuf>,
|
||||||
workspace_root: AbsPathBuf,
|
workspace_root: AbsPathBuf,
|
||||||
|
@ -137,28 +126,28 @@ impl FlycheckHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule a re-start of the cargo check worker to do a workspace wide check.
|
/// Schedule a re-start of the cargo check worker to do a workspace wide check.
|
||||||
pub fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
|
pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
|
||||||
self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap();
|
self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule a re-start of the cargo check worker to do a package wide check.
|
/// Schedule a re-start of the cargo check worker to do a package wide check.
|
||||||
pub fn restart_for_package(&self, package: String) {
|
pub(crate) fn restart_for_package(&self, package: String) {
|
||||||
self.sender
|
self.sender
|
||||||
.send(StateChange::Restart { package: Some(package), saved_file: None })
|
.send(StateChange::Restart { package: Some(package), saved_file: None })
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop this cargo check worker.
|
/// Stop this cargo check worker.
|
||||||
pub fn cancel(&self) {
|
pub(crate) fn cancel(&self) {
|
||||||
self.sender.send(StateChange::Cancel).unwrap();
|
self.sender.send(StateChange::Cancel).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> usize {
|
pub(crate) fn id(&self) -> usize {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Message {
|
pub(crate) enum FlycheckMessage {
|
||||||
/// Request adding a diagnostic with fixes included to a file
|
/// Request adding a diagnostic with fixes included to a file
|
||||||
AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic },
|
AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic },
|
||||||
|
|
||||||
|
@ -173,19 +162,19 @@ pub enum Message {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Message {
|
impl fmt::Debug for FlycheckMessage {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Message::AddDiagnostic { id, workspace_root, diagnostic } => f
|
FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f
|
||||||
.debug_struct("AddDiagnostic")
|
.debug_struct("AddDiagnostic")
|
||||||
.field("id", id)
|
.field("id", id)
|
||||||
.field("workspace_root", workspace_root)
|
.field("workspace_root", workspace_root)
|
||||||
.field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
|
.field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
|
||||||
.finish(),
|
.finish(),
|
||||||
Message::ClearDiagnostics { id } => {
|
FlycheckMessage::ClearDiagnostics { id } => {
|
||||||
f.debug_struct("ClearDiagnostics").field("id", id).finish()
|
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()
|
f.debug_struct("Progress").field("id", id).field("progress", progress).finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +182,7 @@ impl fmt::Debug for Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Progress {
|
pub(crate) enum Progress {
|
||||||
DidStart,
|
DidStart,
|
||||||
DidCheckCrate(String),
|
DidCheckCrate(String),
|
||||||
DidFinish(io::Result<()>),
|
DidFinish(io::Result<()>),
|
||||||
|
@ -210,7 +199,7 @@ enum StateChange {
|
||||||
struct FlycheckActor {
|
struct FlycheckActor {
|
||||||
/// The workspace id of this flycheck instance.
|
/// The workspace id of this flycheck instance.
|
||||||
id: usize,
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
manifest_path: Option<AbsPathBuf>,
|
manifest_path: Option<AbsPathBuf>,
|
||||||
/// Either the workspace root of the workspace we are flychecking,
|
/// Either the workspace root of the workspace we are flychecking,
|
||||||
|
@ -241,12 +230,12 @@ enum FlycheckStatus {
|
||||||
Finished,
|
Finished,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
|
pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
|
||||||
|
|
||||||
impl FlycheckActor {
|
impl FlycheckActor {
|
||||||
fn new(
|
fn new(
|
||||||
id: usize,
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(FlycheckMessage) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
sysroot_root: Option<AbsPathBuf>,
|
sysroot_root: Option<AbsPathBuf>,
|
||||||
workspace_root: AbsPathBuf,
|
workspace_root: AbsPathBuf,
|
||||||
|
@ -267,7 +256,7 @@ impl FlycheckActor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_progress(&self, progress: Progress) {
|
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> {
|
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
|
||||||
|
@ -340,7 +329,7 @@ impl FlycheckActor {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if self.status == FlycheckStatus::Started {
|
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.report_progress(Progress::DidFinish(res));
|
||||||
self.status = FlycheckStatus::Finished;
|
self.status = FlycheckStatus::Finished;
|
||||||
|
@ -362,9 +351,9 @@ impl FlycheckActor {
|
||||||
"diagnostic received"
|
"diagnostic received"
|
||||||
);
|
);
|
||||||
if self.status == FlycheckStatus::Started {
|
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,
|
id: self.id,
|
||||||
workspace_root: self.root.clone(),
|
workspace_root: self.root.clone(),
|
||||||
diagnostic: msg,
|
diagnostic: msg,
|
||||||
|
@ -489,7 +478,7 @@ impl FlycheckActor {
|
||||||
Some(cmd)
|
Some(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&self, check_task: Message) {
|
fn send(&self, check_task: FlycheckMessage) {
|
||||||
(self.sender)(check_task);
|
(self.sender)(check_task);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,6 @@
|
||||||
use std::{ops::Not as _, time::Instant};
|
use std::{ops::Not as _, time::Instant};
|
||||||
|
|
||||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||||
use flycheck::{project_json, FlycheckHandle};
|
|
||||||
use hir::ChangeWithProcMacros;
|
use hir::ChangeWithProcMacros;
|
||||||
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
|
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
|
||||||
use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase, SourceRootDatabase};
|
use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase, SourceRootDatabase};
|
||||||
|
@ -28,6 +27,8 @@ use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs, VfsPath};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, ConfigChange, ConfigErrors, RatomlFileKind},
|
config::{Config, ConfigChange, ConfigErrors, RatomlFileKind},
|
||||||
diagnostics::{CheckFixes, DiagnosticCollection},
|
diagnostics::{CheckFixes, DiagnosticCollection},
|
||||||
|
discover,
|
||||||
|
flycheck::{FlycheckHandle, FlycheckMessage},
|
||||||
line_index::{LineEndings, LineIndex},
|
line_index::{LineEndings, LineIndex},
|
||||||
lsp::{from_proto, to_proto::url_from_abs_path},
|
lsp::{from_proto, to_proto::url_from_abs_path},
|
||||||
lsp_ext,
|
lsp_ext,
|
||||||
|
@ -37,6 +38,7 @@ use crate::{
|
||||||
reload,
|
reload,
|
||||||
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
|
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
|
||||||
task_pool::{TaskPool, TaskQueue},
|
task_pool::{TaskPool, TaskQueue},
|
||||||
|
test_runner::{CargoTestHandle, CargoTestMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct FetchWorkspaceRequest {
|
pub(crate) struct FetchWorkspaceRequest {
|
||||||
|
@ -88,20 +90,20 @@ pub(crate) struct GlobalState {
|
||||||
|
|
||||||
// Flycheck
|
// Flycheck
|
||||||
pub(crate) flycheck: Arc<[FlycheckHandle]>,
|
pub(crate) flycheck: Arc<[FlycheckHandle]>,
|
||||||
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
pub(crate) flycheck_sender: Sender<FlycheckMessage>,
|
||||||
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
|
pub(crate) flycheck_receiver: Receiver<FlycheckMessage>,
|
||||||
pub(crate) last_flycheck_error: Option<String>,
|
pub(crate) last_flycheck_error: Option<String>,
|
||||||
|
|
||||||
// Test explorer
|
// Test explorer
|
||||||
pub(crate) test_run_session: Option<Vec<flycheck::CargoTestHandle>>,
|
pub(crate) test_run_session: Option<Vec<CargoTestHandle>>,
|
||||||
pub(crate) test_run_sender: Sender<flycheck::CargoTestMessage>,
|
pub(crate) test_run_sender: Sender<CargoTestMessage>,
|
||||||
pub(crate) test_run_receiver: Receiver<flycheck::CargoTestMessage>,
|
pub(crate) test_run_receiver: Receiver<CargoTestMessage>,
|
||||||
pub(crate) test_run_remaining_jobs: usize,
|
pub(crate) test_run_remaining_jobs: usize,
|
||||||
|
|
||||||
// Project loading
|
// Project loading
|
||||||
pub(crate) discover_handle: Option<project_json::DiscoverHandle>,
|
pub(crate) discover_handle: Option<discover::DiscoverHandle>,
|
||||||
pub(crate) discover_sender: Sender<project_json::DiscoverProjectMessage>,
|
pub(crate) discover_sender: Sender<discover::DiscoverProjectMessage>,
|
||||||
pub(crate) discover_receiver: Receiver<project_json::DiscoverProjectMessage>,
|
pub(crate) discover_receiver: Receiver<discover::DiscoverProjectMessage>,
|
||||||
|
|
||||||
// VFS
|
// VFS
|
||||||
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>>,
|
||||||
|
|
|
@ -51,6 +51,7 @@ use crate::{
|
||||||
FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
|
FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
|
||||||
},
|
},
|
||||||
target_spec::{CargoTargetSpec, TargetSpec},
|
target_spec::{CargoTargetSpec, TargetSpec},
|
||||||
|
test_runner::{CargoTestHandle, TestTarget},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
|
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 {
|
if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind {
|
||||||
let test_target = if let Some(namespace_root) = namespace_root {
|
let test_target = if let Some(namespace_root) = namespace_root {
|
||||||
if let Some(package_name) = find_package_name(namespace_root, cargo) {
|
if let Some(package_name) = find_package_name(namespace_root, cargo) {
|
||||||
flycheck::TestTarget::Package(package_name)
|
TestTarget::Package(package_name)
|
||||||
} else {
|
} else {
|
||||||
flycheck::TestTarget::Workspace
|
TestTarget::Workspace
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flycheck::TestTarget::Workspace
|
TestTarget::Workspace
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle = flycheck::CargoTestHandle::new(
|
let handle = CargoTestHandle::new(
|
||||||
test_path,
|
test_path,
|
||||||
state.config.cargo_test_options(),
|
state.config.cargo_test_options(),
|
||||||
cargo.workspace_root(),
|
cargo.workspace_root(),
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
|
|
||||||
mod capabilities;
|
mod capabilities;
|
||||||
|
mod command;
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
mod diff;
|
mod diff;
|
||||||
|
mod discover;
|
||||||
mod dispatch;
|
mod dispatch;
|
||||||
|
mod flycheck;
|
||||||
mod hack_recover_crate_name;
|
mod hack_recover_crate_name;
|
||||||
mod line_index;
|
mod line_index;
|
||||||
mod main_loop;
|
mod main_loop;
|
||||||
|
@ -23,6 +26,7 @@ mod op_queue;
|
||||||
mod reload;
|
mod reload;
|
||||||
mod target_spec;
|
mod target_spec;
|
||||||
mod task_pool;
|
mod task_pool;
|
||||||
|
mod test_runner;
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
mod handlers {
|
mod handlers {
|
||||||
|
|
|
@ -9,7 +9,6 @@ use std::{
|
||||||
|
|
||||||
use always_assert::always;
|
use always_assert::always;
|
||||||
use crossbeam_channel::{select, Receiver};
|
use crossbeam_channel::{select, Receiver};
|
||||||
use flycheck::project_json;
|
|
||||||
use ide_db::base_db::{SourceDatabase, SourceRootDatabase, VfsPath};
|
use ide_db::base_db::{SourceDatabase, SourceRootDatabase, VfsPath};
|
||||||
use lsp_server::{Connection, Notification, Request};
|
use lsp_server::{Connection, Notification, Request};
|
||||||
use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
|
use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
|
||||||
|
@ -20,7 +19,9 @@ use vfs::{loader::LoadingProgress, AbsPathBuf, FileId};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
diagnostics::{fetch_native_diagnostics, DiagnosticsGeneration, NativeDiagnosticsFetchKind},
|
diagnostics::{fetch_native_diagnostics, DiagnosticsGeneration, NativeDiagnosticsFetchKind},
|
||||||
|
discover::{DiscoverArgument, DiscoverCommand, DiscoverProjectMessage},
|
||||||
dispatch::{NotificationDispatcher, RequestDispatcher},
|
dispatch::{NotificationDispatcher, RequestDispatcher},
|
||||||
|
flycheck::{self, FlycheckMessage},
|
||||||
global_state::{file_id_to_url, url_to_file_id, FetchWorkspaceRequest, GlobalState},
|
global_state::{file_id_to_url, url_to_file_id, FetchWorkspaceRequest, GlobalState},
|
||||||
hack_recover_crate_name,
|
hack_recover_crate_name,
|
||||||
lsp::{
|
lsp::{
|
||||||
|
@ -29,6 +30,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
lsp_ext,
|
lsp_ext,
|
||||||
reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
|
reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
|
||||||
|
test_runner::{CargoTestMessage, TestState},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> {
|
pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> {
|
||||||
|
@ -61,9 +63,9 @@ enum Event {
|
||||||
Task(Task),
|
Task(Task),
|
||||||
QueuedTask(QueuedTask),
|
QueuedTask(QueuedTask),
|
||||||
Vfs(vfs::loader::Message),
|
Vfs(vfs::loader::Message),
|
||||||
Flycheck(flycheck::Message),
|
Flycheck(FlycheckMessage),
|
||||||
TestResult(flycheck::CargoTestMessage),
|
TestResult(CargoTestMessage),
|
||||||
DiscoverProject(project_json::DiscoverProjectMessage),
|
DiscoverProject(DiscoverProjectMessage),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Event {
|
impl fmt::Display for Event {
|
||||||
|
@ -689,8 +691,7 @@ impl GlobalState {
|
||||||
// `self.report_progress` is called later
|
// `self.report_progress` is called later
|
||||||
let title = &cfg.progress_label.clone();
|
let title = &cfg.progress_label.clone();
|
||||||
let command = cfg.command.clone();
|
let command = cfg.command.clone();
|
||||||
let discover =
|
let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
|
||||||
project_json::Discover::new(self.discover_sender.clone(), command);
|
|
||||||
|
|
||||||
self.report_progress(title, Progress::Begin, None, None, None);
|
self.report_progress(title, Progress::Begin, None, None, None);
|
||||||
self.discover_workspace_queue
|
self.discover_workspace_queue
|
||||||
|
@ -698,12 +699,8 @@ impl GlobalState {
|
||||||
let _ = self.discover_workspace_queue.should_start_op();
|
let _ = self.discover_workspace_queue.should_start_op();
|
||||||
|
|
||||||
let arg = match arg {
|
let arg = match arg {
|
||||||
DiscoverProjectParam::Buildfile(it) => {
|
DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
|
||||||
project_json::DiscoverArgument::Buildfile(it)
|
DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
|
||||||
}
|
|
||||||
DiscoverProjectParam::Path(it) => {
|
|
||||||
project_json::DiscoverArgument::Path(it)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle = discover.spawn(arg).unwrap();
|
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
|
let title = self
|
||||||
.config
|
.config
|
||||||
.discover_workspace_config()
|
.discover_workspace_config()
|
||||||
.map(|cfg| cfg.progress_label.clone())
|
.map(|cfg| cfg.progress_label.clone())
|
||||||
.expect("No title could be found; this is a bug");
|
.expect("No title could be found; this is a bug");
|
||||||
match message {
|
match message {
|
||||||
project_json::DiscoverProjectMessage::Finished { project, buildfile } => {
|
DiscoverProjectMessage::Finished { project, buildfile } => {
|
||||||
self.report_progress(&title, Progress::End, None, None, None);
|
self.report_progress(&title, Progress::End, None, None, None);
|
||||||
self.discover_workspace_queue.op_completed(());
|
self.discover_workspace_queue.op_completed(());
|
||||||
|
|
||||||
|
@ -867,10 +864,10 @@ impl GlobalState {
|
||||||
config.add_linked_projects(project, buildfile);
|
config.add_linked_projects(project, buildfile);
|
||||||
self.update_configuration(config);
|
self.update_configuration(config);
|
||||||
}
|
}
|
||||||
project_json::DiscoverProjectMessage::Progress { message } => {
|
DiscoverProjectMessage::Progress { message } => {
|
||||||
self.report_progress(&title, Progress::Report, Some(message), None, None)
|
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}");
|
let message = format!("Project discovery failed: {error}");
|
||||||
self.discover_workspace_queue.op_completed(());
|
self.discover_workspace_queue.op_completed(());
|
||||||
self.show_and_log_error(message.clone(), source);
|
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 {
|
match message {
|
||||||
flycheck::CargoTestMessage::Test { name, state } => {
|
CargoTestMessage::Test { name, state } => {
|
||||||
let state = match state {
|
let state = match state {
|
||||||
flycheck::TestState::Started => lsp_ext::TestState::Started,
|
TestState::Started => lsp_ext::TestState::Started,
|
||||||
flycheck::TestState::Ignored => lsp_ext::TestState::Skipped,
|
TestState::Ignored => lsp_ext::TestState::Skipped,
|
||||||
flycheck::TestState::Ok => lsp_ext::TestState::Passed,
|
TestState::Ok => lsp_ext::TestState::Passed,
|
||||||
flycheck::TestState::Failed { stdout } => {
|
TestState::Failed { stdout } => lsp_ext::TestState::Failed { message: stdout },
|
||||||
lsp_ext::TestState::Failed { message: stdout }
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let Some(test_id) = hack_recover_crate_name::lookup_name(name) else {
|
let Some(test_id) = hack_recover_crate_name::lookup_name(name) else {
|
||||||
return;
|
return;
|
||||||
|
@ -897,23 +892,23 @@ impl GlobalState {
|
||||||
lsp_ext::ChangeTestStateParams { test_id, state },
|
lsp_ext::ChangeTestStateParams { test_id, state },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
flycheck::CargoTestMessage::Suite => (),
|
CargoTestMessage::Suite => (),
|
||||||
flycheck::CargoTestMessage::Finished => {
|
CargoTestMessage::Finished => {
|
||||||
self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1);
|
self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1);
|
||||||
if self.test_run_remaining_jobs == 0 {
|
if self.test_run_remaining_jobs == 0 {
|
||||||
self.send_notification::<lsp_ext::EndRunTest>(());
|
self.send_notification::<lsp_ext::EndRunTest>(());
|
||||||
self.test_run_session = None;
|
self.test_run_session = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flycheck::CargoTestMessage::Custom { text } => {
|
CargoTestMessage::Custom { text } => {
|
||||||
self.send_notification::<lsp_ext::AppendOutputToRunTest>(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 {
|
match message {
|
||||||
flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
|
FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => {
|
||||||
let snap = self.snapshot();
|
let snap = self.snapshot();
|
||||||
let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
|
let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
|
||||||
&self.config.diagnostics_map(),
|
&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 {
|
let (state, message) = match progress {
|
||||||
flycheck::Progress::DidStart => (Progress::Begin, None),
|
flycheck::Progress::DidStart => (Progress::Begin, None),
|
||||||
flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
|
flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
// FIXME: This is a mess that needs some untangling work
|
// FIXME: This is a mess that needs some untangling work
|
||||||
use std::{iter, mem};
|
use std::{iter, mem};
|
||||||
|
|
||||||
use flycheck::{FlycheckConfig, FlycheckHandle};
|
|
||||||
use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder};
|
use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
|
base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
|
||||||
|
@ -32,6 +31,7 @@ use vfs::{AbsPath, AbsPathBuf, ChangeKind};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, FilesWatcher, LinkedProject},
|
config::{Config, FilesWatcher, LinkedProject},
|
||||||
|
flycheck::{FlycheckConfig, FlycheckHandle},
|
||||||
global_state::{FetchWorkspaceRequest, GlobalState},
|
global_state::{FetchWorkspaceRequest, GlobalState},
|
||||||
lsp_ext,
|
lsp_ext,
|
||||||
main_loop::{DiscoverProjectParam, Task},
|
main_loop::{DiscoverProjectParam, Task},
|
||||||
|
@ -749,12 +749,14 @@ impl GlobalState {
|
||||||
let config = self.config.flycheck();
|
let config = self.config.flycheck();
|
||||||
let sender = self.flycheck_sender.clone();
|
let sender = self.flycheck_sender.clone();
|
||||||
let invocation_strategy = match config {
|
let invocation_strategy = match config {
|
||||||
FlycheckConfig::CargoCommand { .. } => flycheck::InvocationStrategy::PerWorkspace,
|
FlycheckConfig::CargoCommand { .. } => {
|
||||||
|
crate::flycheck::InvocationStrategy::PerWorkspace
|
||||||
|
}
|
||||||
FlycheckConfig::CustomCommand { invocation_strategy, .. } => invocation_strategy,
|
FlycheckConfig::CustomCommand { invocation_strategy, .. } => invocation_strategy,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.flycheck = match invocation_strategy {
|
self.flycheck = match invocation_strategy {
|
||||||
flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn(
|
crate::flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn(
|
||||||
0,
|
0,
|
||||||
Box::new(move |msg| sender.send(msg).unwrap()),
|
Box::new(move |msg| sender.send(msg).unwrap()),
|
||||||
config,
|
config,
|
||||||
|
@ -762,7 +764,7 @@ impl GlobalState {
|
||||||
self.config.root_path().clone(),
|
self.config.root_path().clone(),
|
||||||
None,
|
None,
|
||||||
)],
|
)],
|
||||||
flycheck::InvocationStrategy::PerWorkspace => {
|
crate::flycheck::InvocationStrategy::PerWorkspace => {
|
||||||
self.workspaces
|
self.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|
|
@ -10,12 +10,12 @@ use toolchain::Tool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command::{CommandHandle, ParseFromLine},
|
command::{CommandHandle, ParseFromLine},
|
||||||
CargoOptions,
|
flycheck::CargoOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(tag = "event", rename_all = "camelCase")]
|
#[serde(tag = "event", rename_all = "camelCase")]
|
||||||
pub enum TestState {
|
pub(crate) enum TestState {
|
||||||
Started,
|
Started,
|
||||||
Ok,
|
Ok,
|
||||||
Ignored,
|
Ignored,
|
||||||
|
@ -24,7 +24,7 @@ pub enum TestState {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
pub enum CargoTestMessage {
|
pub(crate) enum CargoTestMessage {
|
||||||
Test {
|
Test {
|
||||||
name: String,
|
name: String,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
@ -54,7 +54,7 @@ impl ParseFromLine for CargoTestMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CargoTestHandle {
|
pub(crate) struct CargoTestHandle {
|
||||||
_handle: CommandHandle<CargoTestMessage>,
|
_handle: CommandHandle<CargoTestMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +64,13 @@ pub struct CargoTestHandle {
|
||||||
// cargo test --package my-package --no-fail-fast -- module::func -Z unstable-options --format=json
|
// cargo test --package my-package --no-fail-fast -- module::func -Z unstable-options --format=json
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TestTarget {
|
pub(crate) enum TestTarget {
|
||||||
Workspace,
|
Workspace,
|
||||||
Package(String),
|
Package(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CargoTestHandle {
|
impl CargoTestHandle {
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
path: Option<&str>,
|
path: Option<&str>,
|
||||||
options: CargoOptions,
|
options: CargoOptions,
|
||||||
root: &AbsPath,
|
root: &AbsPath,
|
Loading…
Reference in a new issue