mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #4381
4381: Simplify r=matklad a=Veetaha Co-authored-by: veetaha <veetaha2@gmail.com>
This commit is contained in:
commit
d7a0b0ff91
2 changed files with 25 additions and 48 deletions
|
@ -88,46 +88,28 @@ impl ProjectRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discover(path: &Path) -> io::Result<Vec<ProjectRoot>> {
|
pub fn discover(path: &Path) -> io::Result<Vec<ProjectRoot>> {
|
||||||
if let Some(project_json) = find_rust_project_json(path) {
|
if let Some(project_json) = find_in_parent_dirs(path, "rust-project.json") {
|
||||||
return Ok(vec![ProjectRoot::ProjectJson(project_json)]);
|
return Ok(vec![ProjectRoot::ProjectJson(project_json)]);
|
||||||
}
|
}
|
||||||
return find_cargo_toml(path)
|
return find_cargo_toml(path)
|
||||||
.map(|paths| paths.into_iter().map(ProjectRoot::CargoToml).collect());
|
.map(|paths| paths.into_iter().map(ProjectRoot::CargoToml).collect());
|
||||||
|
|
||||||
fn find_rust_project_json(path: &Path) -> Option<PathBuf> {
|
|
||||||
if path.ends_with("rust-project.json") {
|
|
||||||
return Some(path.to_path_buf());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut curr = Some(path);
|
|
||||||
while let Some(path) = curr {
|
|
||||||
let candidate = path.join("rust-project.json");
|
|
||||||
if candidate.exists() {
|
|
||||||
return Some(candidate);
|
|
||||||
}
|
|
||||||
curr = path.parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_cargo_toml(path: &Path) -> io::Result<Vec<PathBuf>> {
|
fn find_cargo_toml(path: &Path) -> io::Result<Vec<PathBuf>> {
|
||||||
if path.ends_with("Cargo.toml") {
|
match find_in_parent_dirs(path, "Cargo.toml") {
|
||||||
return Ok(vec![path.to_path_buf()]);
|
Some(it) => Ok(vec![it]),
|
||||||
|
None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(p) = find_cargo_toml_in_parent_dir(path) {
|
|
||||||
return Ok(vec![p]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let entities = read_dir(path)?;
|
|
||||||
Ok(find_cargo_toml_in_child_dir(entities))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_cargo_toml_in_parent_dir(path: &Path) -> Option<PathBuf> {
|
fn find_in_parent_dirs(path: &Path, target_file_name: &str) -> Option<PathBuf> {
|
||||||
|
if path.ends_with(target_file_name) {
|
||||||
|
return Some(path.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
let mut curr = Some(path);
|
let mut curr = Some(path);
|
||||||
|
|
||||||
while let Some(path) = curr {
|
while let Some(path) = curr {
|
||||||
let candidate = path.join("Cargo.toml");
|
let candidate = path.join(target_file_name);
|
||||||
if candidate.exists() {
|
if candidate.exists() {
|
||||||
return Some(candidate);
|
return Some(candidate);
|
||||||
}
|
}
|
||||||
|
@ -139,14 +121,11 @@ impl ProjectRoot {
|
||||||
|
|
||||||
fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<PathBuf> {
|
fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<PathBuf> {
|
||||||
// Only one level down to avoid cycles the easy way and stop a runaway scan with large projects
|
// Only one level down to avoid cycles the easy way and stop a runaway scan with large projects
|
||||||
let mut valid_canditates = vec![];
|
entities
|
||||||
for entity in entities.filter_map(Result::ok) {
|
.filter_map(Result::ok)
|
||||||
let candidate = entity.path().join("Cargo.toml");
|
.map(|it| it.path().join("Cargo.toml"))
|
||||||
if candidate.exists() {
|
.filter(|it| it.exists())
|
||||||
valid_canditates.push(candidate)
|
.collect()
|
||||||
}
|
|
||||||
}
|
|
||||||
valid_canditates
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,23 +96,21 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
|
||||||
let mut world_state = {
|
let mut world_state = {
|
||||||
let workspaces = {
|
let workspaces = {
|
||||||
// FIXME: support dynamic workspace loading.
|
// FIXME: support dynamic workspace loading.
|
||||||
let mut visited = FxHashSet::default();
|
let project_roots: FxHashSet<_> = ws_roots
|
||||||
let project_roots = ws_roots
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|it| ra_project_model::ProjectRoot::discover(it).ok())
|
.filter_map(|it| ra_project_model::ProjectRoot::discover(it).ok())
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(|it| visited.insert(it.clone()))
|
.collect();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if project_roots.is_empty() && config.notifications.cargo_toml_not_found {
|
if project_roots.is_empty() && config.notifications.cargo_toml_not_found {
|
||||||
show_message(
|
show_message(
|
||||||
req::MessageType::Error,
|
req::MessageType::Error,
|
||||||
format!(
|
format!(
|
||||||
"rust-analyzer failed to discover workspace, no Cargo.toml found, dirs searched: {}",
|
"rust-analyzer failed to discover workspace, no Cargo.toml found, dirs searched: {}",
|
||||||
ws_roots.iter().format_with(", ", |it, f| f(&it.display()))
|
ws_roots.iter().format_with(", ", |it, f| f(&it.display()))
|
||||||
),
|
),
|
||||||
&connection.sender,
|
&connection.sender,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
project_roots
|
project_roots
|
||||||
|
|
Loading…
Reference in a new issue