Skip to content

Commit 93e50c9

Browse files
committed
Turn root_ratoml into workspace_ratomls
1 parent 7f314c6 commit 93e50c9

File tree

4 files changed

+83
-74
lines changed

4 files changed

+83
-74
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs

Lines changed: 61 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -779,11 +779,8 @@ pub struct Config {
779779
/// Config node whose values apply to **every** Rust project.
780780
user_config: Option<(GlobalLocalConfigInput, ConfigErrors)>,
781781

782-
/// A special file for this session whose path is set to `self.root_path.join("rust-analyzer.toml")`
783-
root_ratoml_path: VfsPath,
784-
785-
/// This file can be used to make global changes while having only a workspace-wide scope.
786-
root_ratoml: Option<(GlobalLocalConfigInput, ConfigErrors)>,
782+
/// TODO : This file can be used to make global changes while having only a workspace-wide scope.
783+
workspace_ratoml_change: FxHashMap<SourceRootId, (GlobalLocalConfigInput, ConfigErrors)>,
787784

788785
/// For every `SourceRoot` there can be at most one RATOML file.
789786
ratoml_files: FxHashMap<SourceRootId, (LocalConfigInput, ConfigErrors)>,
@@ -917,38 +914,44 @@ impl Config {
917914
should_update = true;
918915
}
919916

920-
if let Some(change) = change.root_ratoml_change {
921-
tracing::info!("updating root ra-toml config: {:#}", change);
922-
#[allow(clippy::single_match)]
923-
match toml::from_str(&change) {
924-
Ok(table) => {
917+
if let Some(change) = change.workspace_ratoml_change {
918+
tracing::info!("updating root ra-toml config");
919+
for (source_root_id, (_, text)) in change {
920+
if let Some(text) = text {
925921
let mut toml_errors = vec![];
926-
validate_toml_table(
927-
GlobalLocalConfigInput::FIELDS,
928-
&table,
929-
&mut String::new(),
930-
&mut toml_errors,
931-
);
932-
config.root_ratoml = Some((
933-
GlobalLocalConfigInput::from_toml(table, &mut toml_errors),
934-
ConfigErrors(
935-
toml_errors
936-
.into_iter()
937-
.map(|(a, b)| ConfigErrorInner::Toml { config_key: a, error: b })
938-
.map(Arc::new)
939-
.collect(),
940-
),
941-
));
942-
should_update = true;
943-
}
944-
Err(e) => {
945-
config.root_ratoml = Some((
946-
GlobalLocalConfigInput::from_toml(toml::map::Map::default(), &mut vec![]),
947-
ConfigErrors(vec![ConfigErrorInner::ParseError {
948-
reason: e.message().to_owned(),
922+
match toml::from_str(&text) {
923+
Ok(table) => {
924+
validate_toml_table(
925+
GlobalLocalConfigInput::FIELDS,
926+
&table,
927+
&mut String::new(),
928+
&mut toml_errors,
929+
);
930+
config.workspace_ratoml_change.insert(
931+
source_root_id,
932+
(
933+
GlobalLocalConfigInput::from_toml(table, &mut toml_errors),
934+
ConfigErrors(
935+
toml_errors
936+
.into_iter()
937+
.map(|(a, b)| ConfigErrorInner::Toml {
938+
config_key: a,
939+
error: b,
940+
})
941+
.map(Arc::new)
942+
.collect(),
943+
),
944+
),
945+
);
946+
should_update = true;
947+
}
948+
Err(e) => {
949+
config.validation_errors.0.push(
950+
ConfigErrorInner::ParseError { reason: e.message().to_owned() }
951+
.into(),
952+
);
949953
}
950-
.into()]),
951-
));
954+
}
952955
}
953956
}
954957
}
@@ -958,7 +961,6 @@ impl Config {
958961
if let Some(text) = text {
959962
let mut toml_errors = vec![];
960963
tracing::info!("updating ra-toml config: {:#}", text);
961-
#[allow(clippy::single_match)]
962964
match toml::from_str(&text) {
963965
Ok(table) => {
964966
validate_toml_table(
@@ -985,16 +987,10 @@ impl Config {
985987
);
986988
}
987989
Err(e) => {
988-
config.root_ratoml = Some((
989-
GlobalLocalConfigInput::from_toml(
990-
toml::map::Map::default(),
991-
&mut vec![],
992-
),
993-
ConfigErrors(vec![ConfigErrorInner::ParseError {
994-
reason: e.message().to_owned(),
995-
}
996-
.into()]),
997-
));
990+
config.validation_errors.0.push(
991+
ConfigErrorInner::ParseError { reason: e.message().to_owned() }
992+
.into(),
993+
);
998994
}
999995
}
1000996
}
@@ -1026,7 +1022,13 @@ impl Config {
10261022
.1
10271023
.0
10281024
.iter()
1029-
.chain(config.root_ratoml.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
1025+
.chain(
1026+
config
1027+
.workspace_ratoml_change
1028+
.values()
1029+
.into_iter()
1030+
.flat_map(|it| it.1 .0.iter()),
1031+
)
10301032
.chain(config.user_config.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
10311033
.chain(config.ratoml_files.values().flat_map(|it| it.1 .0.iter()))
10321034
.chain(config.validation_errors.0.iter())
@@ -1055,8 +1057,8 @@ impl Config {
10551057
#[derive(Default, Debug)]
10561058
pub struct ConfigChange {
10571059
user_config_change: Option<Arc<str>>,
1058-
root_ratoml_change: Option<Arc<str>>,
10591060
client_config_change: Option<serde_json::Value>,
1061+
workspace_ratoml_change: Option<FxHashMap<SourceRootId, (VfsPath, Option<Arc<str>>)>>,
10601062
ratoml_file_change: Option<FxHashMap<SourceRootId, (VfsPath, Option<Arc<str>>)>>,
10611063
source_map_change: Option<Arc<FxHashMap<SourceRootId, SourceRootId>>>,
10621064
}
@@ -1078,9 +1080,15 @@ impl ConfigChange {
10781080
self.user_config_change = content;
10791081
}
10801082

1081-
pub fn change_root_ratoml(&mut self, content: Option<Arc<str>>) {
1082-
assert!(self.root_ratoml_change.is_none()); // Otherwise it is a double write.
1083-
self.root_ratoml_change = content;
1083+
pub fn change_workspace_ratoml(
1084+
&mut self,
1085+
source_root: SourceRootId,
1086+
vfs_path: VfsPath,
1087+
content: Option<Arc<str>>,
1088+
) -> Option<(VfsPath, Option<Arc<str>>)> {
1089+
self.workspace_ratoml_change
1090+
.get_or_insert_with(Default::default)
1091+
.insert(source_root, (vfs_path, content))
10841092
}
10851093

10861094
pub fn change_client_config(&mut self, change: serde_json::Value) {
@@ -1333,11 +1341,6 @@ impl Config {
13331341
// FIXME @alibektas : Temporary solution. I don't think this is right as at some point we may allow users to specify
13341342
// custom USER_CONFIG_PATHs which may also be relative.
13351343
let user_config_path = VfsPath::from(AbsPathBuf::assert(user_config_path));
1336-
let root_ratoml_path = {
1337-
let mut p = root_path.clone();
1338-
p.push("rust-analyzer.toml");
1339-
VfsPath::new_real_path(p.to_string())
1340-
};
13411344

13421345
Config {
13431346
caps: ClientCapabilities::new(caps),
@@ -1352,10 +1355,9 @@ impl Config {
13521355
source_root_parent_map: Arc::new(FxHashMap::default()),
13531356
user_config: None,
13541357
user_config_path,
1355-
root_ratoml: None,
1356-
root_ratoml_path,
13571358
detached_files: Default::default(),
13581359
validation_errors: Default::default(),
1360+
workspace_ratoml_change: Default::default(),
13591361
}
13601362
}
13611363

@@ -1398,10 +1400,6 @@ impl Config {
13981400
&self.root_path
13991401
}
14001402

1401-
pub fn root_ratoml_path(&self) -> &VfsPath {
1402-
&self.root_ratoml_path
1403-
}
1404-
14051403
pub fn caps(&self) -> &ClientCapabilities {
14061404
&self.caps
14071405
}
@@ -3591,7 +3589,7 @@ mod tests {
35913589

35923590
let mut change = ConfigChange::default();
35933591

3594-
change.change_root_ratoml(Some(
3592+
change.change_user_config(Some(
35953593
toml::toml! {
35963594
[cargo.cfgs]
35973595
these = "these"

src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use flycheck::{project_json, FlycheckHandle};
1010
use hir::ChangeWithProcMacros;
1111
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
1212
use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabaseExt};
13+
use itertools::Itertools;
1314
use load_cargo::SourceRootConfig;
1415
use lsp_types::{SemanticTokens, Url};
1516
use nohash_hasher::IntMap;
@@ -22,7 +23,7 @@ use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, Worksp
2223
use rustc_hash::{FxHashMap, FxHashSet};
2324
use tracing::{span, trace, Level};
2425
use triomphe::Arc;
25-
use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs};
26+
use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs, VfsPath};
2627

2728
use crate::{
2829
config::{Config, ConfigChange, ConfigErrors},
@@ -382,26 +383,37 @@ impl GlobalState {
382383
{
383384
let config_change = {
384385
let user_config_path = self.config.user_config_path();
385-
let root_ratoml_path = self.config.root_ratoml_path();
386386
let mut change = ConfigChange::default();
387387
let db = self.analysis_host.raw_database();
388388

389+
// FIXME @alibektas : This is silly. There is abs no reason to use VfsPaths when there is SourceRoots. But how
390+
// do I resolve a "workspace_root" to its corresponding id without having to rely on a cargo.toml's ( or project json etc.) file id?
391+
let workspace_roots = self
392+
.workspaces
393+
.iter()
394+
.map(|ws| VfsPath::from(ws.workspace_root().to_owned()))
395+
.collect_vec();
396+
389397
for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files {
390398
if vfs_path == *user_config_path {
391399
change.change_user_config(Some(db.file_text(file_id)));
392400
continue;
393401
}
394402

395-
if vfs_path == *root_ratoml_path {
396-
change.change_root_ratoml(Some(db.file_text(file_id)));
397-
continue;
398-
}
399-
400403
// If change has been made to a ratoml file that
401404
// belongs to a non-local source root, we will ignore it.
402-
// As it doesn't make sense a users to use external config files.
403405
let sr_id = db.file_source_root(file_id);
404406
let sr = db.source_root(sr_id);
407+
408+
if workspace_roots.contains(&vfs_path) {
409+
change.change_workspace_ratoml(
410+
sr_id,
411+
vfs_path,
412+
Some(db.file_text(file_id)),
413+
);
414+
continue;
415+
}
416+
405417
if !sr.is_library {
406418
if let Some((old_path, old_text)) = change.change_ratoml(
407419
sr_id,
@@ -430,7 +442,7 @@ impl GlobalState {
430442
if should_update {
431443
self.update_configuration(config);
432444
} else {
433-
// No global or client level config was changed. So we can just naively replace config.
445+
// No global or client level config was changed. So we can naively replace config.
434446
self.config = Arc::new(config);
435447
}
436448
}

src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@ impl GlobalState {
541541

542542
watchers.extend(
543543
iter::once(self.config.user_config_path().as_path())
544-
.chain(iter::once(self.config.root_ratoml_path().as_path()))
545544
.chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref)))
546545
.flatten()
547546
.map(|glob_pattern| lsp_types::FileSystemWatcher {

src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ enum Value {
808808
/// Having a ratoml file at the root of a project enables
809809
/// configuring global level configurations as well.
810810
#[test]
811-
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
811+
// #[ignore = "Root ratomls are not being looked for on startup. Fix this."]
812812
fn ratoml_in_root_is_global() {
813813
let server = RatomlTest::new(
814814
vec![

0 commit comments

Comments
 (0)