Skip to content

Commit 8baa4c5

Browse files
committed
Groundwork for specifying the set of projects via config
1 parent 03a7619 commit 8baa4c5

File tree

5 files changed

+83
-46
lines changed

5 files changed

+83
-46
lines changed

crates/rust-analyzer/src/bin/main.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44
mod args;
55

66
use lsp_server::Connection;
7-
use rust_analyzer::{cli, config::Config, from_json, Result};
7+
use rust_analyzer::{
8+
cli,
9+
config::{Config, LinkedProject},
10+
from_json, Result,
11+
};
812

913
use crate::args::HelpPrinted;
14+
use ra_project_model::ProjectManifest;
1015

1116
fn main() -> Result<()> {
1217
setup_logging()?;
@@ -97,28 +102,38 @@ fn run_server() -> Result<()> {
97102
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
98103
}
99104

100-
let cwd = std::env::current_dir()?;
101-
let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
102-
103-
let workspace_roots = initialize_params
104-
.workspace_folders
105-
.map(|workspaces| {
106-
workspaces.into_iter().filter_map(|it| it.uri.to_file_path().ok()).collect::<Vec<_>>()
107-
})
108-
.filter(|workspaces| !workspaces.is_empty())
109-
.unwrap_or_else(|| vec![root]);
110-
111105
let config = {
112106
let mut config = Config::default();
113107
if let Some(value) = &initialize_params.initialization_options {
114108
config.update(value);
115109
}
116110
config.update_caps(&initialize_params.capabilities);
117111

112+
if config.linked_projects.is_empty() {
113+
let cwd = std::env::current_dir()?;
114+
let root =
115+
initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
116+
let workspace_roots = initialize_params
117+
.workspace_folders
118+
.map(|workspaces| {
119+
workspaces
120+
.into_iter()
121+
.filter_map(|it| it.uri.to_file_path().ok())
122+
.collect::<Vec<_>>()
123+
})
124+
.filter(|workspaces| !workspaces.is_empty())
125+
.unwrap_or_else(|| vec![root]);
126+
127+
config.linked_projects = ProjectManifest::discover_all(&workspace_roots)
128+
.into_iter()
129+
.map(LinkedProject::from)
130+
.collect();
131+
}
132+
118133
config
119134
};
120135

121-
rust_analyzer::main_loop(workspace_roots, config, connection)?;
136+
rust_analyzer::main_loop(config, connection)?;
122137

123138
log::info!("shutting down IO...");
124139
io_threads.join()?;

crates/rust-analyzer/src/cli/load_cargo.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use crossbeam_channel::{unbounded, Receiver};
88
use ra_db::{ExternSourceId, FileId, SourceRootId};
99
use ra_ide::{AnalysisChange, AnalysisHost};
1010
use ra_project_model::{
11-
get_rustc_cfg_options, CargoConfig, PackageRoot, ProcMacroClient, ProjectManifest, ProjectWorkspace,
11+
get_rustc_cfg_options, CargoConfig, PackageRoot, ProcMacroClient, ProjectManifest,
12+
ProjectWorkspace,
1213
};
1314
use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
1415
use rustc_hash::{FxHashMap, FxHashSet};

crates/rust-analyzer/src/config.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ use std::{ffi::OsString, path::PathBuf};
1212
use lsp_types::ClientCapabilities;
1313
use ra_flycheck::FlycheckConfig;
1414
use ra_ide::{AssistConfig, CompletionConfig, InlayHintsConfig};
15-
use ra_project_model::CargoConfig;
15+
use ra_project_model::{CargoConfig, JsonProject, ProjectManifest};
1616
use serde::Deserialize;
1717

1818
#[derive(Debug, Clone)]
1919
pub struct Config {
2020
pub client_caps: ClientCapsConfig,
2121

22-
pub with_sysroot: bool,
2322
pub publish_diagnostics: bool,
2423
pub lru_capacity: Option<usize>,
2524
pub proc_macro_srv: Option<(PathBuf, Vec<OsString>)>,
@@ -35,6 +34,27 @@ pub struct Config {
3534
pub assist: AssistConfig,
3635
pub call_info_full: bool,
3736
pub lens: LensConfig,
37+
38+
pub with_sysroot: bool,
39+
pub linked_projects: Vec<LinkedProject>,
40+
}
41+
42+
#[derive(Debug, Clone)]
43+
pub enum LinkedProject {
44+
ProjectManifest(ProjectManifest),
45+
JsonProject(JsonProject),
46+
}
47+
48+
impl From<ProjectManifest> for LinkedProject {
49+
fn from(v: ProjectManifest) -> Self {
50+
LinkedProject::ProjectManifest(v)
51+
}
52+
}
53+
54+
impl From<JsonProject> for LinkedProject {
55+
fn from(v: JsonProject) -> Self {
56+
LinkedProject::JsonProject(v)
57+
}
3858
}
3959

4060
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -141,6 +161,7 @@ impl Default for Config {
141161
assist: AssistConfig::default(),
142162
call_info_full: true,
143163
lens: LensConfig::default(),
164+
linked_projects: Vec::new(),
144165
}
145166
}
146167
}

crates/rust-analyzer/src/main_loop.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ use std::{
1212
fmt,
1313
ops::Range,
1414
panic,
15-
path::PathBuf,
1615
sync::Arc,
1716
time::{Duration, Instant},
1817
};
1918

2019
use crossbeam_channel::{never, select, unbounded, RecvError, Sender};
21-
use itertools::Itertools;
2220
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
2321
use lsp_types::{
2422
DidChangeTextDocumentParams, NumberOrString, TextDocumentContentChangeEvent, WorkDoneProgress,
@@ -28,15 +26,15 @@ use lsp_types::{
2826
use ra_flycheck::{CheckTask, Status};
2927
use ra_ide::{Canceled, FileId, LibraryData, LineIndex, SourceRootId};
3028
use ra_prof::profile;
31-
use ra_project_model::{PackageRoot, ProjectManifest, ProjectWorkspace};
29+
use ra_project_model::{PackageRoot, ProjectWorkspace};
3230
use ra_vfs::{VfsFile, VfsTask, Watch};
3331
use relative_path::RelativePathBuf;
3432
use rustc_hash::FxHashSet;
3533
use serde::{de::DeserializeOwned, Serialize};
3634
use threadpool::ThreadPool;
3735

3836
use crate::{
39-
config::{Config, FilesWatcher},
37+
config::{Config, FilesWatcher, LinkedProject},
4038
diagnostics::{to_proto::url_from_path_with_drive_lowercasing, DiagnosticTask},
4139
from_proto,
4240
global_state::{GlobalState, GlobalStateSnapshot},
@@ -70,7 +68,7 @@ impl fmt::Display for LspError {
7068

7169
impl Error for LspError {}
7270

73-
pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) -> Result<()> {
71+
pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
7472
log::info!("initial config: {:#?}", config);
7573

7674
// Windows scheduler implements priority boosts: if thread waits for an
@@ -95,25 +93,24 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
9593
let mut loop_state = LoopState::default();
9694
let mut global_state = {
9795
let workspaces = {
98-
// FIXME: support dynamic workspace loading.
99-
let project_roots = ProjectManifest::discover_all(&ws_roots);
100-
101-
if project_roots.is_empty() && config.notifications.cargo_toml_not_found {
96+
if config.linked_projects.is_empty() && config.notifications.cargo_toml_not_found {
10297
show_message(
10398
lsp_types::MessageType::Error,
104-
format!(
105-
"rust-analyzer failed to discover workspace, no Cargo.toml found, dirs searched: {}",
106-
ws_roots.iter().format_with(", ", |it, f| f(&it.display()))
107-
),
99+
"rust-analyzer failed to discover workspace".to_string(),
108100
&connection.sender,
109101
);
110102
};
111103

112-
project_roots
113-
.into_iter()
104+
config
105+
.linked_projects
106+
.iter()
107+
.filter_map(|project| match project {
108+
LinkedProject::ProjectManifest(it) => Some(it),
109+
LinkedProject::JsonProject(_) => None,
110+
})
114111
.filter_map(|root| {
115112
ra_project_model::ProjectWorkspace::load(
116-
root,
113+
root.clone(),
117114
&config.cargo,
118115
config.with_sysroot,
119116
)

crates/rust-analyzer/tests/heavy_tests/support.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ use serde_json::{to_string_pretty, Value};
1919
use tempfile::TempDir;
2020
use test_utils::{find_mismatch, parse_fixture};
2121

22+
use ra_project_model::ProjectManifest;
2223
use rust_analyzer::{
23-
config::{ClientCapsConfig, Config},
24+
config::{ClientCapsConfig, Config, LinkedProject},
2425
main_loop,
2526
};
2627

@@ -42,7 +43,7 @@ impl<'a> Project<'a> {
4243
self
4344
}
4445

45-
pub fn root(mut self, path: &str) -> Project<'a> {
46+
pub(crate) fn root(mut self, path: &str) -> Project<'a> {
4647
self.roots.push(path.into());
4748
self
4849
}
@@ -74,7 +75,16 @@ impl<'a> Project<'a> {
7475
paths.push((path, entry.text));
7576
}
7677

77-
let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect();
78+
let mut roots =
79+
self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect::<Vec<_>>();
80+
if roots.is_empty() {
81+
roots.push(tmp_dir.path().to_path_buf());
82+
}
83+
let linked_projects = roots
84+
.into_iter()
85+
.map(|it| ProjectManifest::discover_single(&it).unwrap())
86+
.map(LinkedProject::from)
87+
.collect::<Vec<_>>();
7888

7989
let mut config = Config {
8090
client_caps: ClientCapsConfig {
@@ -84,14 +94,15 @@ impl<'a> Project<'a> {
8494
..Default::default()
8595
},
8696
with_sysroot: self.with_sysroot,
97+
linked_projects,
8798
..Config::default()
8899
};
89100

90101
if let Some(f) = &self.config {
91102
f(&mut config)
92103
}
93104

94-
Server::new(tmp_dir, config, roots, paths)
105+
Server::new(tmp_dir, config, paths)
95106
}
96107
}
97108

@@ -109,20 +120,12 @@ pub struct Server {
109120
}
110121

111122
impl Server {
112-
fn new(
113-
dir: TempDir,
114-
config: Config,
115-
roots: Vec<PathBuf>,
116-
files: Vec<(PathBuf, String)>,
117-
) -> Server {
118-
let path = dir.path().to_path_buf();
119-
120-
let roots = if roots.is_empty() { vec![path] } else { roots };
123+
fn new(dir: TempDir, config: Config, files: Vec<(PathBuf, String)>) -> Server {
121124
let (connection, client) = Connection::memory();
122125

123126
let _thread = jod_thread::Builder::new()
124127
.name("test server".to_string())
125-
.spawn(move || main_loop(roots, config, connection).unwrap())
128+
.spawn(move || main_loop(config, connection).unwrap())
126129
.expect("failed to spawn a thread");
127130

128131
let res =

0 commit comments

Comments
 (0)