Skip to content

Commit 11c7eac

Browse files
davidbarskyWilfred
authored andcommitted
Extend TargetSpec functionality to rust-project.json
1 parent a2e2741 commit 11c7eac

File tree

15 files changed

+529
-227
lines changed

15 files changed

+529
-227
lines changed

crates/ide/src/runnables.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,13 @@ enum RunnableTestKind {
6565

6666
impl Runnable {
6767
// test package::module::testname
68-
pub fn label(&self, target: Option<String>) -> String {
68+
pub fn label(&self, target: String) -> String {
6969
match &self.kind {
7070
RunnableKind::Test { test_id, .. } => format!("test {test_id}"),
7171
RunnableKind::TestMod { path } => format!("test-mod {path}"),
7272
RunnableKind::Bench { test_id } => format!("bench {test_id}"),
7373
RunnableKind::DocTest { test_id, .. } => format!("doctest {test_id}"),
74-
RunnableKind::Bin => {
75-
target.map_or_else(|| "run binary".to_owned(), |t| format!("run {t}"))
76-
}
74+
RunnableKind::Bin => target,
7775
}
7876
}
7977

crates/project-model/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod build_scripts;
2121
mod cargo_workspace;
2222
mod cfg_flag;
2323
mod manifest_path;
24-
mod project_json;
24+
pub mod project_json;
2525
mod rustc_cfg;
2626
mod sysroot;
2727
pub mod target_data_layout;

crates/project-model/src/project_json.rs

Lines changed: 106 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use rustc_hash::FxHashMap;
5656
use serde::{de, Deserialize};
5757
use std::path::PathBuf;
5858

59-
use crate::cfg_flag::CfgFlag;
59+
use crate::{cfg_flag::CfgFlag, TargetKind};
6060

6161
/// Roots and crates that compose this Rust project.
6262
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -73,20 +73,37 @@ pub struct ProjectJson {
7373
/// useful in creating the crate graph.
7474
#[derive(Clone, Debug, Eq, PartialEq)]
7575
pub struct Crate {
76-
pub(crate) display_name: Option<CrateDisplayName>,
77-
pub(crate) root_module: AbsPathBuf,
78-
pub(crate) edition: Edition,
79-
pub(crate) version: Option<String>,
80-
pub(crate) deps: Vec<Dependency>,
81-
pub(crate) cfg: Vec<CfgFlag>,
82-
pub(crate) target: Option<String>,
83-
pub(crate) env: FxHashMap<String, String>,
84-
pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
85-
pub(crate) is_workspace_member: bool,
86-
pub(crate) include: Vec<AbsPathBuf>,
87-
pub(crate) exclude: Vec<AbsPathBuf>,
88-
pub(crate) is_proc_macro: bool,
89-
pub(crate) repository: Option<String>,
76+
pub display_name: Option<CrateDisplayName>,
77+
pub root_module: AbsPathBuf,
78+
pub edition: Edition,
79+
pub version: Option<String>,
80+
pub deps: Vec<Dependency>,
81+
pub cfg: Vec<CfgFlag>,
82+
pub target: Option<String>,
83+
pub env: FxHashMap<String, String>,
84+
pub proc_macro_dylib_path: Option<AbsPathBuf>,
85+
pub is_workspace_member: bool,
86+
pub include: Vec<AbsPathBuf>,
87+
pub exclude: Vec<AbsPathBuf>,
88+
pub is_proc_macro: bool,
89+
pub repository: Option<String>,
90+
pub target_spec: Option<TargetSpec>,
91+
}
92+
93+
#[derive(Clone, Debug, Eq, PartialEq)]
94+
pub struct TargetSpec {
95+
pub manifest_file: AbsPathBuf,
96+
pub target_label: String,
97+
pub target_kind: TargetKind,
98+
pub runnables: Runnables,
99+
pub flycheck_command: Vec<String>,
100+
}
101+
102+
#[derive(Clone, Debug, Eq, PartialEq)]
103+
pub struct Runnables {
104+
pub check: Vec<String>,
105+
pub run: Vec<String>,
106+
pub test: Vec<String>,
90107
}
91108

92109
impl ProjectJson {
@@ -121,6 +138,20 @@ impl ProjectJson {
121138
None => (vec![root_module.parent().unwrap().to_path_buf()], Vec::new()),
122139
};
123140

141+
let target_spec = match crate_data.target_spec {
142+
Some(spec) => {
143+
let spec = TargetSpec {
144+
manifest_file: absolutize_on_base(spec.manifest_file),
145+
target_label: spec.target_label,
146+
target_kind: spec.target_kind.into(),
147+
runnables: spec.runnables.into(),
148+
flycheck_command: spec.flycheck_command,
149+
};
150+
Some(spec)
151+
}
152+
None => None,
153+
};
154+
124155
Crate {
125156
display_name: crate_data
126157
.display_name
@@ -149,6 +180,7 @@ impl ProjectJson {
149180
exclude,
150181
is_proc_macro: crate_data.is_proc_macro,
151182
repository: crate_data.repository,
183+
target_spec,
152184
}
153185
})
154186
.collect(),
@@ -172,6 +204,14 @@ impl ProjectJson {
172204
pub fn path(&self) -> &AbsPath {
173205
&self.project_root
174206
}
207+
208+
pub fn crate_by_root(&self, root: &AbsPath) -> Option<Crate> {
209+
self.crates
210+
.iter()
211+
.filter(|krate| krate.is_workspace_member)
212+
.find(|krate| &krate.root_module == root)
213+
.cloned()
214+
}
175215
}
176216

177217
#[derive(Deserialize, Debug, Clone)]
@@ -201,6 +241,8 @@ struct CrateData {
201241
is_proc_macro: bool,
202242
#[serde(default)]
203243
repository: Option<String>,
244+
#[serde(default)]
245+
target_spec: Option<TargetSpecData>,
204246
}
205247

206248
#[derive(Deserialize, Debug, Clone)]
@@ -216,6 +258,55 @@ enum EditionData {
216258
Edition2024,
217259
}
218260

261+
#[derive(Deserialize, Debug, Clone)]
262+
pub struct TargetSpecData {
263+
manifest_file: PathBuf,
264+
target_label: String,
265+
target_kind: TargetKindData,
266+
runnables: RunnablesData,
267+
flycheck_command: Vec<String>,
268+
}
269+
270+
#[derive(Deserialize, Debug, Clone)]
271+
pub struct RunnablesData {
272+
check: Vec<String>,
273+
run: Vec<String>,
274+
test: Vec<String>,
275+
}
276+
277+
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
278+
#[serde(rename_all = "camelCase")]
279+
pub enum TargetKindData {
280+
Bin,
281+
/// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
282+
Lib,
283+
Example,
284+
Test,
285+
Bench,
286+
BuildScript,
287+
Other,
288+
}
289+
290+
impl From<TargetKindData> for TargetKind {
291+
fn from(value: TargetKindData) -> Self {
292+
match value {
293+
TargetKindData::Bin => TargetKind::Bin,
294+
TargetKindData::Lib => TargetKind::Lib { is_proc_macro: false },
295+
TargetKindData::Example => TargetKind::Example,
296+
TargetKindData::Test => TargetKind::Test,
297+
TargetKindData::Bench => TargetKind::Bench,
298+
TargetKindData::BuildScript => TargetKind::BuildScript,
299+
TargetKindData::Other => TargetKind::Other,
300+
}
301+
}
302+
}
303+
304+
impl From<RunnablesData> for Runnables {
305+
fn from(value: RunnablesData) -> Self {
306+
Runnables { check: value.check, run: value.run, test: value.test }
307+
}
308+
}
309+
219310
impl From<EditionData> for Edition {
220311
fn from(data: EditionData) -> Self {
221312
match data {

crates/rust-analyzer/src/global_state.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use parking_lot::{
1818
RwLockWriteGuard,
1919
};
2020
use proc_macro_api::ProcMacroServer;
21-
use project_model::{CargoWorkspace, ProjectWorkspace, Target, WorkspaceBuildScripts};
21+
use project_model::{CargoWorkspace, ProjectJson, ProjectWorkspace, Target, WorkspaceBuildScripts};
2222
use rustc_hash::{FxHashMap, FxHashSet};
2323
use triomphe::Arc;
2424
use vfs::{AnchoredPathBuf, ChangedFile, Vfs};
@@ -500,18 +500,20 @@ impl GlobalStateSnapshot {
500500
self.vfs_read().file_path(file_id).clone()
501501
}
502502

503-
pub(crate) fn cargo_target_for_crate_root(
503+
pub(crate) fn target_for_crate_root(
504504
&self,
505505
crate_id: CrateId,
506-
) -> Option<(&CargoWorkspace, Target)> {
506+
) -> Option<TargetForCrateRoot<'_>> {
507507
let file_id = self.analysis.crate_root(crate_id).ok()?;
508508
let path = self.vfs_read().file_path(file_id).clone();
509509
let path = path.as_path()?;
510510
self.workspaces.iter().find_map(|ws| match ws {
511511
ProjectWorkspace::Cargo { cargo, .. } => {
512-
cargo.target_by_root(path).map(|it| (cargo, it))
512+
cargo.target_by_root(path).map(|it| TargetForCrateRoot::Cargo(cargo, it))
513+
}
514+
ProjectWorkspace::Json { project, .. } => {
515+
project.crate_by_root(path).map(|it| TargetForCrateRoot::JsonProject(project, it))
513516
}
514-
ProjectWorkspace::Json { .. } => None,
515517
ProjectWorkspace::DetachedFiles { .. } => None,
516518
})
517519
}
@@ -521,6 +523,11 @@ impl GlobalStateSnapshot {
521523
}
522524
}
523525

526+
pub(crate) enum TargetForCrateRoot<'a> {
527+
Cargo(&'a CargoWorkspace, Target),
528+
JsonProject(&'a ProjectJson, project_model::project_json::Crate),
529+
}
530+
524531
pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
525532
let path = vfs.file_path(id);
526533
let path = path.as_path().unwrap();

0 commit comments

Comments
 (0)