aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2019-07-19 22:20:09 +0100
committerKirill Bulatov <[email protected]>2019-07-20 21:45:26 +0100
commit201b344f2b0c9e84606115d135cd658d0a955d2c (patch)
tree1dc9c308c71ea4d2512d351de12933c6475abba8 /crates/ra_ide_api/src
parent761fc71083b9d810aa006210d6df2b0edf95cf33 (diff)
Refactor server api
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/display/structure.rs27
-rw-r--r--crates/ra_ide_api/src/inlay_hints.rs110
-rw-r--r--crates/ra_ide_api/src/lib.rs7
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__inlay_hints.snap63
4 files changed, 180 insertions, 27 deletions
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide_api/src/display/structure.rs
index bd2e908da..2ba10b2ef 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide_api/src/display/structure.rs
@@ -1,6 +1,5 @@
1use crate::TextRange; 1use crate::TextRange;
2 2
3use ra_syntax::ast::PatKind;
4use ra_syntax::{ 3use ra_syntax::{
5 algo::visit::{visitor, Visitor}, 4 algo::visit::{visitor, Visitor},
6 ast::{self, AttrsOwner, NameOwner, TypeAscriptionOwner, TypeParamsOwner}, 5 ast::{self, AttrsOwner, NameOwner, TypeAscriptionOwner, TypeParamsOwner},
@@ -156,32 +155,6 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
156 } 155 }
157 decl(mc) 156 decl(mc)
158 }) 157 })
159 .visit(|let_statement: ast::LetStmt| {
160 let let_syntax = let_statement.syntax();
161
162 let mut label = String::new();
163 collapse_ws(let_syntax, &mut label);
164
165 if let_statement.ascribed_type().is_some() {
166 return None;
167 }
168
169 let pat_range = match let_statement.pat()?.kind() {
170 PatKind::BindPat(bind_pat) => bind_pat.syntax().range(),
171 PatKind::TuplePat(tuple_pat) => tuple_pat.syntax().range(),
172 _ => return None,
173 };
174
175 Some(StructureNode {
176 parent: None,
177 label,
178 navigation_range: pat_range,
179 node_range: let_syntax.range(),
180 kind: let_syntax.kind(),
181 detail: None,
182 deprecated: false,
183 })
184 })
185 .accept(&node)? 158 .accept(&node)?
186} 159}
187 160
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs
new file mode 100644
index 000000000..4d1df65d0
--- /dev/null
+++ b/crates/ra_ide_api/src/inlay_hints.rs
@@ -0,0 +1,110 @@
1use ra_syntax::{
2 algo::visit::{visitor, Visitor},
3 ast::{self, PatKind, TypeAscriptionOwner},
4 AstNode, SmolStr, SourceFile, SyntaxNode, TextRange,
5};
6
7#[derive(Debug, PartialEq, Eq)]
8pub enum InlayKind {
9 LetBinding,
10 ClosureParameter,
11}
12
13#[derive(Debug)]
14pub struct InlayHint {
15 pub range: TextRange,
16 pub text: SmolStr,
17 pub inlay_kind: InlayKind,
18}
19
20pub(crate) fn inlay_hints(file: &SourceFile) -> Vec<InlayHint> {
21 file.syntax().descendants().map(|node| get_inlay_hints(&node)).flatten().collect()
22}
23
24fn get_inlay_hints(node: &SyntaxNode) -> Vec<InlayHint> {
25 visitor()
26 .visit(|let_statement: ast::LetStmt| {
27 let let_syntax = let_statement.syntax();
28
29 if let_statement.ascribed_type().is_some() {
30 return Vec::new();
31 }
32
33 let pat_range = match let_statement.pat().map(|pat| pat.kind()) {
34 Some(PatKind::BindPat(bind_pat)) => bind_pat.syntax().text_range(),
35 Some(PatKind::TuplePat(tuple_pat)) => tuple_pat.syntax().text_range(),
36 _ => return Vec::new(),
37 };
38
39 vec![InlayHint {
40 range: pat_range,
41 text: let_syntax.text().to_smol_string(),
42 inlay_kind: InlayKind::LetBinding,
43 }]
44 })
45 .visit(|closure_parameter: ast::LambdaExpr| {
46 if let Some(param_list) = closure_parameter.param_list() {
47 param_list
48 .params()
49 .filter(|closure_param| closure_param.ascribed_type().is_none())
50 .map(|closure_param| {
51 let closure_param_syntax = closure_param.syntax();
52 InlayHint {
53 range: closure_param_syntax.text_range(),
54 text: closure_param_syntax.text().to_smol_string(),
55 inlay_kind: InlayKind::ClosureParameter,
56 }
57 })
58 .collect()
59 } else {
60 Vec::new()
61 }
62 })
63 .accept(&node)
64 .unwrap_or_else(Vec::new)
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use insta::assert_debug_snapshot_matches;
71
72 #[test]
73 fn test_inlay_hints() {
74 let file = SourceFile::parse(
75 r#"
76struct OuterStruct {}
77
78fn main() {
79 struct InnerStruct {}
80
81 let test = 54;
82 let test = InnerStruct {};
83 let test = OuterStruct {};
84 let test = vec![222];
85 let mut test = Vec::new();
86 test.push(333);
87 let test = test.into_iter().map(|i| i * i).collect::<Vec<_>>();
88 let mut test = 33;
89 let _ = 22;
90 let test: Vec<_> = (0..3).collect();
91
92 let _ = (0..23).map(|i: u32| {
93 let i_squared = i * i;
94 i_squared
95 });
96
97 let test: i32 = 33;
98
99 let (x, c) = (42, 'a');
100 let test = (42, 'a');
101}
102
103"#,
104 )
105 .ok()
106 .unwrap();
107 let hints = inlay_hints(&file);
108 assert_debug_snapshot_matches!("inlay_hints", hints);
109 }
110}
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index c54d574bc..af163088a 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -38,6 +38,7 @@ mod join_lines;
38mod typing; 38mod typing;
39mod matching_brace; 39mod matching_brace;
40mod display; 40mod display;
41mod inlay_hints;
41 42
42#[cfg(test)] 43#[cfg(test)]
43mod marks; 44mod marks;
@@ -64,6 +65,7 @@ pub use crate::{
64 display::{file_structure, FunctionSignature, NavigationTarget, StructureNode}, 65 display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
65 folding_ranges::{Fold, FoldKind}, 66 folding_ranges::{Fold, FoldKind},
66 hover::HoverResult, 67 hover::HoverResult,
68 inlay_hints::{InlayHint, InlayKind},
67 line_index::{LineCol, LineIndex}, 69 line_index::{LineCol, LineIndex},
68 line_index_utils::translate_offset_with_edit, 70 line_index_utils::translate_offset_with_edit,
69 references::ReferenceSearchResult, 71 references::ReferenceSearchResult,
@@ -396,6 +398,11 @@ impl Analysis {
396 file_structure(&parse.tree()) 398 file_structure(&parse.tree())
397 } 399 }
398 400
401 /// Returns a list of the places in the file where type hints can be displayed.
402 pub fn inlay_hints(&self, file_id: FileId) -> Vec<InlayHint> {
403 inlay_hints::inlay_hints(&self.db.parse(file_id).tree())
404 }
405
399 /// Returns the set of folding ranges. 406 /// Returns the set of folding ranges.
400 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 407 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
401 let parse = self.db.parse(file_id); 408 let parse = self.db.parse(file_id);
diff --git a/crates/ra_ide_api/src/snapshots/tests__inlay_hints.snap b/crates/ra_ide_api/src/snapshots/tests__inlay_hints.snap
new file mode 100644
index 000000000..f4d562314
--- /dev/null
+++ b/crates/ra_ide_api/src/snapshots/tests__inlay_hints.snap
@@ -0,0 +1,63 @@
1---
2created: "2019-07-20T20:13:53.385368Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/inlay_hints.rs
5expression: hints
6---
7[
8 InlayHint {
9 range: [71; 75),
10 text: "let test = 54;",
11 inlay_kind: LetBinding,
12 },
13 InlayHint {
14 range: [90; 94),
15 text: "let test = InnerStruct {};",
16 inlay_kind: LetBinding,
17 },
18 InlayHint {
19 range: [121; 125),
20 text: "let test = OuterStruct {};",
21 inlay_kind: LetBinding,
22 },
23 InlayHint {
24 range: [152; 156),
25 text: "let test = vec![222];",
26 inlay_kind: LetBinding,
27 },
28 InlayHint {
29 range: [178; 186),
30 text: "let mut test = Vec::new();",
31 inlay_kind: LetBinding,
32 },
33 InlayHint {
34 range: [229; 233),
35 text: "let test = test.into_iter().map(|i| i * i).collect::<Vec<_>>();",
36 inlay_kind: LetBinding,
37 },
38 InlayHint {
39 range: [258; 259),
40 text: "i",
41 inlay_kind: ClosureParameter,
42 },
43 InlayHint {
44 range: [297; 305),
45 text: "let mut test = 33;",
46 inlay_kind: LetBinding,
47 },
48 InlayHint {
49 range: [417; 426),
50 text: "let i_squared = i * i;",
51 inlay_kind: LetBinding,
52 },
53 InlayHint {
54 range: [500; 506),
55 text: "let (x, c) = (42, \'a\');",
56 inlay_kind: LetBinding,
57 },
58 InlayHint {
59 range: [528; 532),
60 text: "let test = (42, \'a\');",
61 inlay_kind: LetBinding,
62 },
63]