Skip to content

Commit a2057aa

Browse files
committed
Prepare lookup of flags using old, deprecated names
Still blocked by upstream Bazel-side change before it can actually light up.
1 parent 8250480 commit a2057aa

File tree

5 files changed

+82
-22
lines changed

5 files changed

+82
-22
lines changed

README.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,23 @@ Backlog items:
6363
* Diagnose
6464
* ✔ unknown flags
6565
* ✔ allow custom setting flags (`--//my/package:setting` and `--no//my/package:setting`)
66-
* repeated flags
67-
* abbreviated flag names; prefer non-abbreviated flags
66+
* ✔ abbreviated flag names; prefer non-abbreviated flags
67+
* when using an old, deprecated name (blocked on [up-stream Bazel change](https://github.com/bazelbuild/bazel/pull/25169))
6868
* ✔ diagnose deprecated flags
6969
* ✔ diagnose missing `import`ed files
7070
* ✔ configs on `startup`, `import`, `try-import`
7171
* ✔ empty config name
7272
* ✔ config name which doesn't match `[a-z_\-]+` (or similar)
73+
* repeated flags
7374
* offer fix-it:
74-
* to remove repeated flags
7575
* to replace abbreviated flags by non-abbreviated flags
7676
* to remove deprecated no-op flags
77-
* to fix config-name-related issues
78-
* Hover
77+
* to remove repeated flags
78+
* Hover
7979
* ✔ Show documentation of flags on hover
8080
* ✔ Correctly escape `<>` in Markdown (e.g. problematic in the documentation for `--config`)
8181
* Link to flag documentation in hovers
82+
* Expose default value, value description (blocked on [up-stream Bazel change](https://github.com/bazelbuild/bazel/pull/25169))
8283
* ✔ Show documentation for commands on hover
8384
* Autocomplete
8485
* ✔ auto complete command names
@@ -109,8 +110,6 @@ Backlog items:
109110
* write documentation, including explanation of different styles
110111
* ✔ link file names for `import` & `try-import`
111112
* Rename functionality for config names
112-
* Bazel-side changes:
113-
* expose default value, value description and old names and deprecation messages
114113
* Go to Reference:
115-
* other usages of config name
116-
* find other usages of same flag
114+
* Other usages of config name
115+
* Find other usages of same flag

src/bazel_flags.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ pub struct BazelFlags {
4747
pub flags_by_abbreviation: HashMap<String, usize>,
4848
}
4949

50+
#[derive(Clone, Debug, PartialEq, Eq)]
51+
pub enum FlagLookupType {
52+
Normal,
53+
Abbreviation,
54+
OldName,
55+
}
56+
5057
impl BazelFlags {
5158
pub fn from_flags(flags: Vec<FlagInfo>, bazel_version: Option<&str>) -> BazelFlags {
5259
// Index the flags from the protobuf description
@@ -59,11 +66,14 @@ impl BazelFlags {
5966
{
6067
continue;
6168
}
69+
flags_by_name.insert(f.name.clone(), i);
70+
if let Some(old_name) = &f.old_name {
71+
flags_by_name.insert(old_name.clone(), i);
72+
}
6273
for c in &f.commands {
6374
let list = flags_by_commands.entry(c.clone()).or_default();
6475
list.push(i);
6576
}
66-
flags_by_name.insert(f.name.clone(), i);
6777
if let Some(abbreviation) = &f.abbreviation {
6878
flags_by_abbreviation.insert(abbreviation.clone(), i);
6979
}
@@ -98,7 +108,7 @@ impl BazelFlags {
98108
}
99109
}
100110

101-
pub fn get_by_invocation(&self, s: &str) -> Option<&FlagInfo> {
111+
pub fn get_by_invocation(&self, s: &str) -> Option<(FlagLookupType, &FlagInfo)> {
102112
let stripped = s.strip_suffix('=').unwrap_or(s);
103113
// Long names
104114
if let Some(long_name) = stripped.strip_prefix("--") {
@@ -107,10 +117,17 @@ impl BazelFlags {
107117
}
108118
// Strip the `no` prefix, if any
109119
let stripped_no = long_name.strip_prefix("no").unwrap_or(long_name);
110-
return self
111-
.flags_by_name
112-
.get(stripped_no)
113-
.map(|i| self.flags.get(*i).unwrap());
120+
return self.flags_by_name.get(stripped_no).map(|i| {
121+
let flag = self.flags.get(*i).unwrap();
122+
let old_name =
123+
flag.old_name.is_some() && flag.old_name.as_ref().unwrap() == stripped_no;
124+
let lookup_mode = if old_name {
125+
FlagLookupType::OldName
126+
} else {
127+
FlagLookupType::Normal
128+
};
129+
(lookup_mode, flag)
130+
});
114131
}
115132
// Short names
116133
if let Some(abbreviation) = stripped.strip_prefix('-') {
@@ -120,7 +137,7 @@ impl BazelFlags {
120137
return self
121138
.flags_by_abbreviation
122139
.get(abbreviation)
123-
.map(|i| self.flags.get(*i).unwrap());
140+
.map(|i| (FlagLookupType::Abbreviation, self.flags.get(*i).unwrap()));
124141
}
125142
None
126143
}
@@ -210,7 +227,7 @@ pub fn combine_key_value_flags(lines: &mut [crate::parser::Line], bazel_flags: &
210227
new_flags.push(
211228
|| -> Option<Spanned<String>> {
212229
let flag_name = &flag.name.as_ref()?.0;
213-
let info = bazel_flags.get_by_invocation(flag_name)?;
230+
let (_, info) = bazel_flags.get_by_invocation(flag_name)?;
214231
if flag.value.is_some() {
215232
return flag.value.clone();
216233
} else if info.requires_value() {
@@ -321,6 +338,7 @@ fn test_flags() {
321338
assert_eq!(
322339
preemptible_info
323340
.unwrap()
341+
.1
324342
.commands
325343
.iter()
326344
.map(|n| n.to_string())
@@ -330,8 +348,16 @@ fn test_flags() {
330348

331349
// Supports both short and long forms
332350
assert_eq!(
333-
flags.get_by_invocation("-k"),
334-
flags.get_by_invocation("--keep_going")
351+
flags.get_by_invocation("-k").unwrap().0,
352+
FlagLookupType::Abbreviation
353+
);
354+
assert_eq!(
355+
flags.get_by_invocation("--keep_going").unwrap().0,
356+
FlagLookupType::Normal
357+
);
358+
assert_eq!(
359+
flags.get_by_invocation("-k").unwrap().1,
360+
flags.get_by_invocation("--keep_going").unwrap().1
335361
);
336362

337363
// The `remote_cache` is valid for at least one command. Hence, it should be in `common`.

src/bazel_flags_proto.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@ pub struct FlagInfo {
3838
/// e.g. --jobs=100.
3939
#[prost(bool, optional, tag = "10")]
4040
pub requires_value: ::core::option::Option<bool>,
41+
// The old, deprecated name for this option, without leading dashes.
42+
// TODO: Fix the tag number after the upstream Bazel change got merged.
43+
// See https://github.com/bazelbuild/bazel/pull/25169
44+
#[prost(string, optional, tag = "99999")]
45+
pub old_name: Option<::prost::alloc::string::String>,
4146
/// EXTENSION: List of Bazel versions this flag applies to
4247
#[prost(string, repeated, tag = "999")]
4348
pub bazel_versions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4449
}
50+
4551
#[derive(Clone, PartialEq, ::prost::Message)]
4652
pub struct FlagCollection {
4753
#[prost(message, repeated, tag = "1")]

src/diagnostic.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use ropey::Rope;
66
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, DiagnosticTag};
77

88
use crate::{
9-
bazel_flags::BazelFlags, file_utils::resolve_bazelrc_path, lsp_utils::range_to_lsp,
9+
bazel_flags::{BazelFlags, FlagLookupType},
10+
file_utils::resolve_bazelrc_path,
11+
lsp_utils::range_to_lsp,
1012
parser::Line,
1113
};
1214

@@ -62,7 +64,9 @@ fn diagnostics_for_flags(rope: &Rope, line: &Line, bazel_flags: &BazelFlags) ->
6264
.any(|prefix| name.0.starts_with(prefix))
6365
{
6466
// Don't diagnose custom settings at all
65-
} else if let Some(flag_description) = bazel_flags.get_by_invocation(&name.0) {
67+
} else if let Some((lookup_type, flag_description)) =
68+
bazel_flags.get_by_invocation(&name.0)
69+
{
6670
// Diagnose flags used on the wrong command
6771
if !flag_description.supports_command(command) {
6872
diagnostics.push(Diagnostic::new_simple(
@@ -84,7 +88,27 @@ fn diagnostics_for_flags(rope: &Rope, line: &Line, bazel_flags: &BazelFlags) ->
8488
range: range_to_lsp(rope, &name.1).unwrap(),
8589
message: format!("The flag {:?} is a no-op.", name.0),
8690
severity: Some(DiagnosticSeverity::WARNING),
91+
..Default::default()
92+
});
93+
} else if lookup_type == FlagLookupType::OldName {
94+
diagnostics.push(Diagnostic {
95+
range: range_to_lsp(rope, &name.1).unwrap(),
96+
message: format!(
97+
"The flag {:?} was renamed to \"--{}\".",
98+
name.0, flag_description.name
99+
),
87100
tags: Some(vec![DiagnosticTag::DEPRECATED]),
101+
severity: Some(DiagnosticSeverity::WARNING),
102+
..Default::default()
103+
});
104+
} else if lookup_type == FlagLookupType::Abbreviation {
105+
diagnostics.push(Diagnostic {
106+
range: range_to_lsp(rope, &name.1).unwrap(),
107+
message: format!(
108+
"Use the full name {:?} instead of its abbreviation.",
109+
flag_description.name
110+
),
111+
severity: Some(DiagnosticSeverity::WARNING),
88112
..Default::default()
89113
});
90114
}
@@ -351,6 +375,11 @@ fn test_diagnose_flags() {
351375
diagnose_string("common --incompatible_override_toolchain_transition"),
352376
vec!["The flag \"--incompatible_override_toolchain_transition\" is a no-op."]
353377
);
378+
// Diagnose abbreviated flag names
379+
assert_eq!(
380+
diagnose_string("build -k"),
381+
vec!["Use the full name \"keep_going\" instead of its abbreviation."]
382+
);
354383

355384
// Don't diagnose custom flags
356385
assert_eq!(

src/language_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ impl LanguageServer for Backend {
298298
IndexEntryKind::FlagValue(flag_nr) | IndexEntryKind::FlagName(flag_nr) => {
299299
let line = &doc.indexed_lines.lines[*line_nr];
300300
let flag_name = &line.flags.get(*flag_nr)?.name.as_ref()?.0;
301-
let flag_info = self.bazel_flags.get_by_invocation(flag_name)?;
301+
let (_, flag_info) = self.bazel_flags.get_by_invocation(flag_name)?;
302302
let content = flag_info.get_documentation_markdown();
303303
let contents = HoverContents::Scalar(MarkedString::String(content));
304304
Some(Hover {

0 commit comments

Comments
 (0)