mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-21 04:03:11 +00:00
Merge #4860
4860: Accept relative paths in rust-project.json r=matklad a=tweksteen If a relative path is found as part of Crate.root_module or Root.path, interpret it as relative to the location of the rust-project.json file. Fixes: #4816 Co-authored-by: Thiébaud Weksteen <tweek@google.com>
This commit is contained in:
commit
f4f51171ca
@ -29,13 +29,7 @@ pub enum ProjectWorkspace {
|
|||||||
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
|
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
|
||||||
Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
|
Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
|
||||||
/// Project workspace was manually specified using a `rust-project.json` file.
|
/// Project workspace was manually specified using a `rust-project.json` file.
|
||||||
Json { project: JsonProject },
|
Json { project: JsonProject, project_location: PathBuf },
|
||||||
}
|
|
||||||
|
|
||||||
impl From<JsonProject> for ProjectWorkspace {
|
|
||||||
fn from(project: JsonProject) -> ProjectWorkspace {
|
|
||||||
ProjectWorkspace::Json { project }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `PackageRoot` describes a package root folder.
|
/// `PackageRoot` describes a package root folder.
|
||||||
@ -164,10 +158,15 @@ impl ProjectWorkspace {
|
|||||||
format!("Failed to open json file {}", project_json.display())
|
format!("Failed to open json file {}", project_json.display())
|
||||||
})?;
|
})?;
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
|
let project_location = match project_json.parent() {
|
||||||
|
Some(parent) => PathBuf::from(parent),
|
||||||
|
None => PathBuf::new(),
|
||||||
|
};
|
||||||
ProjectWorkspace::Json {
|
ProjectWorkspace::Json {
|
||||||
project: from_reader(reader).with_context(|| {
|
project: from_reader(reader).with_context(|| {
|
||||||
format!("Failed to deserialize json file {}", project_json.display())
|
format!("Failed to deserialize json file {}", project_json.display())
|
||||||
})?,
|
})?,
|
||||||
|
project_location: project_location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectManifest::CargoToml(cargo_toml) => {
|
ProjectManifest::CargoToml(cargo_toml) => {
|
||||||
@ -200,9 +199,11 @@ impl ProjectWorkspace {
|
|||||||
/// the root is a member of the current workspace
|
/// the root is a member of the current workspace
|
||||||
pub fn to_roots(&self) -> Vec<PackageRoot> {
|
pub fn to_roots(&self) -> Vec<PackageRoot> {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project } => {
|
ProjectWorkspace::Json { project, project_location } => project
|
||||||
project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect()
|
.roots
|
||||||
}
|
.iter()
|
||||||
|
.map(|r| PackageRoot::new_member(project_location.join(&r.path)))
|
||||||
|
.collect(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
|
||||||
.packages()
|
.packages()
|
||||||
.map(|pkg| PackageRoot {
|
.map(|pkg| PackageRoot {
|
||||||
@ -219,7 +220,7 @@ impl ProjectWorkspace {
|
|||||||
|
|
||||||
pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
|
pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project } => project
|
ProjectWorkspace::Json { project, .. } => project
|
||||||
.crates
|
.crates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
|
.filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
|
||||||
@ -235,7 +236,7 @@ impl ProjectWorkspace {
|
|||||||
|
|
||||||
pub fn n_packages(&self) -> usize {
|
pub fn n_packages(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project } => project.crates.len(),
|
ProjectWorkspace::Json { project, .. } => project.crates.len(),
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
ProjectWorkspace::Cargo { cargo, sysroot } => {
|
||||||
cargo.packages().len() + sysroot.crates().len()
|
cargo.packages().len() + sysroot.crates().len()
|
||||||
}
|
}
|
||||||
@ -251,13 +252,14 @@ impl ProjectWorkspace {
|
|||||||
) -> CrateGraph {
|
) -> CrateGraph {
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
match self {
|
match self {
|
||||||
ProjectWorkspace::Json { project } => {
|
ProjectWorkspace::Json { project, project_location } => {
|
||||||
let crates: FxHashMap<_, _> = project
|
let crates: FxHashMap<_, _> = project
|
||||||
.crates
|
.crates
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(seq_index, krate)| {
|
.filter_map(|(seq_index, krate)| {
|
||||||
let file_id = load(&krate.root_module)?;
|
let file_path = project_location.join(&krate.root_module);
|
||||||
|
let file_id = load(&file_path)?;
|
||||||
let edition = match krate.edition {
|
let edition = match krate.edition {
|
||||||
json_project::Edition::Edition2015 => Edition::Edition2015,
|
json_project::Edition::Edition2015 => Edition::Edition2015,
|
||||||
json_project::Edition::Edition2018 => Edition::Edition2018,
|
json_project::Edition::Edition2018 => Edition::Edition2018,
|
||||||
@ -540,7 +542,7 @@ impl ProjectWorkspace {
|
|||||||
ProjectWorkspace::Cargo { cargo, .. } => {
|
ProjectWorkspace::Cargo { cargo, .. } => {
|
||||||
Some(cargo.workspace_root()).filter(|root| path.starts_with(root))
|
Some(cargo.workspace_root()).filter(|root| path.starts_with(root))
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Json { project: JsonProject { roots, .. } } => roots
|
ProjectWorkspace::Json { project: JsonProject { roots, .. }, .. } => roots
|
||||||
.iter()
|
.iter()
|
||||||
.find(|root| path.starts_with(&root.path))
|
.find(|root| path.starts_with(&root.path))
|
||||||
.map(|root| root.path.as_ref()),
|
.map(|root| root.path.as_ref()),
|
||||||
|
@ -108,11 +108,11 @@ fn run_server() -> Result<()> {
|
|||||||
config.update(value);
|
config.update(value);
|
||||||
}
|
}
|
||||||
config.update_caps(&initialize_params.capabilities);
|
config.update_caps(&initialize_params.capabilities);
|
||||||
|
let cwd = std::env::current_dir()?;
|
||||||
|
config.root_path =
|
||||||
|
initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
|
||||||
|
|
||||||
if config.linked_projects.is_empty() {
|
if config.linked_projects.is_empty() {
|
||||||
let cwd = std::env::current_dir()?;
|
|
||||||
let root =
|
|
||||||
initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
|
|
||||||
let workspace_roots = initialize_params
|
let workspace_roots = initialize_params
|
||||||
.workspace_folders
|
.workspace_folders
|
||||||
.map(|workspaces| {
|
.map(|workspaces| {
|
||||||
@ -122,7 +122,7 @@ fn run_server() -> Result<()> {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
.filter(|workspaces| !workspaces.is_empty())
|
.filter(|workspaces| !workspaces.is_empty())
|
||||||
.unwrap_or_else(|| vec![root]);
|
.unwrap_or_else(|| vec![config.root_path.clone()]);
|
||||||
|
|
||||||
config.linked_projects = ProjectManifest::discover_all(&workspace_roots)
|
config.linked_projects = ProjectManifest::discover_all(&workspace_roots)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -38,12 +38,13 @@ pub struct Config {
|
|||||||
|
|
||||||
pub with_sysroot: bool,
|
pub with_sysroot: bool,
|
||||||
pub linked_projects: Vec<LinkedProject>,
|
pub linked_projects: Vec<LinkedProject>,
|
||||||
|
pub root_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum LinkedProject {
|
pub enum LinkedProject {
|
||||||
ProjectManifest(ProjectManifest),
|
ProjectManifest(ProjectManifest),
|
||||||
JsonProject(JsonProject),
|
InlineJsonProject(JsonProject),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ProjectManifest> for LinkedProject {
|
impl From<ProjectManifest> for LinkedProject {
|
||||||
@ -54,7 +55,7 @@ impl From<ProjectManifest> for LinkedProject {
|
|||||||
|
|
||||||
impl From<JsonProject> for LinkedProject {
|
impl From<JsonProject> for LinkedProject {
|
||||||
fn from(v: JsonProject) -> Self {
|
fn from(v: JsonProject) -> Self {
|
||||||
LinkedProject::JsonProject(v)
|
LinkedProject::InlineJsonProject(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +168,7 @@ impl Default for Config {
|
|||||||
lens: LensConfig::default(),
|
lens: LensConfig::default(),
|
||||||
hover: HoverConfig::default(),
|
hover: HoverConfig::default(),
|
||||||
linked_projects: Vec::new(),
|
linked_projects: Vec::new(),
|
||||||
|
root_path: PathBuf::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,12 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
|
|||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
LinkedProject::JsonProject(it) => Some(it.clone().into()),
|
LinkedProject::InlineJsonProject(it) => {
|
||||||
|
Some(ra_project_model::ProjectWorkspace::Json {
|
||||||
|
project: it.clone(),
|
||||||
|
project_location: config.root_path.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user