Skip to content

Commit

Permalink
Merge #5884
Browse files Browse the repository at this point in the history
5884: Add sysroot shortcut to rust-project.json
 r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <[email protected]>
  • Loading branch information
bors[bot] and matklad authored Aug 25, 2020
2 parents 91bedef + 189521a commit f647edc
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 22 deletions.
65 changes: 49 additions & 16 deletions crates/project_model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
}
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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
)
}
}
}
Expand Down Expand Up @@ -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| {
Expand Down
11 changes: 8 additions & 3 deletions crates/project_model/src/project_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
}

Expand All @@ -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()
Expand All @@ -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))
}
Expand Down Expand Up @@ -89,6 +93,7 @@ impl ProjectJson {

#[derive(Deserialize)]
pub struct ProjectJsonData {
sysroot_src: Option<PathBuf>,
crates: Vec<CrateData>,
}

Expand Down
16 changes: 13 additions & 3 deletions docs/user/manual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit f647edc

Please sign in to comment.