aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 {}