Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints/adjustment.rs')
| -rw-r--r-- | crates/ide/src/inlay_hints/adjustment.rs | 111 |
1 files changed, 97 insertions, 14 deletions
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 367bd2f661..47e854e4bd 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -11,7 +11,7 @@ use syntax::{ ted, }; -use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind}; +use crate::{AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -40,8 +40,8 @@ pub(super) fn hints( let desc_expr = descended.as_ref().unwrap_or(expr); let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?; - let (needs_outer_parens, needs_inner_parens) = - needs_parens_for_adjustment_hints(expr, config.adjustment_hints_postfix); + let (postfix, needs_outer_parens, needs_inner_parens) = + mode_and_needs_parens_for_adjustment_hints(expr, config.adjustment_hints_mode); if needs_outer_parens { acc.push(InlayHint { @@ -52,7 +52,7 @@ pub(super) fn hints( }); } - if config.adjustment_hints_postfix && needs_inner_parens { + if postfix && needs_inner_parens { acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::OpeningParenthesis, @@ -68,7 +68,7 @@ pub(super) fn hints( } let (mut tmp0, mut tmp1); - let iter: &mut dyn Iterator<Item = _> = if config.adjustment_hints_postfix { + let iter: &mut dyn Iterator<Item = _> = if postfix { tmp0 = adjustments.into_iter(); &mut tmp0 } else { @@ -112,20 +112,16 @@ pub(super) fn hints( }; acc.push(InlayHint { range: expr.syntax().text_range(), - kind: if config.adjustment_hints_postfix { + kind: if postfix { InlayKind::AdjustmentHintPostfix } else { InlayKind::AdjustmentHint }, - label: if config.adjustment_hints_postfix { - format!(".{}", text.trim_end()).into() - } else { - text.into() - }, + label: if postfix { format!(".{}", text.trim_end()).into() } else { text.into() }, tooltip: None, }); } - if !config.adjustment_hints_postfix && needs_inner_parens { + if !postfix && needs_inner_parens { acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::OpeningParenthesis, @@ -150,6 +146,41 @@ pub(super) fn hints( Some(()) } +/// Returns whatever the hint should be postfix and if we need to add paretheses on the inside and/or outside of `expr`, +/// if we are going to add (`postfix`) adjustments hints to it. +fn mode_and_needs_parens_for_adjustment_hints( + expr: &ast::Expr, + mode: AdjustmentHintsMode, +) -> (bool, bool, bool) { + use {std::cmp::Ordering::*, AdjustmentHintsMode::*}; + + match mode { + Prefix | Postfix => { + let postfix = matches!(mode, Postfix); + let (inside, outside) = needs_parens_for_adjustment_hints(expr, postfix); + (postfix, inside, outside) + } + PreferPrefix | PreferPostfix => { + let prefer_postfix = matches!(mode, PreferPostfix); + + let (pre_inside, pre_outside) = needs_parens_for_adjustment_hints(expr, false); + let prefix = (false, pre_inside, pre_outside); + let pre_count = pre_inside as u8 + pre_outside as u8; + + let (post_inside, post_outside) = needs_parens_for_adjustment_hints(expr, true); + let postfix = (true, post_inside, post_outside); + let post_count = post_inside as u8 + post_outside as u8; + + match pre_count.cmp(&post_count) { + Less => prefix, + Greater => postfix, + Equal if prefer_postfix => postfix, + Equal => prefix, + } + } + } +} + /// Returns whatever we need to add paretheses on the inside and/or outside of `expr`, /// if we are going to add (`postfix`) adjustments hints to it. fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) { @@ -217,7 +248,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, mod tests { use crate::{ inlay_hints::tests::{check_with_config, DISABLED_CONFIG}, - AdjustmentHints, InlayHintsConfig, + AdjustmentHints, AdjustmentHintsMode, InlayHintsConfig, }; #[test] @@ -333,7 +364,7 @@ impl Struct { check_with_config( InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, - adjustment_hints_postfix: true, + adjustment_hints_mode: AdjustmentHintsMode::Postfix, ..DISABLED_CONFIG }, r#" @@ -420,6 +451,58 @@ impl Struct { } #[test] + fn adjustment_hints_prefer_prefix() { + check_with_config( + InlayHintsConfig { + adjustment_hints: AdjustmentHints::Always, + adjustment_hints_mode: AdjustmentHintsMode::PreferPrefix, + ..DISABLED_CONFIG + }, + r#" +fn main() { + let _: u32 = loop {}; + //^^^^^^^<never-to-any> + + Struct.by_ref(); + //^^^^^^.& + + let (): () = return (); + //^^^^^^^^^<never-to-any> + + struct Struct; + impl Struct { fn by_ref(&self) {} } +} + "#, + ) + } + + #[test] + fn adjustment_hints_prefer_postfix() { + check_with_config( + InlayHintsConfig { + adjustment_hints: AdjustmentHints::Always, + adjustment_hints_mode: AdjustmentHintsMode::PreferPostfix, + ..DISABLED_CONFIG + }, + r#" +fn main() { + let _: u32 = loop {}; + //^^^^^^^.<never-to-any> + + Struct.by_ref(); + //^^^^^^.& + + let (): () = return (); + //^^^^^^^^^<never-to-any> + + struct Struct; + impl Struct { fn by_ref(&self) {} } +} + "#, + ) + } + + #[test] fn never_to_never_is_never_shown() { check_with_config( InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG }, |