Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21424 from cormacrelf/support-more-runnable-kinds
Support more runnable kinds in project JSON
Chayim Refael Friedman 8 weeks ago
parent 633f271 · parent 7657739 · commit 9aa5e45
-rw-r--r--crates/project-model/src/project_json.rs21
-rw-r--r--crates/rust-analyzer/src/target_spec.rs81
2 files changed, 63 insertions, 39 deletions
diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs
index 682f5462f9..4ea136afbb 100644
--- a/crates/project-model/src/project_json.rs
+++ b/crates/project-model/src/project_json.rs
@@ -365,6 +365,21 @@ pub enum RunnableKind {
/// May include {test_id} which will get the test clicked on by the user.
TestOne,
+ /// Run tests matching a pattern (in RA, usually a path::to::module::of::tests)
+ /// May include {label} which will get the label from the `build` section of a crate.
+ /// May include {test_pattern} which will get the test module clicked on by the user.
+ TestMod,
+
+ /// Run a single doctest
+ /// May include {label} which will get the label from the `build` section of a crate.
+ /// May include {test_id} which will get the doctest clicked on by the user.
+ DocTestOne,
+
+ /// Run a single benchmark
+ /// May include {label} which will get the label from the `build` section of a crate.
+ /// May include {bench_id} which will get the benchmark clicked on by the user.
+ BenchOne,
+
/// Template for checking a target, emitting rustc JSON diagnostics.
/// May include {label} which will get the label from the `build` section of a crate.
Flycheck,
@@ -479,6 +494,9 @@ enum RunnableKindData {
Check,
Run,
TestOne,
+ TestMod,
+ DocTestOne,
+ BenchOne,
/// For forwards-compatibility, i.e. old rust-analyzer binary with newer workspace discovery tools
#[allow(unused)]
@@ -551,6 +569,9 @@ impl From<RunnableKindData> for RunnableKind {
RunnableKindData::Check => RunnableKind::Check,
RunnableKindData::Run => RunnableKind::Run,
RunnableKindData::TestOne => RunnableKind::TestOne,
+ RunnableKindData::TestMod => RunnableKind::TestMod,
+ RunnableKindData::DocTestOne => RunnableKind::DocTestOne,
+ RunnableKindData::BenchOne => RunnableKind::BenchOne,
RunnableKindData::Flycheck => RunnableKind::Flycheck,
RunnableKindData::Unknown => RunnableKind::Unknown,
}
diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs
index 811c0a0c11..8be061cacf 100644
--- a/crates/rust-analyzer/src/target_spec.rs
+++ b/crates/rust-analyzer/src/target_spec.rs
@@ -6,7 +6,7 @@ use cargo_metadata::PackageId;
use cfg::{CfgAtom, CfgExpr};
use hir::sym;
use ide::{Cancellable, Crate, FileId, RunnableKind, TestId};
-use project_model::project_json::Runnable;
+use project_model::project_json::{self, Runnable};
use project_model::{CargoFeatures, ManifestPath, TargetKind};
use rustc_hash::FxHashSet;
use triomphe::Arc;
@@ -72,48 +72,51 @@ pub(crate) struct ProjectJsonTargetSpec {
}
impl ProjectJsonTargetSpec {
+ fn find_replace_runnable(
+ &self,
+ kind: project_json::RunnableKind,
+ replacer: &dyn Fn(&Self, &str) -> String,
+ ) -> Option<Runnable> {
+ for runnable in &self.shell_runnables {
+ if runnable.kind == kind {
+ let mut runnable = runnable.clone();
+
+ let replaced_args: Vec<_> =
+ runnable.args.iter().map(|arg| replacer(self, arg)).collect();
+ runnable.args = replaced_args;
+
+ return Some(runnable);
+ }
+ }
+
+ None
+ }
+
pub(crate) fn runnable_args(&self, kind: &RunnableKind) -> Option<Runnable> {
match kind {
- RunnableKind::Bin => {
- for runnable in &self.shell_runnables {
- if matches!(runnable.kind, project_model::project_json::RunnableKind::Run) {
- let mut runnable = runnable.clone();
-
- let replaced_args: Vec<_> = runnable
- .args
- .iter()
- .map(|arg| arg.replace("{label}", &self.label))
- .collect();
- runnable.args = replaced_args;
-
- return Some(runnable);
- }
- }
-
- None
- }
+ RunnableKind::Bin => self
+ .find_replace_runnable(project_json::RunnableKind::Run, &|this, arg| {
+ arg.replace("{label}", &this.label)
+ }),
RunnableKind::Test { test_id, .. } => {
- for runnable in &self.shell_runnables {
- if matches!(runnable.kind, project_model::project_json::RunnableKind::TestOne) {
- let mut runnable = runnable.clone();
-
- let replaced_args: Vec<_> = runnable
- .args
- .iter()
- .map(|arg| arg.replace("{test_id}", &test_id.to_string()))
- .map(|arg| arg.replace("{label}", &self.label))
- .collect();
- runnable.args = replaced_args;
-
- return Some(runnable);
- }
- }
-
- None
+ self.find_replace_runnable(project_json::RunnableKind::Run, &|this, arg| {
+ arg.replace("{label}", &this.label).replace("{test_id}", &test_id.to_string())
+ })
+ }
+ RunnableKind::TestMod { path } => self
+ .find_replace_runnable(project_json::RunnableKind::TestMod, &|this, arg| {
+ arg.replace("{label}", &this.label).replace("{test_pattern}", path)
+ }),
+ RunnableKind::Bench { test_id } => {
+ self.find_replace_runnable(project_json::RunnableKind::BenchOne, &|this, arg| {
+ arg.replace("{label}", &this.label).replace("{bench_id}", &test_id.to_string())
+ })
+ }
+ RunnableKind::DocTest { test_id } => {
+ self.find_replace_runnable(project_json::RunnableKind::DocTestOne, &|this, arg| {
+ arg.replace("{label}", &this.label).replace("{test_id}", &test_id.to_string())
+ })
}
- RunnableKind::TestMod { .. } => None,
- RunnableKind::Bench { .. } => None,
- RunnableKind::DocTest { .. } => None,
}
}
}