mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +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 {
|
impl fmt::Debug for ProjectWorkspace {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Cargo { cargo, .. } => {
|
ProjectWorkspace::Cargo { cargo, sysroot } => f
|
||||||
f.debug_struct("Cargo").field("n_packages", &cargo.packages().len()).finish()
|
.debug_struct("Cargo")
|
||||||
}
|
.field("n_packages", &cargo.packages().len())
|
||||||
|
.field("n_sysroot_crates", &sysroot.crates().len())
|
||||||
|
.finish(),
|
||||||
ProjectWorkspace::Json { project } => {
|
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<_>>()
|
.collect::<FxHashSet<_>>()
|
||||||
.into_iter()
|
.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<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
||||||
.packages()
|
.packages()
|
||||||
|
@ -272,6 +286,11 @@ impl ProjectWorkspace {
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project } => {
|
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 mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default();
|
||||||
let crates: FxHashMap<_, _> = project
|
let crates: FxHashMap<_, _> = project
|
||||||
.crates()
|
.crates()
|
||||||
|
@ -309,25 +328,33 @@ impl ProjectWorkspace {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for (from, krate) in project.crates() {
|
for (from, krate) in project.crates() {
|
||||||
|
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 {
|
for dep in &krate.deps {
|
||||||
let to_crate_id = dep.crate_id;
|
let to_crate_id = dep.crate_id;
|
||||||
if let (Some(&from), Some(&to)) =
|
if let Some(&to) = crates.get(&to_crate_id) {
|
||||||
(crates.get(&from), crates.get(&to_crate_id))
|
|
||||||
{
|
|
||||||
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
|
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
|
||||||
log::error!("cyclic dependency {:?} -> {:?}", from, to_crate_id);
|
log::error!("cyclic dependency {:?} -> {:?}", from, to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
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();
|
let mut cfg_options = CfgOptions::default();
|
||||||
cfg_options.extend(get_rustc_cfg_options(target));
|
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_to_lib_crate = FxHashMap::default();
|
||||||
let mut pkg_crates = FxHashMap::default();
|
let mut pkg_crates = FxHashMap::default();
|
||||||
|
|
||||||
|
@ -410,7 +437,11 @@ impl ProjectWorkspace {
|
||||||
}
|
}
|
||||||
for (name, krate) in public_deps.iter() {
|
for (name, krate) in public_deps.iter() {
|
||||||
if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
|
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(
|
fn sysroot_to_crate_graph(
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
sysroot: &Sysroot,
|
sysroot: &Sysroot,
|
||||||
cfg_options: &CfgOptions,
|
target: Option<&str>,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
|
) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
|
||||||
|
let mut cfg_options = CfgOptions::default();
|
||||||
|
cfg_options.extend(get_rustc_cfg_options(target));
|
||||||
let sysroot_crates: FxHashMap<_, _> = sysroot
|
let sysroot_crates: FxHashMap<_, _> = sysroot
|
||||||
.crates()
|
.crates()
|
||||||
.filter_map(|krate| {
|
.filter_map(|krate| {
|
||||||
|
|
|
@ -7,11 +7,12 @@ use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::{de, Deserialize};
|
use serde::{de, Deserialize};
|
||||||
|
|
||||||
use crate::cfg_flag::CfgFlag;
|
use crate::{cfg_flag::CfgFlag, Sysroot};
|
||||||
|
|
||||||
/// Roots and crates that compose this Rust project.
|
/// Roots and crates that compose this Rust project.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct ProjectJson {
|
pub struct ProjectJson {
|
||||||
|
pub(crate) sysroot: Option<Sysroot>,
|
||||||
crates: Vec<Crate>,
|
crates: Vec<Crate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ pub struct Crate {
|
||||||
impl ProjectJson {
|
impl ProjectJson {
|
||||||
pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
|
pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
|
||||||
ProjectJson {
|
ProjectJson {
|
||||||
|
sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)),
|
||||||
crates: data
|
crates: data
|
||||||
.crates
|
.crates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -43,11 +45,13 @@ impl ProjectJson {
|
||||||
&& !crate_data.root_module.starts_with("..")
|
&& !crate_data.root_module.starts_with("..")
|
||||||
|| crate_data.root_module.starts_with(base)
|
|| 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 {
|
let (include, exclude) = match crate_data.source {
|
||||||
Some(src) => {
|
Some(src) => {
|
||||||
let absolutize = |dirs: Vec<PathBuf>| {
|
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))
|
(absolutize(src.include_dirs), absolutize(src.exclude_dirs))
|
||||||
}
|
}
|
||||||
|
@ -89,6 +93,7 @@ impl ProjectJson {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct ProjectJsonData {
|
pub struct ProjectJsonData {
|
||||||
|
sysroot_src: Option<PathBuf>,
|
||||||
crates: Vec<CrateData>,
|
crates: Vec<CrateData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,16 @@ However, if you use some other build system, you'll have to describe the structu
|
||||||
[source,TypeScript]
|
[source,TypeScript]
|
||||||
----
|
----
|
||||||
interface JsonProject {
|
interface JsonProject {
|
||||||
|
/// 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.
|
/// The set of crates comprising the current project.
|
||||||
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
|
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
|
||||||
crates: Crate[];
|
crates: Crate[];
|
||||||
|
|
Loading…
Reference in a new issue