diff options
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r-- | crates/ra_ide_api/src/parent_module.rs | 30 | ||||
-rw-r--r-- | crates/ra_ide_api/src/references.rs | 48 | ||||
-rw-r--r-- | crates/ra_ide_api/src/symbol_index.rs | 58 | ||||
-rw-r--r-- | crates/ra_ide_api/src/syntax_tree.rs | 257 |
4 files changed, 391 insertions, 2 deletions
diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide_api/src/parent_module.rs index 603c3db6a..27788c984 100644 --- a/crates/ra_ide_api/src/parent_module.rs +++ b/crates/ra_ide_api/src/parent_module.rs | |||
@@ -28,7 +28,11 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { | |||
28 | 28 | ||
29 | #[cfg(test)] | 29 | #[cfg(test)] |
30 | mod tests { | 30 | mod tests { |
31 | use crate::mock_analysis::analysis_and_position; | 31 | use crate::{ |
32 | AnalysisChange, CrateGraph, | ||
33 | mock_analysis::{analysis_and_position, MockAnalysis}, | ||
34 | Edition::Edition2018, | ||
35 | }; | ||
32 | 36 | ||
33 | #[test] | 37 | #[test] |
34 | fn test_resolve_parent_module() { | 38 | fn test_resolve_parent_module() { |
@@ -59,4 +63,28 @@ mod tests { | |||
59 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | 63 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); |
60 | nav.assert_match("baz MODULE FileId(1) [32; 44)"); | 64 | nav.assert_match("baz MODULE FileId(1) [32; 44)"); |
61 | } | 65 | } |
66 | |||
67 | #[test] | ||
68 | fn test_resolve_crate_root() { | ||
69 | let mock = MockAnalysis::with_files( | ||
70 | " | ||
71 | //- /bar.rs | ||
72 | mod foo; | ||
73 | //- /foo.rs | ||
74 | // empty <|> | ||
75 | ", | ||
76 | ); | ||
77 | let root_file = mock.id_of("/bar.rs"); | ||
78 | let mod_file = mock.id_of("/foo.rs"); | ||
79 | let mut host = mock.analysis_host(); | ||
80 | assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); | ||
81 | |||
82 | let mut crate_graph = CrateGraph::default(); | ||
83 | let crate_id = crate_graph.add_crate_root(root_file, Edition2018); | ||
84 | let mut change = AnalysisChange::new(); | ||
85 | change.set_crate_graph(crate_graph); | ||
86 | host.apply_change(change); | ||
87 | |||
88 | assert_eq!(host.analysis().crate_for(mod_file).unwrap(), vec![crate_id]); | ||
89 | } | ||
62 | } | 90 | } |
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index 22741445a..20bbf11a3 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs | |||
@@ -216,10 +216,56 @@ mod tests { | |||
216 | use crate::{ | 216 | use crate::{ |
217 | mock_analysis::single_file_with_position, | 217 | mock_analysis::single_file_with_position, |
218 | mock_analysis::analysis_and_position, | 218 | mock_analysis::analysis_and_position, |
219 | FileId | 219 | FileId, ReferenceSearchResult |
220 | }; | 220 | }; |
221 | 221 | ||
222 | #[test] | 222 | #[test] |
223 | fn test_find_all_refs_for_local() { | ||
224 | let code = r#" | ||
225 | fn main() { | ||
226 | let mut i = 1; | ||
227 | let j = 1; | ||
228 | i = i<|> + j; | ||
229 | |||
230 | { | ||
231 | i = 0; | ||
232 | } | ||
233 | |||
234 | i = 5; | ||
235 | }"#; | ||
236 | |||
237 | let refs = get_all_refs(code); | ||
238 | assert_eq!(refs.len(), 5); | ||
239 | } | ||
240 | |||
241 | #[test] | ||
242 | fn test_find_all_refs_for_param_inside() { | ||
243 | let code = r#" | ||
244 | fn foo(i : u32) -> u32 { | ||
245 | i<|> | ||
246 | }"#; | ||
247 | |||
248 | let refs = get_all_refs(code); | ||
249 | assert_eq!(refs.len(), 2); | ||
250 | } | ||
251 | |||
252 | #[test] | ||
253 | fn test_find_all_refs_for_fn_param() { | ||
254 | let code = r#" | ||
255 | fn foo(i<|> : u32) -> u32 { | ||
256 | i | ||
257 | }"#; | ||
258 | |||
259 | let refs = get_all_refs(code); | ||
260 | assert_eq!(refs.len(), 2); | ||
261 | } | ||
262 | |||
263 | fn get_all_refs(text: &str) -> ReferenceSearchResult { | ||
264 | let (analysis, position) = single_file_with_position(text); | ||
265 | analysis.find_all_refs(position).unwrap().unwrap() | ||
266 | } | ||
267 | |||
268 | #[test] | ||
223 | fn test_rename_for_local() { | 269 | fn test_rename_for_local() { |
224 | test_rename( | 270 | test_rename( |
225 | r#" | 271 | r#" |
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 0978d164a..0eadc4e71 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -270,3 +270,61 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { | |||
270 | container_name: None, | 270 | container_name: None, |
271 | }) | 271 | }) |
272 | } | 272 | } |
273 | |||
274 | #[cfg(test)] | ||
275 | mod tests { | ||
276 | use ra_syntax::SmolStr; | ||
277 | use crate::{ | ||
278 | navigation_target::NavigationTarget, | ||
279 | mock_analysis::single_file, | ||
280 | Query, | ||
281 | }; | ||
282 | |||
283 | #[test] | ||
284 | fn test_world_symbols_with_no_container() { | ||
285 | let code = r#" | ||
286 | enum FooInner { } | ||
287 | "#; | ||
288 | |||
289 | let mut symbols = get_symbols_matching(code, "FooInner"); | ||
290 | |||
291 | let s = symbols.pop().unwrap(); | ||
292 | |||
293 | assert_eq!(s.name(), "FooInner"); | ||
294 | assert!(s.container_name().is_none()); | ||
295 | } | ||
296 | |||
297 | #[test] | ||
298 | fn test_world_symbols_include_container_name() { | ||
299 | let code = r#" | ||
300 | fn foo() { | ||
301 | enum FooInner { } | ||
302 | } | ||
303 | "#; | ||
304 | |||
305 | let mut symbols = get_symbols_matching(code, "FooInner"); | ||
306 | |||
307 | let s = symbols.pop().unwrap(); | ||
308 | |||
309 | assert_eq!(s.name(), "FooInner"); | ||
310 | assert_eq!(s.container_name(), Some(&SmolStr::new("foo"))); | ||
311 | |||
312 | let code = r#" | ||
313 | mod foo { | ||
314 | struct FooInner; | ||
315 | } | ||
316 | "#; | ||
317 | |||
318 | let mut symbols = get_symbols_matching(code, "FooInner"); | ||
319 | |||
320 | let s = symbols.pop().unwrap(); | ||
321 | |||
322 | assert_eq!(s.name(), "FooInner"); | ||
323 | assert_eq!(s.container_name(), Some(&SmolStr::new("foo"))); | ||
324 | } | ||
325 | |||
326 | fn get_symbols_matching(text: &str, query: &str) -> Vec<NavigationTarget> { | ||
327 | let (analysis, _) = single_file(text); | ||
328 | analysis.symbol_search(Query::new(query.into())).unwrap() | ||
329 | } | ||
330 | } | ||
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs index bbe9222b4..276f8a8c8 100644 --- a/crates/ra_ide_api/src/syntax_tree.rs +++ b/crates/ra_ide_api/src/syntax_tree.rs | |||
@@ -85,3 +85,260 @@ fn syntax_tree_for_token<T: AstToken>(node: &T, text_range: TextRange) -> Option | |||
85 | 85 | ||
86 | None | 86 | None |
87 | } | 87 | } |
88 | |||
89 | #[cfg(test)] | ||
90 | mod tests { | ||
91 | use crate::mock_analysis::{single_file, single_file_with_range}; | ||
92 | |||
93 | #[test] | ||
94 | fn test_syntax_tree_without_range() { | ||
95 | // Basic syntax | ||
96 | let (analysis, file_id) = single_file(r#"fn foo() {}"#); | ||
97 | let syn = analysis.syntax_tree(file_id, None); | ||
98 | |||
99 | assert_eq!( | ||
100 | syn.trim(), | ||
101 | r#" | ||
102 | SOURCE_FILE@[0; 11) | ||
103 | FN_DEF@[0; 11) | ||
104 | FN_KW@[0; 2) | ||
105 | WHITESPACE@[2; 3) | ||
106 | NAME@[3; 6) | ||
107 | IDENT@[3; 6) "foo" | ||
108 | PARAM_LIST@[6; 8) | ||
109 | L_PAREN@[6; 7) | ||
110 | R_PAREN@[7; 8) | ||
111 | WHITESPACE@[8; 9) | ||
112 | BLOCK@[9; 11) | ||
113 | L_CURLY@[9; 10) | ||
114 | R_CURLY@[10; 11) | ||
115 | "# | ||
116 | .trim() | ||
117 | ); | ||
118 | |||
119 | let (analysis, file_id) = single_file( | ||
120 | r#" | ||
121 | fn test() { | ||
122 | assert!(" | ||
123 | fn foo() { | ||
124 | } | ||
125 | ", ""); | ||
126 | }"# | ||
127 | .trim(), | ||
128 | ); | ||
129 | let syn = analysis.syntax_tree(file_id, None); | ||
130 | |||
131 | assert_eq!( | ||
132 | syn.trim(), | ||
133 | r#" | ||
134 | SOURCE_FILE@[0; 60) | ||
135 | FN_DEF@[0; 60) | ||
136 | FN_KW@[0; 2) | ||
137 | WHITESPACE@[2; 3) | ||
138 | NAME@[3; 7) | ||
139 | IDENT@[3; 7) "test" | ||
140 | PARAM_LIST@[7; 9) | ||
141 | L_PAREN@[7; 8) | ||
142 | R_PAREN@[8; 9) | ||
143 | WHITESPACE@[9; 10) | ||
144 | BLOCK@[10; 60) | ||
145 | L_CURLY@[10; 11) | ||
146 | WHITESPACE@[11; 16) | ||
147 | EXPR_STMT@[16; 58) | ||
148 | MACRO_CALL@[16; 57) | ||
149 | PATH@[16; 22) | ||
150 | PATH_SEGMENT@[16; 22) | ||
151 | NAME_REF@[16; 22) | ||
152 | IDENT@[16; 22) "assert" | ||
153 | EXCL@[22; 23) | ||
154 | TOKEN_TREE@[23; 57) | ||
155 | L_PAREN@[23; 24) | ||
156 | STRING@[24; 52) | ||
157 | COMMA@[52; 53) | ||
158 | WHITESPACE@[53; 54) | ||
159 | STRING@[54; 56) | ||
160 | R_PAREN@[56; 57) | ||
161 | SEMI@[57; 58) | ||
162 | WHITESPACE@[58; 59) | ||
163 | R_CURLY@[59; 60) | ||
164 | "# | ||
165 | .trim() | ||
166 | ); | ||
167 | } | ||
168 | |||
169 | #[test] | ||
170 | fn test_syntax_tree_with_range() { | ||
171 | let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim()); | ||
172 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)); | ||
173 | |||
174 | assert_eq!( | ||
175 | syn.trim(), | ||
176 | r#" | ||
177 | FN_DEF@[0; 11) | ||
178 | FN_KW@[0; 2) | ||
179 | WHITESPACE@[2; 3) | ||
180 | NAME@[3; 6) | ||
181 | IDENT@[3; 6) "foo" | ||
182 | PARAM_LIST@[6; 8) | ||
183 | L_PAREN@[6; 7) | ||
184 | R_PAREN@[7; 8) | ||
185 | WHITESPACE@[8; 9) | ||
186 | BLOCK@[9; 11) | ||
187 | L_CURLY@[9; 10) | ||
188 | R_CURLY@[10; 11) | ||
189 | "# | ||
190 | .trim() | ||
191 | ); | ||
192 | |||
193 | let (analysis, range) = single_file_with_range( | ||
194 | r#"fn test() { | ||
195 | <|>assert!(" | ||
196 | fn foo() { | ||
197 | } | ||
198 | ", "");<|> | ||
199 | }"# | ||
200 | .trim(), | ||
201 | ); | ||
202 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)); | ||
203 | |||
204 | assert_eq!( | ||
205 | syn.trim(), | ||
206 | r#" | ||
207 | EXPR_STMT@[16; 58) | ||
208 | MACRO_CALL@[16; 57) | ||
209 | PATH@[16; 22) | ||
210 | PATH_SEGMENT@[16; 22) | ||
211 | NAME_REF@[16; 22) | ||
212 | IDENT@[16; 22) "assert" | ||
213 | EXCL@[22; 23) | ||
214 | TOKEN_TREE@[23; 57) | ||
215 | L_PAREN@[23; 24) | ||
216 | STRING@[24; 52) | ||
217 | COMMA@[52; 53) | ||
218 | WHITESPACE@[53; 54) | ||
219 | STRING@[54; 56) | ||
220 | R_PAREN@[56; 57) | ||
221 | SEMI@[57; 58) | ||
222 | "# | ||
223 | .trim() | ||
224 | ); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn test_syntax_tree_inside_string() { | ||
229 | let (analysis, range) = single_file_with_range( | ||
230 | r#"fn test() { | ||
231 | assert!(" | ||
232 | <|>fn foo() { | ||
233 | }<|> | ||
234 | fn bar() { | ||
235 | } | ||
236 | ", ""); | ||
237 | }"# | ||
238 | .trim(), | ||
239 | ); | ||
240 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)); | ||
241 | assert_eq!( | ||
242 | syn.trim(), | ||
243 | r#" | ||
244 | SOURCE_FILE@[0; 12) | ||
245 | FN_DEF@[0; 12) | ||
246 | FN_KW@[0; 2) | ||
247 | WHITESPACE@[2; 3) | ||
248 | NAME@[3; 6) | ||
249 | IDENT@[3; 6) "foo" | ||
250 | PARAM_LIST@[6; 8) | ||
251 | L_PAREN@[6; 7) | ||
252 | R_PAREN@[7; 8) | ||
253 | WHITESPACE@[8; 9) | ||
254 | BLOCK@[9; 12) | ||
255 | L_CURLY@[9; 10) | ||
256 | WHITESPACE@[10; 11) | ||
257 | R_CURLY@[11; 12) | ||
258 | "# | ||
259 | .trim() | ||
260 | ); | ||
261 | |||
262 | // With a raw string | ||
263 | let (analysis, range) = single_file_with_range( | ||
264 | r###"fn test() { | ||
265 | assert!(r#" | ||
266 | <|>fn foo() { | ||
267 | }<|> | ||
268 | fn bar() { | ||
269 | } | ||
270 | "#, ""); | ||
271 | }"### | ||
272 | .trim(), | ||
273 | ); | ||
274 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)); | ||
275 | assert_eq!( | ||
276 | syn.trim(), | ||
277 | r#" | ||
278 | SOURCE_FILE@[0; 12) | ||
279 | FN_DEF@[0; 12) | ||
280 | FN_KW@[0; 2) | ||
281 | WHITESPACE@[2; 3) | ||
282 | NAME@[3; 6) | ||
283 | IDENT@[3; 6) "foo" | ||
284 | PARAM_LIST@[6; 8) | ||
285 | L_PAREN@[6; 7) | ||
286 | R_PAREN@[7; 8) | ||
287 | WHITESPACE@[8; 9) | ||
288 | BLOCK@[9; 12) | ||
289 | L_CURLY@[9; 10) | ||
290 | WHITESPACE@[10; 11) | ||
291 | R_CURLY@[11; 12) | ||
292 | "# | ||
293 | .trim() | ||
294 | ); | ||
295 | |||
296 | // With a raw string | ||
297 | let (analysis, range) = single_file_with_range( | ||
298 | r###"fn test() { | ||
299 | assert!(r<|>#" | ||
300 | fn foo() { | ||
301 | } | ||
302 | fn bar() { | ||
303 | }"<|>#, ""); | ||
304 | }"### | ||
305 | .trim(), | ||
306 | ); | ||
307 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)); | ||
308 | assert_eq!( | ||
309 | syn.trim(), | ||
310 | r#" | ||
311 | SOURCE_FILE@[0; 25) | ||
312 | FN_DEF@[0; 12) | ||
313 | FN_KW@[0; 2) | ||
314 | WHITESPACE@[2; 3) | ||
315 | NAME@[3; 6) | ||
316 | IDENT@[3; 6) "foo" | ||
317 | PARAM_LIST@[6; 8) | ||
318 | L_PAREN@[6; 7) | ||
319 | R_PAREN@[7; 8) | ||
320 | WHITESPACE@[8; 9) | ||
321 | BLOCK@[9; 12) | ||
322 | L_CURLY@[9; 10) | ||
323 | WHITESPACE@[10; 11) | ||
324 | R_CURLY@[11; 12) | ||
325 | WHITESPACE@[12; 13) | ||
326 | FN_DEF@[13; 25) | ||
327 | FN_KW@[13; 15) | ||
328 | WHITESPACE@[15; 16) | ||
329 | NAME@[16; 19) | ||
330 | IDENT@[16; 19) "bar" | ||
331 | PARAM_LIST@[19; 21) | ||
332 | L_PAREN@[19; 20) | ||
333 | R_PAREN@[20; 21) | ||
334 | WHITESPACE@[21; 22) | ||
335 | BLOCK@[22; 25) | ||
336 | L_CURLY@[22; 23) | ||
337 | WHITESPACE@[23; 24) | ||
338 | R_CURLY@[24; 25) | ||
339 | |||
340 | "# | ||
341 | .trim() | ||
342 | ); | ||
343 | } | ||
344 | } | ||