aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-03-03 10:02:55 +0000
committerVille Penttinen <[email protected]>2019-03-03 17:49:50 +0000
commitac52d9a1f1a94e2c836c8a04a316f6454936a79a (patch)
treebf0e217ed101a32c1597fb6ed0e20fc755954d2c
parent17aaece6b39c2fb525be0eccce4626fc622e8236 (diff)
Add optional range parameter to SyntaxTreeParams
When range is provided, instead of showing the syntax for the whole file, we'll show the syntax tree for the given range.
-rw-r--r--crates/ra_ide_api/src/lib.rs12
-rw-r--r--crates/ra_ide_api/tests/test/main.rs136
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs4
-rw-r--r--crates/ra_lsp_server/src/req.rs1
4 files changed, 148 insertions, 5 deletions
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 6546d0644..3e7cfbb54 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -38,7 +38,7 @@ mod marks;
38 38
39use std::sync::Arc; 39use std::sync::Arc;
40 40
41use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit, AstNode}; 41use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit, AstNode, algo};
42use ra_text_edit::TextEdit; 42use ra_text_edit::TextEdit;
43use ra_db::{ 43use ra_db::{
44 SourceDatabase, CheckCanceled, 44 SourceDatabase, CheckCanceled,
@@ -245,8 +245,14 @@ impl Analysis {
245 245
246 /// Returns a syntax tree represented as `String`, for debug purposes. 246 /// Returns a syntax tree represented as `String`, for debug purposes.
247 // FIXME: use a better name here. 247 // FIXME: use a better name here.
248 pub fn syntax_tree(&self, file_id: FileId) -> String { 248 pub fn syntax_tree(&self, file_id: FileId, text_range: Option<TextRange>) -> String {
249 self.db.parse(file_id).syntax().debug_dump() 249 if let Some(text_range) = text_range {
250 let file = self.db.parse(file_id);
251 let node = algo::find_covering_node(file.syntax(), text_range);
252 node.debug_dump()
253 } else {
254 self.db.parse(file_id).syntax().debug_dump()
255 }
250 } 256 }
251 257
252 /// Returns an edit to remove all newlines in the range, cleaning up minor 258 /// Returns an edit to remove all newlines in the range, cleaning up minor
diff --git a/crates/ra_ide_api/tests/test/main.rs b/crates/ra_ide_api/tests/test/main.rs
index ff1a0e46b..b0c80e255 100644
--- a/crates/ra_ide_api/tests/test/main.rs
+++ b/crates/ra_ide_api/tests/test/main.rs
@@ -1,6 +1,6 @@
1use insta::assert_debug_snapshot_matches; 1use insta::assert_debug_snapshot_matches;
2use ra_ide_api::{ 2use ra_ide_api::{
3 mock_analysis::{single_file, single_file_with_position, MockAnalysis}, 3 mock_analysis::{single_file, single_file_with_position, single_file_with_range, MockAnalysis},
4 AnalysisChange, CrateGraph, Edition::Edition2018, Query, NavigationTarget, 4 AnalysisChange, CrateGraph, Edition::Edition2018, Query, NavigationTarget,
5 ReferenceSearchResult, 5 ReferenceSearchResult,
6}; 6};
@@ -138,3 +138,137 @@ mod foo {
138 assert_eq!(s.name(), "FooInner"); 138 assert_eq!(s.name(), "FooInner");
139 assert_eq!(s.container_name(), Some(&SmolStr::new("foo"))); 139 assert_eq!(s.container_name(), Some(&SmolStr::new("foo")));
140} 140}
141
142#[test]
143fn test_syntax_tree_without_range() {
144 // Basic syntax
145 let (analysis, file_id) = single_file(r#"fn foo() {}"#);
146 let syn = analysis.syntax_tree(file_id, None);
147
148 assert_eq!(
149 syn.trim(),
150 r#"
151SOURCE_FILE@[0; 11)
152 FN_DEF@[0; 11)
153 FN_KW@[0; 2)
154 WHITESPACE@[2; 3)
155 NAME@[3; 6)
156 IDENT@[3; 6) "foo"
157 PARAM_LIST@[6; 8)
158 L_PAREN@[6; 7)
159 R_PAREN@[7; 8)
160 WHITESPACE@[8; 9)
161 BLOCK@[9; 11)
162 L_CURLY@[9; 10)
163 R_CURLY@[10; 11)
164 "#
165 .trim()
166 );
167
168 let (analysis, file_id) = single_file(
169 r#"
170fn test() {
171 assert!("
172 fn foo() {
173 }
174 ", "");
175}"#
176 .trim(),
177 );
178 let syn = analysis.syntax_tree(file_id, None);
179
180 assert_eq!(
181 syn.trim(),
182 r#"
183SOURCE_FILE@[0; 60)
184 FN_DEF@[0; 60)
185 FN_KW@[0; 2)
186 WHITESPACE@[2; 3)
187 NAME@[3; 7)
188 IDENT@[3; 7) "test"
189 PARAM_LIST@[7; 9)
190 L_PAREN@[7; 8)
191 R_PAREN@[8; 9)
192 WHITESPACE@[9; 10)
193 BLOCK@[10; 60)
194 L_CURLY@[10; 11)
195 WHITESPACE@[11; 16)
196 EXPR_STMT@[16; 58)
197 MACRO_CALL@[16; 57)
198 PATH@[16; 22)
199 PATH_SEGMENT@[16; 22)
200 NAME_REF@[16; 22)
201 IDENT@[16; 22) "assert"
202 EXCL@[22; 23)
203 TOKEN_TREE@[23; 57)
204 L_PAREN@[23; 24)
205 STRING@[24; 52)
206 COMMA@[52; 53)
207 WHITESPACE@[53; 54)
208 STRING@[54; 56)
209 R_PAREN@[56; 57)
210 SEMI@[57; 58)
211 WHITESPACE@[58; 59)
212 R_CURLY@[59; 60)
213 "#
214 .trim()
215 );
216}
217
218#[test]
219fn test_syntax_tree_with_range() {
220 let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
221 let syn = analysis.syntax_tree(range.file_id, Some(range.range));
222
223 assert_eq!(
224 syn.trim(),
225 r#"
226FN_DEF@[0; 11)
227 FN_KW@[0; 2)
228 WHITESPACE@[2; 3)
229 NAME@[3; 6)
230 IDENT@[3; 6) "foo"
231 PARAM_LIST@[6; 8)
232 L_PAREN@[6; 7)
233 R_PAREN@[7; 8)
234 WHITESPACE@[8; 9)
235 BLOCK@[9; 11)
236 L_CURLY@[9; 10)
237 R_CURLY@[10; 11)
238 "#
239 .trim()
240 );
241
242 let (analysis, range) = single_file_with_range(
243 r#"fn test() {
244 <|>assert!("
245 fn foo() {
246 }
247 ", "");<|>
248}"#
249 .trim(),
250 );
251 let syn = analysis.syntax_tree(range.file_id, Some(range.range));
252
253 assert_eq!(
254 syn.trim(),
255 r#"
256EXPR_STMT@[16; 58)
257 MACRO_CALL@[16; 57)
258 PATH@[16; 22)
259 PATH_SEGMENT@[16; 22)
260 NAME_REF@[16; 22)
261 IDENT@[16; 22) "assert"
262 EXCL@[22; 23)
263 TOKEN_TREE@[23; 57)
264 L_PAREN@[23; 24)
265 STRING@[24; 52)
266 COMMA@[52; 53)
267 WHITESPACE@[53; 54)
268 STRING@[54; 56)
269 R_PAREN@[56; 57)
270 SEMI@[57; 58)
271 "#
272 .trim()
273 );
274}
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index dce6fcc67..89e96a33a 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -32,7 +32,9 @@ pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result<String> {
32 32
33pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> { 33pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> {
34 let id = params.text_document.try_conv_with(&world)?; 34 let id = params.text_document.try_conv_with(&world)?;
35 let res = world.analysis().syntax_tree(id); 35 let line_index = world.analysis().file_line_index(id);
36 let text_range = params.range.map(|p| p.conv_with(&line_index));
37 let res = world.analysis().syntax_tree(id, text_range);
36 Ok(res) 38 Ok(res)
37} 39}
38 40
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index e224ede80..5c589f969 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -39,6 +39,7 @@ impl Request for SyntaxTree {
39#[serde(rename_all = "camelCase")] 39#[serde(rename_all = "camelCase")]
40pub struct SyntaxTreeParams { 40pub struct SyntaxTreeParams {
41 pub text_document: TextDocumentIdentifier, 41 pub text_document: TextDocumentIdentifier,
42 pub range: Option<Range>,
42} 43}
43 44
44pub enum ExtendSelection {} 45pub enum ExtendSelection {}