Skip to content

Commit 73df43f

Browse files
committed
Implement old to new config patching
1 parent 291f94e commit 73df43f

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

crates/rust-analyzer/src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ use crate::{
3535
lsp_ext::{self, supports_utf8, WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope},
3636
};
3737

38+
mod patch_old_style;
39+
3840
// Conventions for configuration keys to preserve maximal extendability without breakage:
3941
// - Toggles (be it binary true/false or with more options in-between) should almost always suffix as `_enable`
4042
// This has the benefit of namespaces being extensible, and if the suffix doesn't fit later it can be changed without breakage.
@@ -592,6 +594,7 @@ impl Config {
592594
.into_iter()
593595
.map(AbsPathBuf::assert)
594596
.collect();
597+
patch_old_style::patch_json_for_outdated_configs(&mut json);
595598
self.data = ConfigData::from_json(json, &mut errors);
596599
self.snippets.clear();
597600
for (name, def) in self.data.completion_snippets_custom.iter() {
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//! See [`patch_json_for_outdated_configs`]
2+
use serde_json::{json, Value};
3+
4+
/// This function patches the json config to the new expected keys.
5+
/// That is we try to load old known config keys here and convert them to the new ones.
6+
/// See https://github.com/rust-lang/rust-analyzer/pull/12010
7+
pub(super) fn patch_json_for_outdated_configs(json: &mut Value) {
8+
let copy = json.clone();
9+
10+
macro_rules! patch {
11+
($(
12+
$($src:ident).+ -> $($dst:ident).+ ;
13+
)+) => { $(
14+
if let Some(it) = copy.pointer(concat!($("/", stringify!($src)),+)).cloned() {
15+
let mut last = it;
16+
for segment in [$(stringify!($dst)),+].into_iter().rev() {
17+
last = Value::Object(serde_json::Map::from_iter(std::iter::once((segment.to_string(), last))));
18+
}
19+
20+
merge(json, last);
21+
}
22+
)+ };
23+
}
24+
25+
patch! {
26+
assist.allowMergingIntoGlobImports -> imports.merge.glob;
27+
assist.exprFillDefault -> assist.expressionFillDefault;
28+
assist.importEnforceGranularity -> imports.granularity.enforce;
29+
assist.importGranularity -> imports.granularity.group;
30+
assist.importMergeBehavior -> imports.granularity.group;
31+
assist.importMergeBehaviour -> imports.granularity.group;
32+
assist.importGroup -> imports.group.enable;
33+
assist.importPrefix -> imports.prefix;
34+
cache.warmup -> primeCaches.enable;
35+
cargo.loadOutDirsFromCheck -> cargo.buildScripts.enable;
36+
cargo.runBuildScripts -> cargo.runBuildScripts.overrideCommand;
37+
cargo.runBuildScriptsCommand -> cargo.runBuildScripts.overrideCommand;
38+
cargo.useRustcWrapperForBuildScripts -> cargo.runBuildScripts.useRustcWrapper;
39+
completion.snippets -> completion.snippets.custom;
40+
diagnostics.enableExperimental -> diagnostics.experimental.enable;
41+
experimental.procAttrMacros -> procMacro.attributes.enable;
42+
highlighting.strings -> semanticHighlighting.strings.enable;
43+
highlightRelated.breakPoints -> semanticHighlighting.breakPoints.enable;
44+
highlightRelated.exitPoints -> semanticHighlighting.exitPoints.enable;
45+
highlightRelated.yieldPoints -> semanticHighlighting.yieldPoints.enable;
46+
highlightRelated.references -> semanticHighlighting.references.enable;
47+
hover.documentation -> hover.documentation.enable;
48+
hover.linksInHover -> hover.links.enable;
49+
hoverActions.linksInHover -> hover.links.enable;
50+
hoverActions.debug -> hoverActions.debug.enable;
51+
hoverActions.enable -> hoverActions.enable.enable;
52+
hoverActions.gotoTypeDef -> hoverActions.gotoTypeDef.enable;
53+
hoverActions.implementations -> hoverActions.implementations.enable;
54+
hoverActions.references -> hoverActions.references.enable;
55+
hoverActions.run -> hoverActions.run.enable;
56+
inlayHints.chainingHints -> inlayHints.chainingHints.enable;
57+
inlayHints.closureReturnTypeHints -> inlayHints.closureReturnTypeHints.enable;
58+
inlayHints.hideNamedConstructorHints -> inlayHints.typeHints.hideNamedConstructorHints;
59+
inlayHints.parameterHints -> inlayHints.parameterHints.enable;
60+
inlayHints.reborrowHints -> inlayHints.reborrowHints.enable;
61+
inlayHints.typeHints -> inlayHints.typeHints.enable;
62+
lruCapacity -> lru.capacity;
63+
runnables.cargoExtraArgs -> runnables.extraArgs ;
64+
runnables.overrideCargo -> runnables.command ;
65+
rustcSource -> rustc.source;
66+
rustfmt.enableRangeFormatting -> rustfmt.rangeFormatting.enable;
67+
}
68+
69+
// callInfo_full -> signatureInfo_detail, signatureInfo_documentation_enable
70+
if let Some(Value::Bool(b)) = copy.pointer("/callInfo/full") {
71+
let sig_info = match b {
72+
true => json!({ "signatureInfo": {
73+
"documentation": {"enable": true}},
74+
"detail": "full"
75+
}),
76+
false => json!({ "signatureInfo": {
77+
"documentation": {"enable": false}},
78+
"detail": "parameters"
79+
}),
80+
};
81+
merge(json, sig_info);
82+
}
83+
84+
// cargo_allFeatures, cargo_features -> cargo_features
85+
if let Some(Value::Bool(true)) = copy.pointer("/cargo/allFeatures") {
86+
merge(json, json!({ "cargo": { "features": "all" } }));
87+
}
88+
89+
// checkOnSave_allFeatures, checkOnSave_features -> checkOnSave_features
90+
if let Some(Value::Bool(true)) = copy.pointer("/checkOnSave/allFeatures") {
91+
merge(json, json!({ "checkOnSave": { "features": "all" } }));
92+
}
93+
94+
// completion_addCallArgumentSnippets completion_addCallParenthesis -> completion_callable_snippets
95+
let res = match (
96+
copy.pointer("/completion/addCallArgumentSnippets"),
97+
copy.pointer("/completion/addCallParenthesis"),
98+
) {
99+
(Some(Value::Bool(true)), Some(Value::Bool(true))) => json!("fill_arguments"),
100+
(Some(Value::Bool(true)), _) => json!("add_parentheses"),
101+
(_, _) => json!(null),
102+
};
103+
merge(json, json!({ "completion": { "callable": {"snippets": res }} }));
104+
}
105+
106+
fn merge(dst: &mut Value, src: Value) {
107+
match (dst, src) {
108+
(Value::Object(dst), Value::Object(src)) => {
109+
for (k, v) in src {
110+
merge(dst.entry(k).or_insert(v.clone()), v)
111+
}
112+
}
113+
(dst, src) => *dst = src,
114+
}
115+
}

0 commit comments

Comments
 (0)