Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints/chaining.rs')
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs107
1 files changed, 97 insertions, 10 deletions
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index cf3149c946..4b06f83971 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -2,13 +2,13 @@
use hir::DisplayTarget;
use ide_db::famous_defs::FamousDefs;
use syntax::{
- Direction, NodeOrToken, SyntaxKind, T,
+ Direction, NodeOrToken, SyntaxKind, T, TextRange,
ast::{self, AstNode},
};
use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind};
-use super::label_of_ty;
+use super::{TypeHintsPlacement, label_of_ty};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -40,13 +40,14 @@ pub(super) fn hints(
// Chaining can be defined as an expression whose next sibling tokens are newline and dot
// Ignoring extra whitespace and comments
- let next = tokens.next()?.kind();
- if next == SyntaxKind::WHITESPACE {
- let mut next_next = tokens.next()?.kind();
- while next_next == SyntaxKind::WHITESPACE {
- next_next = tokens.next()?.kind();
+ let next_token = tokens.next()?;
+ if next_token.kind() == SyntaxKind::WHITESPACE {
+ let newline_token = next_token;
+ let mut next_next = tokens.next()?;
+ while next_next.kind() == SyntaxKind::WHITESPACE {
+ next_next = tokens.next()?;
}
- if next_next == T![.] {
+ if next_next.kind() == T![.] {
let ty = sema.type_of_expr(desc_expr)?.original;
if ty.is_unknown() {
return None;
@@ -58,8 +59,18 @@ pub(super) fn hints(
return None;
}
let label = label_of_ty(famous_defs, config, &ty, display_target)?;
+ let range = {
+ let mut range = expr.syntax().text_range();
+ if config.type_hints_placement == TypeHintsPlacement::EndOfLine {
+ range = TextRange::new(
+ range.start(),
+ newline_token.text_range().start().max(range.end()),
+ );
+ }
+ range
+ };
acc.push(InlayHint {
- range: expr.syntax().text_range(),
+ range,
kind: InlayKind::Chaining,
label,
text_edit: None,
@@ -79,7 +90,7 @@ mod tests {
use ide_db::text_edit::{TextRange, TextSize};
use crate::{
- InlayHintsConfig, fixture,
+ InlayHintsConfig, TypeHintsPlacement, fixture,
inlay_hints::{
LazyProperty,
tests::{DISABLED_CONFIG, TEST_CONFIG, check_expect, check_with_config},
@@ -686,4 +697,80 @@ fn main() {
"#]],
);
}
+
+ #[test]
+ fn chaining_hints_end_of_line_placement() {
+ check_expect(
+ InlayHintsConfig {
+ chaining_hints: true,
+ type_hints_placement: TypeHintsPlacement::EndOfLine,
+ ..DISABLED_CONFIG
+ },
+ r#"
+fn main() {
+ let baz = make()
+ .into_bar()
+ .into_baz();
+}
+
+struct Foo;
+struct Bar;
+struct Baz;
+
+impl Foo {
+ fn into_bar(self) -> Bar { Bar }
+}
+
+impl Bar {
+ fn into_baz(self) -> Baz { Baz }
+}
+
+fn make() -> Foo {
+ Foo
+}
+"#,
+ expect![[r#"
+ [
+ (
+ 26..52,
+ [
+ InlayHintLabelPart {
+ text: "Bar",
+ linked_location: Some(
+ Computed(
+ FileRangeWrapper {
+ file_id: FileId(
+ 0,
+ ),
+ range: 96..99,
+ },
+ ),
+ ),
+ tooltip: "",
+ },
+ ],
+ ),
+ (
+ 26..32,
+ [
+ InlayHintLabelPart {
+ text: "Foo",
+ linked_location: Some(
+ Computed(
+ FileRangeWrapper {
+ file_id: FileId(
+ 0,
+ ),
+ range: 84..87,
+ },
+ ),
+ ),
+ tooltip: "",
+ },
+ ],
+ ),
+ ]
+ "#]],
+ );
+ }
}