ide/inlay_hints/
range_exclusive.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Implementation of "range exclusive" inlay hints:
//! ```ignore
//! for i in 0../* < */10 {}
//! if let ../* < */100 = 50 {}
//! ```
use ide_db::famous_defs::FamousDefs;
use span::EditionedFileId;
use syntax::{ast, SyntaxToken, T};

use crate::{InlayHint, InlayHintsConfig};

pub(super) fn hints(
    acc: &mut Vec<InlayHint>,
    FamousDefs(_sema, _): &FamousDefs<'_, '_>,
    config: &InlayHintsConfig,
    _file_id: EditionedFileId,
    range: impl ast::RangeItem,
) -> Option<()> {
    (config.range_exclusive_hints && range.end().is_some())
        .then(|| {
            range.op_token().filter(|token| token.kind() == T![..]).map(|token| {
                acc.push(inlay_hint(token));
            })
        })
        .flatten()
}

fn inlay_hint(token: SyntaxToken) -> InlayHint {
    InlayHint {
        range: token.text_range(),
        position: crate::InlayHintPosition::After,
        pad_left: false,
        pad_right: false,
        kind: crate::InlayKind::RangeExclusive,
        label: crate::InlayHintLabel::from("<"),
        text_edit: None,
        resolve_parent: None,
    }
}

#[cfg(test)]
mod tests {
    use crate::{
        inlay_hints::tests::{check_with_config, DISABLED_CONFIG},
        InlayHintsConfig,
    };

    #[test]
    fn range_exclusive_expression_bounded_above_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    let a = 0..10;
           //^^<
    let b = ..100;
          //^^<
    let c = (2 - 1)..(7 * 8)
                 //^^<
}"#,
        );
    }

    #[test]
    fn range_exclusive_expression_unbounded_above_no_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    let a = 0..;
    let b = ..;
}"#,
        );
    }

    #[test]
    fn range_inclusive_expression_no_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    let a = 0..=10;
    let b = ..=100;
}"#,
        );
    }

    #[test]
    fn range_exclusive_pattern_bounded_above_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    if let 0..10 = 0 {}
          //^^<
    if let ..100 = 0 {}
         //^^<
}"#,
        );
    }

    #[test]
    fn range_exclusive_pattern_unbounded_above_no_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    if let 0.. = 0 {}
    if let .. = 0 {}
}"#,
        );
    }

    #[test]
    fn range_inclusive_pattern_no_hints() {
        check_with_config(
            InlayHintsConfig { range_exclusive_hints: true, ..DISABLED_CONFIG },
            r#"
fn main() {
    if let 0..=10 = 0 {}
    if let ..=100 = 0 {}
}"#,
        );
    }
}