mirror of
https://github.com/WhatsApp/erlang-language-platform.git
synced 2025-12-23 12:26:48 +00:00
BE: track related info in declarative tests
Some checks are pending
ELP CI / edb (push) Waiting to run
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, true, linux-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, true, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-13, macos-13-x64, x86_64-apple-darwin, true, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-latest, macos-latest-arm, aarch64-apple-darwin, true, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, windows, 26.2, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, true, win32-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, windows, 27.3, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, windows, 28, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
Deploy Website to GitHub Pages / Deploy Website to GitHub Pages (push) Waiting to run
Some checks are pending
ELP CI / edb (push) Waiting to run
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, true, linux-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, true, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-13, macos-13-x64, x86_64-apple-darwin, true, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-latest, macos-latest-arm, aarch64-apple-darwin, true, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, windows, 26.2, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, true, win32-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, windows, 27.3, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, windows, 28, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
Deploy Website to GitHub Pages / Deploy Website to GitHub Pages (push) Waiting to run
Summary: Our declarative tests allow us to add annotations for expected diagnostics, so we can clearly see and check what is generated. But at present there is no way to check any related information for a diagnostic. This diff adds that capability, showing related information together with the FileId and range each refers to. Reviewed By: robertoaloi Differential Revision: D87316965 fbshipit-source-id: ea7db2980b11950c3552befec7b666665ceef84b
This commit is contained in:
parent
dcf4e3a4ff
commit
8efb4fe29c
7 changed files with 54 additions and 2 deletions
|
|
@ -168,6 +168,12 @@ directly in test code:
|
|||
- **Left-margin annotation**: `%%<^^^ text` - Annotation starts at `%%` position
|
||||
instead of first `^`
|
||||
- **Multiline annotations**: Use continuation lines with `%% | next line`
|
||||
- Continuation lines are particularly useful for diagnostics with related information:
|
||||
```erlang
|
||||
foo() -> syntax error oops.
|
||||
%% ^^^^^ error: P1711: syntax error before: error
|
||||
%% | Related info: 0:45-50 function foo/0 undefined
|
||||
```
|
||||
|
||||
#### Example Test Fixture
|
||||
|
||||
|
|
|
|||
|
|
@ -3433,6 +3433,9 @@ baz(1)->4.
|
|||
-spec foo() -> ok.
|
||||
foo( -> ok. %%
|
||||
%% ^ error: W0004: Missing ')'
|
||||
%% | Related info: 0:21-43 function foo/0 undefined
|
||||
%% | Related info: 0:74-79 function foo/0 undefined
|
||||
%% | Related info: 0:82-99 spec for undefined function foo/0
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
@ -3463,6 +3466,7 @@ baz(1)->4.
|
|||
|
||||
foo() -> syntax error oops.
|
||||
%% ^^^^^ error: P1711: syntax error before: error
|
||||
%% | Related info: 0:25-30 function foo/0 undefined
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
@ -3766,6 +3770,7 @@ baz(1)->4.
|
|||
\~"\"\\µA\"" = \~/"\\µA"/
|
||||
X = 3.
|
||||
%% ^ error: P1711: syntax error before: X
|
||||
%% | Related info: 0:32-37 function foo/0 undefined
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ mod tests {
|
|||
foo(0) -> 1;
|
||||
boo(1) -> 2.
|
||||
%% ^^^ 💡 error: P1700: head mismatch 'boo' vs 'foo'
|
||||
%% | Related info: 0:21-24 Mismatched clause name
|
||||
"#,
|
||||
);
|
||||
check_fix(
|
||||
|
|
@ -421,6 +422,7 @@ mod tests {
|
|||
ok;
|
||||
fooX(_X) ->
|
||||
%% ^^^^ 💡 error: P1700: head mismatch 'fooX' vs 'food'
|
||||
%% | Related info: 0:21-25 Mismatched clause name
|
||||
no.
|
||||
|
||||
bar() ->
|
||||
|
|
@ -450,6 +452,7 @@ mod tests {
|
|||
-module(main).
|
||||
foo(0) -> 1;
|
||||
%% ^^^ 💡 error: P1700: head mismatch 'foo' vs 'boo'
|
||||
%% | Related info: 0:37-40 Mismatched clause name
|
||||
boo(1) -> 2;
|
||||
boo(2) -> 3.
|
||||
"#,
|
||||
|
|
@ -478,6 +481,7 @@ mod tests {
|
|||
foo(0) -> 1;
|
||||
foo(1,0) -> 2.
|
||||
%% ^^^^^^^^^^^^^ error: P1700: head arity mismatch 2 vs 1
|
||||
%% | Related info: 0:21-32 Mismatched clause
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
@ -490,6 +494,7 @@ mod tests {
|
|||
foo(2,0) -> 3;
|
||||
foo(0) -> 1;
|
||||
%% ^^^^^^^^^^^ error: P1700: head arity mismatch 1 vs 2
|
||||
%% | Related info: 0:21-34 Mismatched clause
|
||||
foo(1,0) -> 2.
|
||||
"#,
|
||||
);
|
||||
|
|
@ -516,6 +521,7 @@ mod tests {
|
|||
(0) -> ok;
|
||||
A(N) -> ok
|
||||
%% ^ 💡 error: P1700: head mismatch 'A' vs ''
|
||||
%% | Related info: 0:44-53 Mismatched clause name
|
||||
end,
|
||||
F().
|
||||
"#,
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ mod tests {
|
|||
-module(main).
|
||||
-dyalizer({nowarn_function, f/0}).
|
||||
%%% ^^^^^^^^ 💡 error: W0013: misspelled attribute, saw 'dyalizer' but expected 'dialyzer'
|
||||
%%% | Related info: 0:22-30 Misspelled attribute
|
||||
"#,
|
||||
);
|
||||
check_fix(
|
||||
|
|
@ -224,6 +225,7 @@ mod tests {
|
|||
-module(main).
|
||||
-module_doc """
|
||||
%%% ^^^^^^^^^^ 💡 error: W0013: misspelled attribute, saw 'module_doc' but expected 'moduledoc'
|
||||
%%% | Related info: 0:24-34 Misspelled attribute
|
||||
Hola
|
||||
""".
|
||||
"#,
|
||||
|
|
@ -237,6 +239,7 @@ mod tests {
|
|||
-module(main).
|
||||
-docs """
|
||||
%%% ^^^^ 💡 error: W0013: misspelled attribute, saw 'docs' but expected 'doc'
|
||||
%%% | Related info: 0:24-28 Misspelled attribute
|
||||
Hola
|
||||
""".
|
||||
foo() -> ok.
|
||||
|
|
|
|||
|
|
@ -581,6 +581,7 @@ foo() -> ok.
|
|||
%% The following shows up as a wild attribute, which we regard as being used.
|
||||
-defin e(X, 1).
|
||||
%% ^^^^^ 💡 error: W0013: misspelled attribute, saw 'defin' but expected 'define'
|
||||
%% | Related info: 1:82-87 Misspelled attribute
|
||||
|
||||
-def ine(Y, 2).
|
||||
"#,
|
||||
|
|
|
|||
|
|
@ -401,6 +401,23 @@ fn convert_diagnostics_to_annotations(diagnostics: Vec<Diagnostic>) -> Vec<(Text
|
|||
annotation.push_str(&d.code.as_code());
|
||||
annotation.push_str(": ");
|
||||
annotation.push_str(&convert_diagnostic_message(&d));
|
||||
|
||||
// Append related info to the annotation
|
||||
if let Some(related_info) = &d.related_info {
|
||||
// Sort related info alphabetically by message for consistent test output
|
||||
let mut sorted_info = related_info.clone();
|
||||
sorted_info.sort_by(|a, b| a.message.cmp(&b.message));
|
||||
for info in sorted_info {
|
||||
annotation.push_str(&format!(
|
||||
"\nRelated info: {}:{}-{} {}",
|
||||
info.file_id.index(),
|
||||
u32::from(info.range.start()),
|
||||
u32::from(info.range.end()),
|
||||
info.message
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(d.range, annotation)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
|||
|
|
@ -472,6 +472,14 @@ pub fn extract_tags(mut text: &str, tag: &str) -> (Vec<(TextRange, Option<String
|
|||
/// %% | second line
|
||||
/// ```
|
||||
///
|
||||
/// This is useful for representing diagnostics with related information:
|
||||
///
|
||||
/// ```not_rust
|
||||
/// foo() -> syntax error oops.
|
||||
/// %% ^^^^^ error: P1711: syntax error before: error
|
||||
/// %% | Related info: 0:25-30 function foo/0 undefined
|
||||
/// ```
|
||||
///
|
||||
/// Annotations point to the last line that actually was long enough for the
|
||||
/// range, not counting annotations themselves. So overlapping annotations are
|
||||
/// possible:
|
||||
|
|
@ -551,10 +559,16 @@ pub fn extract_annotations(text: &str) -> (Vec<(TextRange, String)>, String) {
|
|||
if !res.is_empty() {
|
||||
offset += annotation_offset;
|
||||
this_line_annotations.push((offset, res.len() - 1));
|
||||
let &(_, idx) = prev_line_annotations
|
||||
// Try to find a previous annotation at the same offset
|
||||
let idx = if let Some(&(_, idx)) = prev_line_annotations
|
||||
.iter()
|
||||
.find(|&&(off, _idx)| off == offset)
|
||||
.unwrap();
|
||||
{
|
||||
idx
|
||||
} else {
|
||||
// If no exact offset match, append to the most recent annotation
|
||||
res.len() - 1
|
||||
};
|
||||
res[idx].1.push('\n');
|
||||
res[idx].1.push_str(&content);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue