mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Add ProcMacroClient
This commit is contained in:
parent
a617f24eae
commit
d0b6ed4441
17 changed files with 222 additions and 43 deletions
|
@ -83,6 +83,7 @@ pub struct PackageData {
|
|||
pub edition: Edition,
|
||||
pub features: Vec<String>,
|
||||
pub out_dir: Option<PathBuf>,
|
||||
pub proc_macro_dylib_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -158,8 +159,11 @@ impl CargoWorkspace {
|
|||
})?;
|
||||
|
||||
let mut out_dir_by_id = FxHashMap::default();
|
||||
let mut proc_macro_dylib_paths = FxHashMap::default();
|
||||
if cargo_features.load_out_dirs_from_check {
|
||||
out_dir_by_id = load_out_dirs(cargo_toml, cargo_features);
|
||||
let resources = load_extern_resources(cargo_toml, cargo_features);
|
||||
out_dir_by_id = resources.out_dirs;
|
||||
proc_macro_dylib_paths = resources.proc_dylib_paths;
|
||||
}
|
||||
|
||||
let mut pkg_by_id = FxHashMap::default();
|
||||
|
@ -183,6 +187,7 @@ impl CargoWorkspace {
|
|||
dependencies: Vec::new(),
|
||||
features: Vec::new(),
|
||||
out_dir: out_dir_by_id.get(&id).cloned(),
|
||||
proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(),
|
||||
});
|
||||
let pkg_data = &mut packages[pkg];
|
||||
pkg_by_id.insert(id, pkg);
|
||||
|
@ -246,10 +251,13 @@ impl CargoWorkspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_out_dirs(
|
||||
cargo_toml: &Path,
|
||||
cargo_features: &CargoFeatures,
|
||||
) -> FxHashMap<PackageId, PathBuf> {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ExternResources {
|
||||
out_dirs: FxHashMap<PackageId, PathBuf>,
|
||||
proc_dylib_paths: FxHashMap<PackageId, PathBuf>,
|
||||
}
|
||||
|
||||
pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures) -> ExternResources {
|
||||
let mut args: Vec<String> = vec![
|
||||
"check".to_string(),
|
||||
"--message-format=json".to_string(),
|
||||
|
@ -267,14 +275,21 @@ pub fn load_out_dirs(
|
|||
args.extend(cargo_features.features.iter().cloned());
|
||||
}
|
||||
|
||||
let mut acc = FxHashMap::default();
|
||||
let mut acc = ExternResources::default();
|
||||
let res = run_cargo(&args, cargo_toml.parent(), &mut |message| {
|
||||
match message {
|
||||
Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => {
|
||||
acc.insert(package_id, out_dir);
|
||||
acc.out_dirs.insert(package_id, out_dir);
|
||||
}
|
||||
|
||||
Message::CompilerArtifact(_) => (),
|
||||
Message::CompilerArtifact(message) => {
|
||||
if message.target.kind.contains(&"proc-macro".to_string()) {
|
||||
let package_id = message.package_id;
|
||||
if let Some(filename) = message.filenames.get(0) {
|
||||
acc.proc_dylib_paths.insert(package_id, filename.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::CompilerMessage(_) => (),
|
||||
Message::Unknown => (),
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ pub struct Crate {
|
|||
pub(crate) atom_cfgs: FxHashSet<String>,
|
||||
pub(crate) key_value_cfgs: FxHashMap<String, String>,
|
||||
pub(crate) out_dir: Option<PathBuf>,
|
||||
pub(crate) proc_macro_dylib_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize)]
|
||||
|
|
|
@ -23,6 +23,7 @@ pub use crate::{
|
|||
json_project::JsonProject,
|
||||
sysroot::Sysroot,
|
||||
};
|
||||
pub use ra_proc_macro::ProcMacroClient;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct CargoTomlNotFoundError {
|
||||
|
@ -173,6 +174,29 @@ impl ProjectWorkspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
|
||||
match self {
|
||||
ProjectWorkspace::Json { project } => {
|
||||
let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len());
|
||||
for krate in &project.crates {
|
||||
if let Some(out_dir) = &krate.proc_macro_dylib_path {
|
||||
proc_macro_dylib_paths.push(out_dir.to_path_buf());
|
||||
}
|
||||
}
|
||||
proc_macro_dylib_paths
|
||||
}
|
||||
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
|
||||
let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len());
|
||||
for pkg in cargo.packages() {
|
||||
if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path {
|
||||
proc_macro_dylib_paths.push(dylib_path.to_path_buf());
|
||||
}
|
||||
}
|
||||
proc_macro_dylib_paths
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn n_packages(&self) -> usize {
|
||||
match self {
|
||||
ProjectWorkspace::Json { project } => project.crates.len(),
|
||||
|
@ -186,6 +210,7 @@ impl ProjectWorkspace {
|
|||
&self,
|
||||
default_cfg_options: &CfgOptions,
|
||||
extern_source_roots: &FxHashMap<PathBuf, ExternSourceId>,
|
||||
proc_macro_client: &ProcMacroClient,
|
||||
load: &mut dyn FnMut(&Path) -> Option<FileId>,
|
||||
) -> CrateGraph {
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
|
@ -219,7 +244,10 @@ impl ProjectWorkspace {
|
|||
extern_source.set_extern_path(&out_dir, extern_source_id);
|
||||
}
|
||||
}
|
||||
|
||||
let proc_macro = krate
|
||||
.proc_macro_dylib_path
|
||||
.clone()
|
||||
.map(|it| proc_macro_client.by_dylib_path(&it));
|
||||
// FIXME: No crate name in json definition such that we cannot add OUT_DIR to env
|
||||
crates.insert(
|
||||
crate_id,
|
||||
|
@ -231,6 +259,7 @@ impl ProjectWorkspace {
|
|||
cfg_options,
|
||||
env,
|
||||
extern_source,
|
||||
proc_macro.unwrap_or_default(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -270,6 +299,8 @@ impl ProjectWorkspace {
|
|||
|
||||
let env = Env::default();
|
||||
let extern_source = ExternSource::default();
|
||||
let proc_macro = vec![];
|
||||
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
file_id,
|
||||
Edition::Edition2018,
|
||||
|
@ -280,6 +311,7 @@ impl ProjectWorkspace {
|
|||
cfg_options,
|
||||
env,
|
||||
extern_source,
|
||||
proc_macro,
|
||||
);
|
||||
sysroot_crates.insert(krate, crate_id);
|
||||
}
|
||||
|
@ -327,6 +359,12 @@ impl ProjectWorkspace {
|
|||
extern_source.set_extern_path(&out_dir, extern_source_id);
|
||||
}
|
||||
}
|
||||
let proc_macro = cargo[pkg]
|
||||
.proc_macro_dylib_path
|
||||
.as_ref()
|
||||
.map(|it| proc_macro_client.by_dylib_path(&it))
|
||||
.unwrap_or_default();
|
||||
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
file_id,
|
||||
edition,
|
||||
|
@ -334,6 +372,7 @@ impl ProjectWorkspace {
|
|||
cfg_options,
|
||||
env,
|
||||
extern_source,
|
||||
proc_macro.clone(),
|
||||
);
|
||||
if cargo[tgt].kind == TargetKind::Lib {
|
||||
lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue