aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_project_model/src/lib.rs51
-rw-r--r--crates/rust-analyzer/src/main_loop.rs20
2 files changed, 24 insertions, 47 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 3adb8baf6..4f098b706 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -88,46 +88,28 @@ impl ProjectRoot {
88 } 88 }
89 89
90 pub fn discover(path: &Path) -> io::Result<Vec<ProjectRoot>> { 90 pub fn discover(path: &Path) -> io::Result<Vec<ProjectRoot>> {
91 if let Some(project_json) = find_rust_project_json(path) { 91 if let Some(project_json) = find_in_parent_dirs(path, "rust-project.json") {
92 return Ok(vec![ProjectRoot::ProjectJson(project_json)]); 92 return Ok(vec![ProjectRoot::ProjectJson(project_json)]);
93 } 93 }
94 return find_cargo_toml(path) 94 return find_cargo_toml(path)
95 .map(|paths| paths.into_iter().map(ProjectRoot::CargoToml).collect()); 95 .map(|paths| paths.into_iter().map(ProjectRoot::CargoToml).collect());
96 96
97 fn find_rust_project_json(path: &Path) -> Option<PathBuf> {
98 if path.ends_with("rust-project.json") {
99 return Some(path.to_path_buf());
100 }
101
102 let mut curr = Some(path);
103 while let Some(path) = curr {
104 let candidate = path.join("rust-project.json");
105 if candidate.exists() {
106 return Some(candidate);
107 }
108 curr = path.parent();
109 }
110
111 None
112 }
113
114 fn find_cargo_toml(path: &Path) -> io::Result<Vec<PathBuf>> { 97 fn find_cargo_toml(path: &Path) -> io::Result<Vec<PathBuf>> {
115 if path.ends_with("Cargo.toml") { 98 match find_in_parent_dirs(path, "Cargo.toml") {
116 return Ok(vec![path.to_path_buf()]); 99 Some(it) => Ok(vec![it]),
100 None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)),
117 } 101 }
102 }
118 103
119 if let Some(p) = find_cargo_toml_in_parent_dir(path) { 104 fn find_in_parent_dirs(path: &Path, target_file_name: &str) -> Option<PathBuf> {
120 return Ok(vec![p]); 105 if path.ends_with(target_file_name) {
106 return Some(path.to_owned());
121 } 107 }
122 108
123 let entities = read_dir(path)?;
124 Ok(find_cargo_toml_in_child_dir(entities))
125 }
126
127 fn find_cargo_toml_in_parent_dir(path: &Path) -> Option<PathBuf> {
128 let mut curr = Some(path); 109 let mut curr = Some(path);
110
129 while let Some(path) = curr { 111 while let Some(path) = curr {
130 let candidate = path.join("Cargo.toml"); 112 let candidate = path.join(target_file_name);
131 if candidate.exists() { 113 if candidate.exists() {
132 return Some(candidate); 114 return Some(candidate);
133 } 115 }
@@ -139,14 +121,11 @@ impl ProjectRoot {
139 121
140 fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<PathBuf> { 122 fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec<PathBuf> {
141 // Only one level down to avoid cycles the easy way and stop a runaway scan with large projects 123 // Only one level down to avoid cycles the easy way and stop a runaway scan with large projects
142 let mut valid_canditates = vec![]; 124 entities
143 for entity in entities.filter_map(Result::ok) { 125 .filter_map(Result::ok)
144 let candidate = entity.path().join("Cargo.toml"); 126 .map(|it| it.path().join("Cargo.toml"))
145 if candidate.exists() { 127 .filter(|it| it.exists())
146 valid_canditates.push(candidate) 128 .collect()
147 }
148 }
149 valid_canditates
150 } 129 }
151 } 130 }
152} 131}
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index b77f0c5a9..17b0b95b9 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -96,23 +96,21 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
96 let mut world_state = { 96 let mut world_state = {
97 let workspaces = { 97 let workspaces = {
98 // FIXME: support dynamic workspace loading. 98 // FIXME: support dynamic workspace loading.
99 let mut visited = FxHashSet::default(); 99 let project_roots: FxHashSet<_> = ws_roots
100 let project_roots = ws_roots
101 .iter() 100 .iter()
102 .filter_map(|it| ra_project_model::ProjectRoot::discover(it).ok()) 101 .filter_map(|it| ra_project_model::ProjectRoot::discover(it).ok())
103 .flatten() 102 .flatten()
104 .filter(|it| visited.insert(it.clone())) 103 .collect();
105 .collect::<Vec<_>>();
106 104
107 if project_roots.is_empty() && config.notifications.cargo_toml_not_found { 105 if project_roots.is_empty() && config.notifications.cargo_toml_not_found {
108 show_message( 106 show_message(
109 req::MessageType::Error, 107 req::MessageType::Error,
110 format!( 108 format!(
111 "rust-analyzer failed to discover workspace, no Cargo.toml found, dirs searched: {}", 109 "rust-analyzer failed to discover workspace, no Cargo.toml found, dirs searched: {}",
112 ws_roots.iter().format_with(", ", |it, f| f(&it.display())) 110 ws_roots.iter().format_with(", ", |it, f| f(&it.display()))
113 ), 111 ),
114 &connection.sender, 112 &connection.sender,
115 ); 113 );
116 }; 114 };
117 115
118 project_roots 116 project_roots