mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Simplify most of the inlay hints tests
This commit is contained in:
parent
0954d31bee
commit
442c13ba17
2 changed files with 199 additions and 631 deletions
|
@ -3,7 +3,7 @@ use ra_ide_db::RootDatabase;
|
|||
use ra_prof::profile;
|
||||
use ra_syntax::{
|
||||
ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner},
|
||||
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, TextRange,
|
||||
match_ast, Direction, NodeOrToken, SmolStr, SyntaxKind, TextRange, T,
|
||||
};
|
||||
|
||||
use crate::{FileId, FunctionSignature};
|
||||
|
@ -112,7 +112,7 @@ fn get_chaining_hints(
|
|||
// Ignoring extra whitespace and comments
|
||||
let next = tokens.next()?.kind();
|
||||
let next_next = tokens.next()?.kind();
|
||||
if next == SyntaxKind::WHITESPACE && next_next == SyntaxKind::DOT {
|
||||
if next == SyntaxKind::WHITESPACE && next_next == T![.] {
|
||||
let ty = sema.type_of_expr(&expr)?;
|
||||
if ty.is_unknown() {
|
||||
return None;
|
||||
|
@ -345,583 +345,245 @@ fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::inlay_hints::InlayHintsConfig;
|
||||
use insta::assert_debug_snapshot;
|
||||
use test_utils::extract_annotations;
|
||||
|
||||
use crate::mock_analysis::single_file;
|
||||
use crate::{inlay_hints::InlayHintsConfig, mock_analysis::single_file};
|
||||
|
||||
fn check(ra_fixture: &str) {
|
||||
check_with_config(ra_fixture, InlayHintsConfig::default());
|
||||
}
|
||||
|
||||
fn check_with_config(ra_fixture: &str, config: InlayHintsConfig) {
|
||||
let (analysis, file_id) = single_file(ra_fixture);
|
||||
let expected = extract_annotations(&*analysis.file_text(file_id).unwrap());
|
||||
let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap();
|
||||
let actual =
|
||||
inlay_hints.into_iter().map(|it| (it.range, it.label.to_string())).collect::<Vec<_>>();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn param_hints_only() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
fn foo(a: i32, b: i32) -> i32 { a + b }
|
||||
fn main() {
|
||||
let _x = foo(4, 4);
|
||||
}"#,
|
||||
let _x = foo(
|
||||
4,
|
||||
//^ a
|
||||
4,
|
||||
//^ b
|
||||
);
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: true, type_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 69..70,
|
||||
kind: ParameterHint,
|
||||
label: "a",
|
||||
}"#,
|
||||
InlayHintsConfig {
|
||||
parameter_hints: true,
|
||||
type_hints: false,
|
||||
chaining_hints: false,
|
||||
max_length: None,
|
||||
},
|
||||
InlayHint {
|
||||
range: 72..73,
|
||||
kind: ParameterHint,
|
||||
label: "b",
|
||||
},
|
||||
]
|
||||
"###);
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hints_disabled() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
fn foo(a: i32, b: i32) -> i32 { a + b }
|
||||
fn main() {
|
||||
let _x = foo(4, 4);
|
||||
}"#,
|
||||
InlayHintsConfig {
|
||||
type_hints: false,
|
||||
parameter_hints: false,
|
||||
chaining_hints: false,
|
||||
max_length: None,
|
||||
},
|
||||
);
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: false, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"[]"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_hints_only() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
fn foo(a: i32, b: i32) -> i32 { a + b }
|
||||
fn main() {
|
||||
let _x = foo(4, 4);
|
||||
//^^ i32
|
||||
}"#,
|
||||
);
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: true, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 60..62,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
InlayHintsConfig {
|
||||
type_hints: true,
|
||||
parameter_hints: false,
|
||||
chaining_hints: false,
|
||||
max_length: None,
|
||||
},
|
||||
]
|
||||
"###);
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_generic_types_should_not_be_displayed() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
struct Test<K, T = u8> {
|
||||
k: K,
|
||||
t: T,
|
||||
}
|
||||
struct Test<K, T = u8> { k: K, t: T }
|
||||
|
||||
fn main() {
|
||||
let zz = Test { t: 23u8, k: 33 };
|
||||
//^^ Test<i32>
|
||||
let zz_ref = &zz;
|
||||
//^^^^^^ &Test<i32>
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 68..70,
|
||||
kind: TypeHint,
|
||||
label: "Test<i32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 106..112,
|
||||
kind: TypeHint,
|
||||
label: "&Test<i32>",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_statement() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
#[derive(PartialEq)]
|
||||
enum CustomOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
enum Option<T> { None, Some(T) }
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct Test {
|
||||
a: CustomOption<u32>,
|
||||
b: u8,
|
||||
}
|
||||
struct Test { a: Option<u32>, b: u8 }
|
||||
|
||||
fn main() {
|
||||
struct InnerStruct {}
|
||||
|
||||
let test = 54;
|
||||
//^^^^ i32
|
||||
let test: i32 = 33;
|
||||
let mut test = 33;
|
||||
//^^^^^^^^ i32
|
||||
let _ = 22;
|
||||
let test = "test";
|
||||
//^^^^ &str
|
||||
let test = InnerStruct {};
|
||||
|
||||
let test = vec![222];
|
||||
let test: Vec<_> = (0..3).collect();
|
||||
let test = (0..3).collect::<Vec<i128>>();
|
||||
let test = (0..3).collect::<Vec<_>>();
|
||||
|
||||
let mut test = Vec::new();
|
||||
test.push(333);
|
||||
let test = unresolved();
|
||||
|
||||
let test = (42, 'a');
|
||||
let (a, (b, c, (d, e), f)) = (2, (3, 4, (6.6, 7.7), 5));
|
||||
//^^^^ (i32, char)
|
||||
let (a, (b, (c,)) = (2, (3, (9.2,));
|
||||
//^ i32 ^ i32 ^ f64
|
||||
let &x = &92;
|
||||
//^ i32
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 192..196,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 235..243,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 274..278,
|
||||
kind: TypeHint,
|
||||
label: "&str",
|
||||
},
|
||||
InlayHint {
|
||||
range: 538..542,
|
||||
kind: TypeHint,
|
||||
label: "(i32, char)",
|
||||
},
|
||||
InlayHint {
|
||||
range: 565..566,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 569..570,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 572..573,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 576..577,
|
||||
kind: TypeHint,
|
||||
label: "f64",
|
||||
},
|
||||
InlayHint {
|
||||
range: 579..580,
|
||||
kind: TypeHint,
|
||||
label: "f64",
|
||||
},
|
||||
InlayHint {
|
||||
range: 583..584,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 626..627,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closure_parameters() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
fn main() {
|
||||
let mut start = 0;
|
||||
(0..2).for_each(|increment| {
|
||||
start += increment;
|
||||
});
|
||||
//^^^^^^^^^ i32
|
||||
(0..2).for_each(|increment| { start += increment; });
|
||||
//^^^^^^^^^ i32
|
||||
|
||||
let multiply = |a, b, c, d| a * b * c * d;
|
||||
let _: i32 = multiply(1, 2, 3, 4);
|
||||
let multiply =
|
||||
//^^^^^^^^ |…| -> i32
|
||||
| a, b| a * b
|
||||
//^ i32 ^ i32
|
||||
;
|
||||
|
||||
let _: i32 = multiply(1, 2);
|
||||
let multiply_ref = &multiply;
|
||||
//^^^^^^^^^^^^ &|…| -> i32
|
||||
|
||||
let return_42 = || 42;
|
||||
//^^^^^^^^^ || -> i32
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 20..29,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 56..65,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 114..122,
|
||||
kind: TypeHint,
|
||||
label: "|…| -> i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 126..127,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 129..130,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 132..133,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 135..136,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 200..212,
|
||||
kind: TypeHint,
|
||||
label: "&|…| -> i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 235..244,
|
||||
kind: TypeHint,
|
||||
label: "|| -> i32",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_expression() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
fn main() {
|
||||
let mut start = 0;
|
||||
for increment in 0..2 {
|
||||
start += increment;
|
||||
}
|
||||
//^^^^^^^^^ i32
|
||||
for increment in 0..2 { start += increment; }
|
||||
//^^^^^^^^^ i32
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 20..29,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 43..52,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_expr() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
#[derive(PartialEq)]
|
||||
enum CustomOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
enum Option<T> { None, Some(T) }
|
||||
use Option::*;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct Test {
|
||||
a: CustomOption<u32>,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
use CustomOption::*;
|
||||
struct Test { a: Option<u32>, b: u8 }
|
||||
|
||||
fn main() {
|
||||
let test = Some(Test { a: Some(3), b: 1 });
|
||||
//^^^^ Option<Test>
|
||||
if let None = &test {};
|
||||
if let test = &test {};
|
||||
//^^^^ &Option<Test>
|
||||
if let Some(test) = &test {};
|
||||
//^^^^ &Test
|
||||
if let Some(Test { a, b }) = &test {};
|
||||
//^ &Option<u32> ^ &u8
|
||||
if let Some(Test { a: x, b: y }) = &test {};
|
||||
//^ &Option<u32> ^ &u8
|
||||
if let Some(Test { a: Some(x), b: y }) = &test {};
|
||||
//^ &u32 ^ &u8
|
||||
if let Some(Test { a: None, b: y }) = &test {};
|
||||
//^ &u8
|
||||
if let Some(Test { b: y, .. }) = &test {};
|
||||
|
||||
//^ &u8
|
||||
if test == None {}
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 187..191,
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<Test>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 266..270,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<Test>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 299..303,
|
||||
kind: TypeHint,
|
||||
label: "&Test",
|
||||
},
|
||||
InlayHint {
|
||||
range: 340..341,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 343..344,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 386..387,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 392..393,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 440..441,
|
||||
kind: TypeHint,
|
||||
label: "&u32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 447..448,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 499..500,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 542..543,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn while_expr() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
#[derive(PartialEq)]
|
||||
enum CustomOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
enum Option<T> { None, Some(T) }
|
||||
use Option::*;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct Test {
|
||||
a: CustomOption<u32>,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
use CustomOption::*;
|
||||
struct Test { a: Option<u32>, b: u8 }
|
||||
|
||||
fn main() {
|
||||
let test = Some(Test { a: Some(3), b: 1 });
|
||||
while let None = &test {};
|
||||
while let test = &test {};
|
||||
while let Some(test) = &test {};
|
||||
while let Some(Test { a, b }) = &test {};
|
||||
while let Some(Test { a: x, b: y }) = &test {};
|
||||
//^^^^ Option<Test>
|
||||
while let Some(Test { a: Some(x), b: y }) = &test {};
|
||||
while let Some(Test { a: None, b: y }) = &test {};
|
||||
while let Some(Test { b: y, .. }) = &test {};
|
||||
|
||||
while test == None {}
|
||||
//^ &u32 ^ &u8
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 187..191,
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<Test>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 272..276,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<Test>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 308..312,
|
||||
kind: TypeHint,
|
||||
label: "&Test",
|
||||
},
|
||||
InlayHint {
|
||||
range: 352..353,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 355..356,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 401..402,
|
||||
kind: TypeHint,
|
||||
label: "&CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 407..408,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 458..459,
|
||||
kind: TypeHint,
|
||||
label: "&u32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 465..466,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 520..521,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 566..567,
|
||||
kind: TypeHint,
|
||||
label: "&u8",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_arm_list() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
#[derive(PartialEq)]
|
||||
enum CustomOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
enum Option<T> { None, Some(T) }
|
||||
use Option::*;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct Test {
|
||||
a: CustomOption<u32>,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
use CustomOption::*;
|
||||
struct Test { a: Option<u32>, b: u8 }
|
||||
|
||||
fn main() {
|
||||
match Some(Test { a: Some(3), b: 1 }) {
|
||||
None => (),
|
||||
test => (),
|
||||
Some(test) => (),
|
||||
Some(Test { a, b }) => (),
|
||||
Some(Test { a: x, b: y }) => (),
|
||||
//^^^^ Option<Test>
|
||||
Some(Test { a: Some(x), b: y }) => (),
|
||||
Some(Test { a: None, b: y }) => (),
|
||||
Some(Test { b: y, .. }) => (),
|
||||
//^ u32 ^ u8
|
||||
_ => {}
|
||||
}
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 251..255,
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<Test>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 276..280,
|
||||
kind: TypeHint,
|
||||
label: "Test",
|
||||
},
|
||||
InlayHint {
|
||||
range: 309..310,
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 312..313,
|
||||
kind: TypeHint,
|
||||
label: "u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 347..348,
|
||||
kind: TypeHint,
|
||||
label: "CustomOption<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 353..354,
|
||||
kind: TypeHint,
|
||||
label: "u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 393..394,
|
||||
kind: TypeHint,
|
||||
label: "u32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 400..401,
|
||||
kind: TypeHint,
|
||||
label: "u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 444..445,
|
||||
kind: TypeHint,
|
||||
label: "u8",
|
||||
},
|
||||
InlayHint {
|
||||
range: 479..480,
|
||||
kind: TypeHint,
|
||||
label: "u8",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hint_truncation() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
struct Smol<T>(T);
|
||||
|
||||
|
@ -929,52 +591,26 @@ struct VeryLongOuterName<T>(T);
|
|||
|
||||
fn main() {
|
||||
let a = Smol(0u32);
|
||||
//^ Smol<u32>
|
||||
let b = VeryLongOuterName(0usize);
|
||||
//^ VeryLongOuterName<…>
|
||||
let c = Smol(Smol(0u32))
|
||||
//^ Smol<Smol<…>>
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 73..74,
|
||||
kind: TypeHint,
|
||||
label: "Smol<u32>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 97..98,
|
||||
kind: TypeHint,
|
||||
label: "VeryLongOuterName<…>",
|
||||
},
|
||||
InlayHint {
|
||||
range: 136..137,
|
||||
kind: TypeHint,
|
||||
label: "Smol<Smol<…>>",
|
||||
},
|
||||
]
|
||||
"###
|
||||
InlayHintsConfig { max_length: Some(8), ..Default::default() },
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_call_parameter_hint() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check(
|
||||
r#"
|
||||
enum CustomOption<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
use CustomOption::*;
|
||||
enum Option<T> { None, Some(T) }
|
||||
use Option::*;
|
||||
|
||||
struct FileId {}
|
||||
struct SmolStr {}
|
||||
|
||||
impl From<&str> for SmolStr {
|
||||
fn from(_: &str) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct TextRange {}
|
||||
struct SyntaxKind {}
|
||||
struct NavigationTarget {}
|
||||
|
@ -982,18 +618,15 @@ struct NavigationTarget {}
|
|||
struct Test {}
|
||||
|
||||
impl Test {
|
||||
fn method(&self, mut param: i32) -> i32 {
|
||||
param * 2
|
||||
}
|
||||
fn method(&self, mut param: i32) -> i32 { param * 2 }
|
||||
|
||||
fn from_syntax(
|
||||
file_id: FileId,
|
||||
name: SmolStr,
|
||||
focus_range: CustomOption<TextRange>,
|
||||
focus_range: Option<TextRange>,
|
||||
full_range: TextRange,
|
||||
kind: SyntaxKind,
|
||||
docs: CustomOption<String>,
|
||||
description: CustomOption<String>,
|
||||
docs: Option<String>,
|
||||
) -> NavigationTarget {
|
||||
NavigationTarget {}
|
||||
}
|
||||
|
@ -1005,108 +638,35 @@ fn test_func(mut foo: i32, bar: i32, msg: &str, _: i32, last: i32) -> i32 {
|
|||
|
||||
fn main() {
|
||||
let not_literal = 1;
|
||||
//^^^^^^^^^^^ i32
|
||||
let _: i32 = test_func(1, 2, "hello", 3, not_literal);
|
||||
//^ foo ^ bar ^^^^^^^ msg ^^^^^^^^^^^ last
|
||||
let t: Test = Test {};
|
||||
t.method(123);
|
||||
//^^^ param
|
||||
Test::method(&t, 3456);
|
||||
|
||||
//^^ &self ^^^^ param
|
||||
Test::from_syntax(
|
||||
FileId {},
|
||||
//^^^^^^^^^ file_id
|
||||
"impl".into(),
|
||||
//^^^^^^^^^^^^^ name
|
||||
None,
|
||||
//^^^^ focus_range
|
||||
TextRange {},
|
||||
//^^^^^^^^^^^^ full_range
|
||||
SyntaxKind {},
|
||||
//^^^^^^^^^^^^^ kind
|
||||
None,
|
||||
None,
|
||||
//^^^^ docs
|
||||
);
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
|
||||
[
|
||||
InlayHint {
|
||||
range: 797..808,
|
||||
kind: TypeHint,
|
||||
label: "i32",
|
||||
},
|
||||
InlayHint {
|
||||
range: 841..842,
|
||||
kind: ParameterHint,
|
||||
label: "foo",
|
||||
},
|
||||
InlayHint {
|
||||
range: 844..845,
|
||||
kind: ParameterHint,
|
||||
label: "bar",
|
||||
},
|
||||
InlayHint {
|
||||
range: 847..854,
|
||||
kind: ParameterHint,
|
||||
label: "msg",
|
||||
},
|
||||
InlayHint {
|
||||
range: 859..870,
|
||||
kind: ParameterHint,
|
||||
label: "last",
|
||||
},
|
||||
InlayHint {
|
||||
range: 913..916,
|
||||
kind: ParameterHint,
|
||||
label: "param",
|
||||
},
|
||||
InlayHint {
|
||||
range: 936..938,
|
||||
kind: ParameterHint,
|
||||
label: "&self",
|
||||
},
|
||||
InlayHint {
|
||||
range: 940..944,
|
||||
kind: ParameterHint,
|
||||
label: "param",
|
||||
},
|
||||
InlayHint {
|
||||
range: 979..988,
|
||||
kind: ParameterHint,
|
||||
label: "file_id",
|
||||
},
|
||||
InlayHint {
|
||||
range: 998..1011,
|
||||
kind: ParameterHint,
|
||||
label: "name",
|
||||
},
|
||||
InlayHint {
|
||||
range: 1021..1025,
|
||||
kind: ParameterHint,
|
||||
label: "focus_range",
|
||||
},
|
||||
InlayHint {
|
||||
range: 1035..1047,
|
||||
kind: ParameterHint,
|
||||
label: "full_range",
|
||||
},
|
||||
InlayHint {
|
||||
range: 1057..1070,
|
||||
kind: ParameterHint,
|
||||
label: "kind",
|
||||
},
|
||||
InlayHint {
|
||||
range: 1080..1084,
|
||||
kind: ParameterHint,
|
||||
label: "docs",
|
||||
},
|
||||
InlayHint {
|
||||
range: 1094..1098,
|
||||
kind: ParameterHint,
|
||||
label: "description",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn omitted_parameters_hints_heuristics() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
fn map(f: i32) {}
|
||||
fn filter(predicate: i32) {}
|
||||
|
@ -1187,23 +747,16 @@ fn main() {
|
|||
let _: f64 = a.div_euclid(b);
|
||||
let _: f64 = a.abs_sub(b);
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
|
||||
[]
|
||||
"###
|
||||
InlayHintsConfig { max_length: Some(8), ..Default::default() },
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_structs_have_no_type_hints() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
enum CustomResult<T, E> {
|
||||
Ok(T),
|
||||
Err(E),
|
||||
}
|
||||
use CustomResult::*;
|
||||
enum Result<T, E> { Ok(T), Err(E) }
|
||||
use Result::*;
|
||||
|
||||
struct SyntheticSyntax;
|
||||
|
||||
|
@ -1213,11 +766,7 @@ fn main() {
|
|||
Err(SyntheticSyntax) => (),
|
||||
}
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
|
||||
[]
|
||||
"###
|
||||
InlayHintsConfig { max_length: Some(8), ..Default::default() },
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1255,7 +804,7 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn chaining_hints_without_newlines() {
|
||||
let (analysis, file_id) = single_file(
|
||||
check_with_config(
|
||||
r#"
|
||||
struct A(B);
|
||||
impl A { fn into_b(self) -> B { self.0 } }
|
||||
|
@ -1266,8 +815,13 @@ fn main() {
|
|||
fn main() {
|
||||
let c = A(B(C)).into_b().into_c();
|
||||
}"#,
|
||||
InlayHintsConfig {
|
||||
parameter_hints: false,
|
||||
type_hints: false,
|
||||
chaining_hints: true,
|
||||
max_length: None,
|
||||
},
|
||||
);
|
||||
assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"[]"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -11,7 +11,7 @@ pub mod mark;
|
|||
mod fixture;
|
||||
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
convert::{TryFrom, TryInto},
|
||||
env, fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
@ -169,10 +169,9 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
|
|||
for line in lines_with_ends(text) {
|
||||
if let Some(idx) = line.find("//^") {
|
||||
let offset = prev_line_start.unwrap() + TextSize::of(&line[..idx + "//".len()]);
|
||||
let marker_and_data = &line[idx + "//".len()..];
|
||||
let len = marker_and_data.chars().take_while(|&it| it == '^').count();
|
||||
let data = marker_and_data[len..].trim().to_string();
|
||||
res.push((TextRange::at(offset, len.try_into().unwrap()), data))
|
||||
for (line_range, text) in extract_line_annotations(&line[idx + "//".len()..]) {
|
||||
res.push((line_range + offset, text))
|
||||
}
|
||||
}
|
||||
prev_line_start = Some(line_start);
|
||||
line_start += TextSize::of(line);
|
||||
|
@ -180,13 +179,28 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
|
|||
res
|
||||
}
|
||||
|
||||
fn extract_line_annotations(mut line: &str) -> Vec<(TextRange, String)> {
|
||||
let mut res = Vec::new();
|
||||
let mut offset: TextSize = 0.into();
|
||||
while !line.is_empty() {
|
||||
let len = line.chars().take_while(|&it| it == '^').count();
|
||||
assert!(len > 0);
|
||||
let range = TextRange::at(offset, len.try_into().unwrap());
|
||||
let next = line[len..].find('^').map_or(line.len(), |it| it + len);
|
||||
res.push((range, line[len..][..next - len].trim().to_string()));
|
||||
line = &line[next..];
|
||||
offset += TextSize::try_from(next).unwrap();
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_annotations() {
|
||||
let text = stdx::trim_indent(
|
||||
r#"
|
||||
fn main() {
|
||||
let x = 92;
|
||||
//^ def
|
||||
let (x, y) = (9, 2);
|
||||
//^ def ^ def
|
||||
zoo + 1
|
||||
} //^^^ i32
|
||||
"#,
|
||||
|
@ -195,7 +209,7 @@ fn main() {
|
|||
.into_iter()
|
||||
.map(|(range, ann)| (&text[range], ann))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(res, vec![("x", "def".into()), ("zoo", "i32".into()),]);
|
||||
assert_eq!(res, vec![("x", "def".into()), ("y", "def".into()), ("zoo", "i32".into()),]);
|
||||
}
|
||||
|
||||
// Comparison functionality borrowed from cargo:
|
||||
|
|
Loading…
Reference in a new issue