Skip to content

Commit 9c506a9

Browse files
committed
Start building the tree construction
1 parent 7c5f33c commit 9c506a9

File tree

1 file changed

+70
-10
lines changed
  • crates/rust-analyzer/src/config

1 file changed

+70
-10
lines changed

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

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,47 @@ pub enum ConfigTreeError {
2424
/// Some rust-analyzer.toml files have changed, and/or the LSP client sent a new configuration.
2525
pub struct ConfigChanges {
2626
ra_toml_changes: Vec<vfs::ChangedFile>,
27+
xdg_config_change: Option<Arc<ConfigInput>>,
2728
client_change: Option<Arc<ConfigInput>>,
29+
parent_changes: Vec<ConfigParentChange>,
30+
}
31+
32+
pub struct ConfigParentChange {
33+
/// The config node in question
34+
pub node: FileId,
35+
pub parent: ConfigParent,
36+
}
37+
38+
pub enum ConfigParent {
39+
/// The node is now a root in its own right, but still inherits from the config in XDG_CONFIG_HOME
40+
/// etc
41+
UserDefault,
42+
/// The node is now a child of another rust-analyzer.toml. Even if that one is a non-existent
43+
/// file, it's fine.
44+
///
45+
///
46+
/// ```ignore,text
47+
/// /project_root/
48+
/// rust-analyzer.toml
49+
/// crate_a/
50+
/// crate_b/
51+
/// rust-analyzer.toml
52+
///
53+
/// ```
54+
///
55+
/// ```ignore
56+
/// // imagine set_file_contents = vfs.set_file_contents() and then get the vfs.file_id()
57+
///
58+
/// let root = vfs.set_file_contents("/project_root/rust-analyzer.toml", Some("..."));
59+
/// let crate_a = vfs.set_file_contents("/project_root/crate_a/rust-analyzer.toml", None);
60+
/// let crate_b = vfs.set_file_contents("/project_root/crate_a/crate_b/rust-analyzer.toml", Some("..."));
61+
/// let config_parent_changes = [
62+
/// ConfigParentChange { node: root, parent: ConfigParent::UserDefault },
63+
/// ConfigParentChange { node: crate_a, parent: ConfigParent::Parent(root) },
64+
/// ConfigParentChange { node: crate_b, parent: ConfigParent::Parent(crate_a) }
65+
/// ];
66+
/// ```
67+
Parent(FileId),
2868
}
2969

3070
impl ConcurrentConfigTree {
@@ -56,13 +96,15 @@ slotmap::new_key_type! {
5696

5797
struct ConfigNode {
5898
src: ConfigSource,
99+
// TODO: make option
59100
input: Arc<ConfigInput>,
60101
computed: ComputedIdx,
61102
}
62103

63104
struct ConfigTree {
64105
tree: indextree::Arena<ConfigNode>,
65-
client_config: NodeId,
106+
client_config: Arc<ConfigInput>,
107+
xdg_config_node_id: NodeId,
66108
ra_file_id_map: FxHashMap<FileId, NodeId>,
67109
computed: SlotMap<ComputedIdx, Option<Arc<LocalConfigData>>>,
68110
}
@@ -98,15 +140,24 @@ fn parse_toml(
98140
}
99141

100142
impl ConfigTree {
101-
fn new() -> Self {
143+
fn new(xdg_config_file_id: FileId) -> Self {
102144
let mut tree = indextree::Arena::new();
103145
let mut computed = SlotMap::default();
104-
let client_config = tree.new_node(ConfigNode {
105-
src: ConfigSource::ClientConfig,
146+
let mut ra_file_id_map = FxHashMap::default();
147+
let xdg_config = tree.new_node(ConfigNode {
148+
src: ConfigSource::RaToml(xdg_config_file_id),
106149
input: Arc::new(ConfigInput::default()),
107150
computed: computed.insert(Option::<Arc<LocalConfigData>>::None),
108151
});
109-
Self { client_config, ra_file_id_map: FxHashMap::default(), tree, computed }
152+
ra_file_id_map.insert(xdg_config_file_id, xdg_config);
153+
154+
Self {
155+
client_config: Arc::new(Default::default()),
156+
xdg_config_node_id: xdg_config,
157+
ra_file_id_map,
158+
tree,
159+
computed,
160+
}
110161
}
111162

112163
fn read_only(&self, file_id: FileId) -> Result<Option<Arc<LocalConfigData>>, ConfigTreeError> {
@@ -205,18 +256,27 @@ impl ConfigTree {
205256

206257
fn apply_changes(
207258
&mut self,
208-
changes: ConfigChanges,
259+
mut changes: ConfigChanges,
209260
vfs: &Vfs,
210261
errors: &mut Vec<ConfigTreeError>,
211262
) {
212263
let mut scratch_errors = Vec::new();
213-
let ConfigChanges { client_change, ra_toml_changes } = changes;
264+
let ConfigChanges { client_change, ra_toml_changes, xdg_config_change, parent_changes } =
265+
changes;
266+
214267
if let Some(change) = client_change {
215-
let node =
216-
self.tree.get_mut(self.client_config).expect("client_config node should exist");
268+
self.client_config = change;
269+
}
270+
271+
if let Some(change) = xdg_config_change {
272+
let node = self
273+
.tree
274+
.get_mut(self.xdg_config_node_id)
275+
.expect("client_config node should exist");
217276
node.get_mut().input = change;
218-
self.invalidate_subtree(self.client_config);
277+
self.invalidate_subtree(self.xdg_config_node_id);
219278
}
279+
220280
for change in ra_toml_changes {
221281
// turn and face the strain
222282
match change.change_kind {

0 commit comments

Comments
 (0)