Skip to content

Commit a6f58c9

Browse files
author
Paolo Tranquilli
committed
Rust: add option for proc macro server
1 parent 3dd7f23 commit a6f58c9

File tree

3 files changed

+92
-65
lines changed

3 files changed

+92
-65
lines changed

rust/extractor/src/config.rs

+81-55
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ use num_traits::Zero;
1313
use ra_ap_cfg::{CfgAtom, CfgDiff};
1414
use ra_ap_ide_db::FxHashMap;
1515
use ra_ap_intern::Symbol;
16+
use ra_ap_load_cargo::{LoadCargoConfig, ProcMacroServerChoice};
1617
use ra_ap_paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1718
use ra_ap_project_model::{CargoConfig, CargoFeatures, CfgOverrides, RustLibSource, Sysroot};
1819
use rust_extractor_macros::extractor_cli_config;
1920
use serde::{Deserialize, Serialize};
2021
use std::collections::HashSet;
2122
use std::fmt::Debug;
2223
use std::ops::Not;
23-
use std::path::PathBuf;
24+
use std::path::{Path, PathBuf};
2425

2526
#[derive(Debug, PartialEq, Eq, Default, Serialize, Deserialize, Clone, Copy, clap::ValueEnum)]
2627
#[serde(rename_all = "lowercase")]
@@ -64,6 +65,7 @@ pub struct Config {
6465
pub rustc_src: Option<PathBuf>,
6566
pub build_script_command: Vec<String>,
6667
pub extra_includes: Vec<PathBuf>,
68+
pub proc_macro_server: Option<PathBuf>,
6769
}
6870

6971
impl Config {
@@ -93,70 +95,87 @@ impl Config {
9395
figment.extract().context("loading configuration")
9496
}
9597

96-
pub fn to_cargo_config(&self, dir: &AbsPath) -> CargoConfig {
97-
let path_buf_to_abs_path_buf = |path: &PathBuf| {
98-
let Ok(path) = Utf8PathBuf::from_path_buf(path.clone()) else {
99-
panic!("non utf8 input: {}", path.display())
100-
};
101-
dir.join(path)
102-
};
103-
let sysroot_input = self.sysroot.as_ref().map(path_buf_to_abs_path_buf);
104-
let sysroot_src_input = self.sysroot_src.as_ref().map(path_buf_to_abs_path_buf);
105-
let rustc_src_input = self.rustc_src.as_ref().map(path_buf_to_abs_path_buf);
106-
107-
let sysroot = match (sysroot_input, sysroot_src_input) {
98+
fn sysroot(&self, dir: &AbsPath) -> Sysroot {
99+
let sysroot_input = self.sysroot.as_ref().map(|p| join_path_buf(dir, p));
100+
let sysroot_src_input = self.sysroot_src.as_ref().map(|p| join_path_buf(dir, p));
101+
match (sysroot_input, sysroot_src_input) {
108102
(None, None) => Sysroot::discover(dir, &self.cargo_extra_env),
109103
(Some(sysroot), None) => Sysroot::discover_sysroot_src_dir(sysroot),
110104
(None, Some(sysroot_src)) => {
111105
Sysroot::discover_with_src_override(dir, &self.cargo_extra_env, sysroot_src)
112106
}
113107
(Some(sysroot), Some(sysroot_src)) => Sysroot::new(Some(sysroot), Some(sysroot_src)),
114-
};
115-
CargoConfig {
116-
all_targets: self.cargo_all_targets,
117-
sysroot_src: sysroot.src_root().map(ToOwned::to_owned),
118-
rustc_source: rustc_src_input
119-
.or_else(|| sysroot.discover_rustc_src().map(AbsPathBuf::from))
120-
.map(RustLibSource::Path),
121-
sysroot: sysroot
122-
.root()
123-
.map(ToOwned::to_owned)
124-
.map(RustLibSource::Path),
108+
}
109+
}
125110

126-
extra_env: self.cargo_extra_env.clone(),
127-
extra_args: self.cargo_extra_args.clone(),
128-
extra_includes: self
129-
.extra_includes
130-
.iter()
131-
.map(path_buf_to_abs_path_buf)
132-
.collect(),
133-
target_dir: Utf8PathBuf::from_path_buf(
134-
self.cargo_target_dir
135-
.clone()
136-
.unwrap_or_else(|| self.scratch_dir.join("target")),
137-
)
138-
.ok(),
139-
features: if self.cargo_features.is_empty() {
140-
Default::default()
141-
} else if self.cargo_features.contains(&"*".to_string()) {
142-
CargoFeatures::All
143-
} else {
144-
CargoFeatures::Selected {
145-
features: self.cargo_features.clone(),
146-
no_default_features: false,
147-
}
111+
fn proc_macro_server_choice(&self, dir: &AbsPath) -> ProcMacroServerChoice {
112+
match &self.proc_macro_server {
113+
Some(path) => match path.to_str() {
114+
Some("none") => ProcMacroServerChoice::None,
115+
Some("sysroot") => ProcMacroServerChoice::Sysroot,
116+
_ => ProcMacroServerChoice::Explicit(join_path_buf(dir, path)),
148117
},
149-
target: self.cargo_target.clone(),
150-
cfg_overrides: to_cfg_overrides(&self.cargo_cfg_overrides),
151-
wrap_rustc_in_build_scripts: false,
152-
run_build_script_command: if self.build_script_command.is_empty() {
153-
None
154-
} else {
155-
Some(self.build_script_command.clone())
156-
},
157-
..Default::default()
118+
None => ProcMacroServerChoice::Sysroot,
158119
}
159120
}
121+
122+
pub fn to_cargo_config(&self, dir: &AbsPath) -> (CargoConfig, LoadCargoConfig) {
123+
let sysroot = self.sysroot(dir);
124+
(
125+
CargoConfig {
126+
all_targets: self.cargo_all_targets,
127+
sysroot_src: sysroot.src_root().map(ToOwned::to_owned),
128+
rustc_source: self
129+
.rustc_src
130+
.as_ref()
131+
.map(|p| join_path_buf(dir, p))
132+
.or_else(|| sysroot.discover_rustc_src().map(AbsPathBuf::from))
133+
.map(RustLibSource::Path),
134+
sysroot: sysroot
135+
.root()
136+
.map(ToOwned::to_owned)
137+
.map(RustLibSource::Path),
138+
139+
extra_env: self.cargo_extra_env.clone(),
140+
extra_args: self.cargo_extra_args.clone(),
141+
extra_includes: self
142+
.extra_includes
143+
.iter()
144+
.map(|p| join_path_buf(dir, p))
145+
.collect(),
146+
target_dir: Utf8PathBuf::from_path_buf(
147+
self.cargo_target_dir
148+
.clone()
149+
.unwrap_or_else(|| self.scratch_dir.join("target")),
150+
)
151+
.ok(),
152+
features: if self.cargo_features.is_empty() {
153+
Default::default()
154+
} else if self.cargo_features.contains(&"*".to_string()) {
155+
CargoFeatures::All
156+
} else {
157+
CargoFeatures::Selected {
158+
features: self.cargo_features.clone(),
159+
no_default_features: false,
160+
}
161+
},
162+
target: self.cargo_target.clone(),
163+
cfg_overrides: to_cfg_overrides(&self.cargo_cfg_overrides),
164+
wrap_rustc_in_build_scripts: false,
165+
run_build_script_command: if self.build_script_command.is_empty() {
166+
None
167+
} else {
168+
Some(self.build_script_command.clone())
169+
},
170+
..Default::default()
171+
},
172+
LoadCargoConfig {
173+
load_out_dirs_from_check: true,
174+
with_proc_macro_server: self.proc_macro_server_choice(dir),
175+
prefill_caches: false,
176+
},
177+
)
178+
}
160179
}
161180

162181
fn to_cfg_override(spec: &str) -> CfgAtom {
@@ -194,3 +213,10 @@ fn to_cfg_overrides(specs: &Vec<String>) -> CfgOverrides {
194213
..Default::default()
195214
}
196215
}
216+
217+
fn join_path_buf(lhs: &AbsPath, rhs: &Path) -> AbsPathBuf {
218+
let Ok(path) = Utf8PathBuf::from_path_buf(rhs.into()) else {
219+
panic!("non utf8 input: {}", rhs.display())
220+
};
221+
lhs.join(path)
222+
}

rust/extractor/src/main.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use log::{info, warn};
77
use ra_ap_hir::Semantics;
88
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
99
use ra_ap_ide_db::RootDatabase;
10+
use ra_ap_load_cargo::LoadCargoConfig;
1011
use ra_ap_paths::{AbsPathBuf, Utf8PathBuf};
1112
use ra_ap_project_model::{CargoConfig, ProjectManifest};
1213
use ra_ap_vfs::Vfs;
@@ -112,9 +113,10 @@ impl<'a> Extractor<'a> {
112113
&mut self,
113114
project: &ProjectManifest,
114115
config: &CargoConfig,
116+
load_config: &LoadCargoConfig,
115117
) -> Option<(RootDatabase, Vfs)> {
116118
let before = Instant::now();
117-
let ret = RustAnalyzer::load_workspace(project, config);
119+
let ret = RustAnalyzer::load_workspace(project, config, load_config);
118120
self.steps
119121
.push(ExtractionStep::load_manifest(before, project));
120122
ret
@@ -221,9 +223,12 @@ fn main() -> anyhow::Result<()> {
221223
}
222224
extractor.extract_without_semantics(file, "no manifest found");
223225
}
224-
let cargo_config = cfg.to_cargo_config(&cwd()?);
226+
let cwd = cwd()?;
227+
let (cargo_config, load_cargo_config) = cfg.to_cargo_config(&cwd);
225228
for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) {
226-
if let Some((ref db, ref vfs)) = extractor.load_manifest(manifest, &cargo_config) {
229+
if let Some((ref db, ref vfs)) =
230+
extractor.load_manifest(manifest, &cargo_config, &load_cargo_config)
231+
{
227232
let semantics = Semantics::new(db);
228233
for file in files {
229234
match extractor.load_source(file, &semantics, vfs) {

rust/extractor/src/rust_analyzer.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use log::{debug, error, info, warn};
33
use ra_ap_base_db::SourceDatabase;
44
use ra_ap_hir::Semantics;
55
use ra_ap_ide_db::RootDatabase;
6-
use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
6+
use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig};
77
use ra_ap_paths::Utf8PathBuf;
88
use ra_ap_project_model::ProjectManifest;
99
use ra_ap_project_model::{CargoConfig, ManifestPath};
@@ -50,16 +50,12 @@ impl<'a> RustAnalyzer<'a> {
5050
pub fn load_workspace(
5151
project: &ProjectManifest,
5252
config: &CargoConfig,
53+
load_config: &LoadCargoConfig,
5354
) -> Option<(RootDatabase, Vfs)> {
5455
let progress = |t| (log::trace!("progress: {}", t));
55-
let load_config = LoadCargoConfig {
56-
load_out_dirs_from_check: true,
57-
with_proc_macro_server: ProcMacroServerChoice::Sysroot,
58-
prefill_caches: false,
59-
};
6056
let manifest = project.manifest_path();
6157

62-
match load_workspace_at(manifest.as_ref(), config, &load_config, &progress) {
58+
match load_workspace_at(manifest.as_ref(), config, load_config, &progress) {
6359
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
6460
Err(err) => {
6561
log::error!("failed to load workspace for {}: {}", manifest, err);

0 commit comments

Comments
 (0)