mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Merge #5884
5884: Add sysroot shortcut to rust-project.json
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
f647edcb08
3 changed files with 70 additions and 22 deletions
|
@ -39,11 +39,18 @@ pub enum ProjectWorkspace {
|
|||
impl fmt::Debug for ProjectWorkspace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ProjectWorkspace::Cargo { cargo, .. } => {
|
||||
f.debug_struct("Cargo").field("n_packages", &cargo.packages().len()).finish()
|
||||
}
|
||||
ProjectWorkspace::Cargo { cargo, sysroot } => f
|
||||
.debug_struct("Cargo")
|
||||
.field("n_packages", &cargo.packages().len())
|
||||
.field("n_sysroot_crates", &sysroot.crates().len())
|
||||
.finish(),
|
||||
ProjectWorkspace::Json { project } => {
|
||||
f.debug_struct("Json").field("n_crates", &project.n_crates()).finish()
|
||||
let mut debug_struct = f.debug_struct("Json");
|
||||
debug_struct.field("n_crates", &project.n_crates());
|
||||
if let Some(sysroot) = &project.sysroot {
|
||||
debug_struct.field("n_sysroot_crates", &sysroot.crates().len());
|
||||
}
|
||||
debug_struct.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +217,13 @@ impl ProjectWorkspace {
|
|||
})
|
||||
.collect::<FxHashSet<_>>()
|
||||
.into_iter()
|
||||
.chain(project.sysroot.as_ref().into_iter().flat_map(|sysroot| {
|
||||
sysroot.crates().map(move |krate| PackageRoot {
|
||||
is_member: false,
|
||||
include: vec![sysroot[krate].root_dir().to_path_buf()],
|
||||
exclude: Vec::new(),
|
||||
})
|
||||
}))
|
||||
.collect::<Vec<_>>(),
|
||||
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
||||
.packages()
|
||||
|
@ -272,6 +286,11 @@ impl ProjectWorkspace {
|
|||
let mut crate_graph = CrateGraph::default();
|
||||
match self {
|
||||
ProjectWorkspace::Json { project } => {
|
||||
let sysroot_dps = project
|
||||
.sysroot
|
||||
.as_ref()
|
||||
.map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load));
|
||||
|
||||
let mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default();
|
||||
let crates: FxHashMap<_, _> = project
|
||||
.crates()
|
||||
|
@ -309,25 +328,33 @@ impl ProjectWorkspace {
|
|||
.collect();
|
||||
|
||||
for (from, krate) in project.crates() {
|
||||
for dep in &krate.deps {
|
||||
let to_crate_id = dep.crate_id;
|
||||
if let (Some(&from), Some(&to)) =
|
||||
(crates.get(&from), crates.get(&to_crate_id))
|
||||
{
|
||||
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
|
||||
log::error!("cyclic dependency {:?} -> {:?}", from, to_crate_id);
|
||||
if let Some(&from) = crates.get(&from) {
|
||||
if let Some((public_deps, _proc_macro)) = &sysroot_dps {
|
||||
for (name, to) in public_deps.iter() {
|
||||
if let Err(_) = crate_graph.add_dep(from, name.clone(), *to) {
|
||||
log::error!("cyclic dependency on {} for {:?}", name, from)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for dep in &krate.deps {
|
||||
let to_crate_id = dep.crate_id;
|
||||
if let Some(&to) = crates.get(&to_crate_id) {
|
||||
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
|
||||
log::error!("cyclic dependency {:?} -> {:?}", from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load);
|
||||
|
||||
let mut cfg_options = CfgOptions::default();
|
||||
cfg_options.extend(get_rustc_cfg_options(target));
|
||||
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, &cfg_options, load);
|
||||
|
||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||
let mut pkg_crates = FxHashMap::default();
|
||||
|
||||
|
@ -410,7 +437,11 @@ impl ProjectWorkspace {
|
|||
}
|
||||
for (name, krate) in public_deps.iter() {
|
||||
if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
|
||||
log::error!("cyclic dependency on core for {}", &cargo[pkg].name)
|
||||
log::error!(
|
||||
"cyclic dependency on {} for {}",
|
||||
name,
|
||||
&cargo[pkg].name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,9 +516,11 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
|
|||
fn sysroot_to_crate_graph(
|
||||
crate_graph: &mut CrateGraph,
|
||||
sysroot: &Sysroot,
|
||||
cfg_options: &CfgOptions,
|
||||
target: Option<&str>,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
|
||||
let mut cfg_options = CfgOptions::default();
|
||||
cfg_options.extend(get_rustc_cfg_options(target));
|
||||
let sysroot_crates: FxHashMap<_, _> = sysroot
|
||||
.crates()
|
||||
.filter_map(|krate| {
|
||||
|
|
|
@ -7,11 +7,12 @@ use paths::{AbsPath, AbsPathBuf};
|
|||
use rustc_hash::FxHashMap;
|
||||
use serde::{de, Deserialize};
|
||||
|
||||
use crate::cfg_flag::CfgFlag;
|
||||
use crate::{cfg_flag::CfgFlag, Sysroot};
|
||||
|
||||
/// Roots and crates that compose this Rust project.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ProjectJson {
|
||||
pub(crate) sysroot: Option<Sysroot>,
|
||||
crates: Vec<Crate>,
|
||||
}
|
||||
|
||||
|
@ -34,6 +35,7 @@ pub struct Crate {
|
|||
impl ProjectJson {
|
||||
pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
|
||||
ProjectJson {
|
||||
sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)),
|
||||
crates: data
|
||||
.crates
|
||||
.into_iter()
|
||||
|
@ -43,11 +45,13 @@ impl ProjectJson {
|
|||
&& !crate_data.root_module.starts_with("..")
|
||||
|| crate_data.root_module.starts_with(base)
|
||||
});
|
||||
let root_module = base.join(crate_data.root_module);
|
||||
let root_module = base.join(crate_data.root_module).normalize();
|
||||
let (include, exclude) = match crate_data.source {
|
||||
Some(src) => {
|
||||
let absolutize = |dirs: Vec<PathBuf>| {
|
||||
dirs.into_iter().map(|it| base.join(it)).collect::<Vec<_>>()
|
||||
dirs.into_iter()
|
||||
.map(|it| base.join(it).normalize())
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
(absolutize(src.include_dirs), absolutize(src.exclude_dirs))
|
||||
}
|
||||
|
@ -89,6 +93,7 @@ impl ProjectJson {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ProjectJsonData {
|
||||
sysroot_src: Option<PathBuf>,
|
||||
crates: Vec<CrateData>,
|
||||
}
|
||||
|
||||
|
|
|
@ -273,9 +273,19 @@ However, if you use some other build system, you'll have to describe the structu
|
|||
[source,TypeScript]
|
||||
----
|
||||
interface JsonProject {
|
||||
/// The set of crates comprising the current project.
|
||||
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
|
||||
crates: Crate[];
|
||||
/// Path to the directory with *source code* of sysroot crates.
|
||||
///
|
||||
/// It should point to the directory where std, core, and friends can be found:
|
||||
/// https://github.com/rust-lang/rust/tree/master/library.
|
||||
///
|
||||
/// If provided, rust-analyzer automatically adds dependencies on sysroot
|
||||
/// crates. Conversely, if you omit this path, you can specify sysroot
|
||||
/// dependencies yourself and, for example, have several different "sysroots" in
|
||||
/// one graph of crates.
|
||||
sysroot_src?: string;
|
||||
/// The set of crates comprising the current project.
|
||||
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
|
||||
crates: Crate[];
|
||||
}
|
||||
|
||||
interface Crate {
|
||||
|
|
Loading…
Reference in a new issue