diff options
Diffstat (limited to 'crates')
81 files changed, 1691 insertions, 1505 deletions
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs index 2e56bd7ff..030b9cd0c 100644 --- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::iter; | 1 | use std::iter; |
2 | 2 | ||
3 | use either::Either; | 3 | use either::Either; |
4 | use hir::{AsName, EnumVariant, Module, ModuleDef, Name}; | 4 | use hir::{AsName, Module, ModuleDef, Name, Variant}; |
5 | use ide_db::helpers::{ | 5 | use ide_db::helpers::{ |
6 | insert_use::{insert_use, ImportScope}, | 6 | insert_use::{insert_use, ImportScope}, |
7 | mod_path_to_ast, | 7 | mod_path_to_ast, |
@@ -53,7 +53,7 @@ pub(crate) fn extract_struct_from_enum_variant( | |||
53 | let variant_hir_name = variant_hir.name(ctx.db()); | 53 | let variant_hir_name = variant_hir.name(ctx.db()); |
54 | let enum_module_def = ModuleDef::from(enum_hir); | 54 | let enum_module_def = ModuleDef::from(enum_hir); |
55 | let usages = | 55 | let usages = |
56 | Definition::ModuleDef(ModuleDef::EnumVariant(variant_hir)).usages(&ctx.sema).all(); | 56 | Definition::ModuleDef(ModuleDef::Variant(variant_hir)).usages(&ctx.sema).all(); |
57 | 57 | ||
58 | let mut visited_modules_set = FxHashSet::default(); | 58 | let mut visited_modules_set = FxHashSet::default(); |
59 | let current_module = enum_hir.module(ctx.db()); | 59 | let current_module = enum_hir.module(ctx.db()); |
@@ -109,7 +109,7 @@ fn extract_field_list_if_applicable( | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool { | 112 | fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Variant) -> bool { |
113 | variant | 113 | variant |
114 | .parent_enum(db) | 114 | .parent_enum(db) |
115 | .module(db) | 115 | .module(db) |
@@ -119,7 +119,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &En | |||
119 | // only check type-namespace | 119 | // only check type-namespace |
120 | hir::ScopeDef::ModuleDef(def) => matches!(def, | 120 | hir::ScopeDef::ModuleDef(def) => matches!(def, |
121 | ModuleDef::Module(_) | ModuleDef::Adt(_) | | 121 | ModuleDef::Module(_) | ModuleDef::Adt(_) | |
122 | ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) | | 122 | ModuleDef::Variant(_) | ModuleDef::Trait(_) | |
123 | ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) | 123 | ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) |
124 | ), | 124 | ), |
125 | _ => false, | 125 | _ => false, |
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index ef12ef0cf..cb60a3128 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs | |||
@@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def( | |||
192 | .collect() | 192 | .collect() |
193 | } | 193 | } |
194 | 194 | ||
195 | fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> { | 195 | fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::Variant) -> Option<ast::Pat> { |
196 | let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?); | 196 | let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?); |
197 | 197 | ||
198 | // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though | 198 | // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though |
diff --git a/crates/assists/src/handlers/fix_visibility.rs b/crates/assists/src/handlers/fix_visibility.rs index c86720787..8558a8ff0 100644 --- a/crates/assists/src/handlers/fix_visibility.rs +++ b/crates/assists/src/handlers/fix_visibility.rs | |||
@@ -201,7 +201,7 @@ fn target_data_for_def( | |||
201 | (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id) | 201 | (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id) |
202 | } | 202 | } |
203 | // Enum variants can't be private, we can't modify builtin types | 203 | // Enum variants can't be private, we can't modify builtin types |
204 | hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, | 204 | hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None, |
205 | }; | 205 | }; |
206 | 206 | ||
207 | Some((offset, current_visibility, target, target_file, target_name)) | 207 | Some((offset, current_visibility, target, target_file, target_name)) |
diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs index 758188a42..f4cf155b6 100644 --- a/crates/assists/src/handlers/generate_function.rs +++ b/crates/assists/src/handlers/generate_function.rs | |||
@@ -145,7 +145,7 @@ impl FunctionBuilder { | |||
145 | self.type_params, | 145 | self.type_params, |
146 | self.params, | 146 | self.params, |
147 | fn_body, | 147 | fn_body, |
148 | Some(make::ret_type(make::ty("()"))), | 148 | Some(make::ret_type(make::ty_unit())), |
149 | ); | 149 | ); |
150 | let leading_ws; | 150 | let leading_ws; |
151 | let trailing_ws; | 151 | let trailing_ws; |
diff --git a/crates/completion/src/completions.rs b/crates/completion/src/completions.rs index 9b7d6c580..1ef6b5f48 100644 --- a/crates/completion/src/completions.rs +++ b/crates/completion/src/completions.rs | |||
@@ -19,7 +19,7 @@ use hir::{ModPath, ScopeDef, Type}; | |||
19 | use crate::{ | 19 | use crate::{ |
20 | item::Builder, | 20 | item::Builder, |
21 | render::{ | 21 | render::{ |
22 | const_::render_const, enum_variant::render_enum_variant, function::render_fn, | 22 | const_::render_const, enum_variant::render_variant, function::render_fn, |
23 | macro_::render_macro, render_field, render_resolution, render_tuple_field, | 23 | macro_::render_macro, render_field, render_resolution, render_tuple_field, |
24 | type_alias::render_type_alias, RenderContext, | 24 | type_alias::render_type_alias, RenderContext, |
25 | }, | 25 | }, |
@@ -120,20 +120,20 @@ impl Completions { | |||
120 | pub(crate) fn add_qualified_enum_variant( | 120 | pub(crate) fn add_qualified_enum_variant( |
121 | &mut self, | 121 | &mut self, |
122 | ctx: &CompletionContext, | 122 | ctx: &CompletionContext, |
123 | variant: hir::EnumVariant, | 123 | variant: hir::Variant, |
124 | path: ModPath, | 124 | path: ModPath, |
125 | ) { | 125 | ) { |
126 | let item = render_enum_variant(RenderContext::new(ctx), None, None, variant, Some(path)); | 126 | let item = render_variant(RenderContext::new(ctx), None, None, variant, Some(path)); |
127 | self.add(item); | 127 | self.add(item); |
128 | } | 128 | } |
129 | 129 | ||
130 | pub(crate) fn add_enum_variant( | 130 | pub(crate) fn add_enum_variant( |
131 | &mut self, | 131 | &mut self, |
132 | ctx: &CompletionContext, | 132 | ctx: &CompletionContext, |
133 | variant: hir::EnumVariant, | 133 | variant: hir::Variant, |
134 | local_name: Option<String>, | 134 | local_name: Option<String>, |
135 | ) { | 135 | ) { |
136 | let item = render_enum_variant(RenderContext::new(ctx), None, local_name, variant, None); | 136 | let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None); |
137 | self.add(item); | 137 | self.add(item); |
138 | } | 138 | } |
139 | } | 139 | } |
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index acce2e7e7..19ce2482f 100644 --- a/crates/completion/src/completions/attribute.rs +++ b/crates/completion/src/completions/attribute.rs | |||
@@ -428,8 +428,8 @@ struct Test {} | |||
428 | at Hash | 428 | at Hash |
429 | at PartialEq | 429 | at PartialEq |
430 | at PartialEq, Eq | 430 | at PartialEq, Eq |
431 | at PartialEq, Eq, PartialOrd, Ord | ||
432 | at PartialEq, PartialOrd | 431 | at PartialEq, PartialOrd |
432 | at PartialEq, Eq, PartialOrd, Ord | ||
433 | "#]], | 433 | "#]], |
434 | ); | 434 | ); |
435 | } | 435 | } |
@@ -457,10 +457,10 @@ struct Test {} | |||
457 | at Clone, Copy | 457 | at Clone, Copy |
458 | at Debug | 458 | at Debug |
459 | at Default | 459 | at Default |
460 | at Eq | ||
461 | at Eq, PartialOrd, Ord | ||
462 | at Hash | 460 | at Hash |
461 | at Eq | ||
463 | at PartialOrd | 462 | at PartialOrd |
463 | at Eq, PartialOrd, Ord | ||
464 | "#]], | 464 | "#]], |
465 | ) | 465 | ) |
466 | } | 466 | } |
@@ -472,14 +472,14 @@ struct Test {} | |||
472 | expect![[r#" | 472 | expect![[r#" |
473 | at allow(…) | 473 | at allow(…) |
474 | at automatically_derived | 474 | at automatically_derived |
475 | at cfg(…) | ||
476 | at cfg_attr(…) | 475 | at cfg_attr(…) |
476 | at cfg(…) | ||
477 | at cold | 477 | at cold |
478 | at deny(…) | 478 | at deny(…) |
479 | at deprecated = "…" | 479 | at deprecated = "…" |
480 | at derive(…) | 480 | at derive(…) |
481 | at doc = "…" | ||
482 | at export_name = "…" | 481 | at export_name = "…" |
482 | at doc = "…" | ||
483 | at forbid(…) | 483 | at forbid(…) |
484 | at ignore = "…" | 484 | at ignore = "…" |
485 | at inline(…) | 485 | at inline(…) |
@@ -518,15 +518,15 @@ struct Test {} | |||
518 | expect![[r#" | 518 | expect![[r#" |
519 | at allow(…) | 519 | at allow(…) |
520 | at automatically_derived | 520 | at automatically_derived |
521 | at cfg(…) | ||
522 | at cfg_attr(…) | 521 | at cfg_attr(…) |
522 | at cfg(…) | ||
523 | at cold | 523 | at cold |
524 | at crate_name = "" | 524 | at crate_name = "" |
525 | at deny(…) | 525 | at deny(…) |
526 | at deprecated = "…" | 526 | at deprecated = "…" |
527 | at derive(…) | 527 | at derive(…) |
528 | at doc = "…" | ||
529 | at export_name = "…" | 528 | at export_name = "…" |
529 | at doc = "…" | ||
530 | at feature(…) | 530 | at feature(…) |
531 | at forbid(…) | 531 | at forbid(…) |
532 | at global_allocator | 532 | at global_allocator |
@@ -538,8 +538,8 @@ struct Test {} | |||
538 | at macro_export | 538 | at macro_export |
539 | at macro_use | 539 | at macro_use |
540 | at must_use = "…" | 540 | at must_use = "…" |
541 | at no_implicit_prelude | ||
542 | at no_link | 541 | at no_link |
542 | at no_implicit_prelude | ||
543 | at no_main | 543 | at no_main |
544 | at no_mangle | 544 | at no_mangle |
545 | at no_std | 545 | at no_std |
diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs index c9875045a..551ef1771 100644 --- a/crates/completion/src/completions/dot.rs +++ b/crates/completion/src/completions/dot.rs | |||
@@ -82,8 +82,8 @@ impl S { | |||
82 | fn foo(s: S) { s.<|> } | 82 | fn foo(s: S) { s.<|> } |
83 | "#, | 83 | "#, |
84 | expect![[r#" | 84 | expect![[r#" |
85 | me bar() fn bar(&self) | ||
86 | fd foo u32 | 85 | fd foo u32 |
86 | me bar() fn bar(&self) | ||
87 | "#]], | 87 | "#]], |
88 | ); | 88 | ); |
89 | } | 89 | } |
@@ -98,8 +98,8 @@ impl S { | |||
98 | } | 98 | } |
99 | "#, | 99 | "#, |
100 | expect![[r#" | 100 | expect![[r#" |
101 | me foo() fn foo(self) | ||
102 | fd the_field (u32,) | 101 | fd the_field (u32,) |
102 | me foo() fn foo(self) | ||
103 | "#]], | 103 | "#]], |
104 | ) | 104 | ) |
105 | } | 105 | } |
@@ -114,8 +114,8 @@ impl A { | |||
114 | } | 114 | } |
115 | "#, | 115 | "#, |
116 | expect![[r#" | 116 | expect![[r#" |
117 | me foo() fn foo(&self) | ||
118 | fd the_field (u32, i32) | 117 | fd the_field (u32, i32) |
118 | me foo() fn foo(&self) | ||
119 | "#]], | 119 | "#]], |
120 | ) | 120 | ) |
121 | } | 121 | } |
@@ -147,8 +147,8 @@ mod inner { | |||
147 | fn foo(a: inner::A) { a.<|> } | 147 | fn foo(a: inner::A) { a.<|> } |
148 | "#, | 148 | "#, |
149 | expect![[r#" | 149 | expect![[r#" |
150 | fd crate_field u32 | ||
151 | fd pub_field u32 | 150 | fd pub_field u32 |
151 | fd crate_field u32 | ||
152 | fd super_field u32 | 152 | fd super_field u32 |
153 | "#]], | 153 | "#]], |
154 | ); | 154 | ); |
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs index 720349b9d..1859dec70 100644 --- a/crates/completion/src/completions/keyword.rs +++ b/crates/completion/src/completions/keyword.rs | |||
@@ -223,21 +223,21 @@ mod tests { | |||
223 | check( | 223 | check( |
224 | r"m<|>", | 224 | r"m<|>", |
225 | expect![[r#" | 225 | expect![[r#" |
226 | kw const | ||
227 | kw enum | ||
228 | kw extern | ||
229 | kw fn | 226 | kw fn |
227 | kw use | ||
230 | kw impl | 228 | kw impl |
231 | kw mod | ||
232 | kw pub | ||
233 | kw pub(crate) | ||
234 | kw static | ||
235 | kw struct | ||
236 | kw trait | 229 | kw trait |
237 | kw type | 230 | kw enum |
231 | kw struct | ||
238 | kw union | 232 | kw union |
233 | kw mod | ||
234 | kw const | ||
235 | kw type | ||
236 | kw static | ||
237 | kw extern | ||
239 | kw unsafe | 238 | kw unsafe |
240 | kw use | 239 | kw pub(crate) |
240 | kw pub | ||
241 | "#]], | 241 | "#]], |
242 | ); | 242 | ); |
243 | } | 243 | } |
@@ -247,23 +247,23 @@ mod tests { | |||
247 | check( | 247 | check( |
248 | r"fn quux() { <|> }", | 248 | r"fn quux() { <|> }", |
249 | expect![[r#" | 249 | expect![[r#" |
250 | kw const | ||
251 | kw extern | ||
252 | kw fn | 250 | kw fn |
251 | kw use | ||
252 | kw impl | ||
253 | kw trait | ||
254 | kw match | ||
255 | kw while | ||
256 | kw loop | ||
253 | kw if | 257 | kw if |
254 | kw if let | 258 | kw if let |
255 | kw impl | ||
256 | kw let | 259 | kw let |
257 | kw loop | ||
258 | kw match | ||
259 | kw mod | 260 | kw mod |
260 | kw return | 261 | kw const |
261 | kw static | ||
262 | kw trait | ||
263 | kw type | 262 | kw type |
263 | kw static | ||
264 | kw extern | ||
264 | kw unsafe | 265 | kw unsafe |
265 | kw use | 266 | kw return |
266 | kw while | ||
267 | "#]], | 267 | "#]], |
268 | ); | 268 | ); |
269 | } | 269 | } |
@@ -273,23 +273,23 @@ mod tests { | |||
273 | check( | 273 | check( |
274 | r"fn quux() { if true { <|> } }", | 274 | r"fn quux() { if true { <|> } }", |
275 | expect![[r#" | 275 | expect![[r#" |
276 | kw const | ||
277 | kw extern | ||
278 | kw fn | 276 | kw fn |
277 | kw use | ||
278 | kw impl | ||
279 | kw trait | ||
280 | kw match | ||
281 | kw while | ||
282 | kw loop | ||
279 | kw if | 283 | kw if |
280 | kw if let | 284 | kw if let |
281 | kw impl | ||
282 | kw let | 285 | kw let |
283 | kw loop | ||
284 | kw match | ||
285 | kw mod | 286 | kw mod |
286 | kw return | 287 | kw const |
287 | kw static | ||
288 | kw trait | ||
289 | kw type | 288 | kw type |
289 | kw static | ||
290 | kw extern | ||
290 | kw unsafe | 291 | kw unsafe |
291 | kw use | 292 | kw return |
292 | kw while | ||
293 | "#]], | 293 | "#]], |
294 | ); | 294 | ); |
295 | } | 295 | } |
@@ -299,25 +299,25 @@ mod tests { | |||
299 | check( | 299 | check( |
300 | r#"fn quux() { if true { () } <|> }"#, | 300 | r#"fn quux() { if true { () } <|> }"#, |
301 | expect![[r#" | 301 | expect![[r#" |
302 | kw const | ||
303 | kw else | ||
304 | kw else if | ||
305 | kw extern | ||
306 | kw fn | 302 | kw fn |
303 | kw use | ||
304 | kw impl | ||
305 | kw trait | ||
306 | kw match | ||
307 | kw while | ||
308 | kw loop | ||
307 | kw if | 309 | kw if |
308 | kw if let | 310 | kw if let |
309 | kw impl | ||
310 | kw let | 311 | kw let |
311 | kw loop | 312 | kw else |
312 | kw match | 313 | kw else if |
313 | kw mod | 314 | kw mod |
314 | kw return | 315 | kw const |
315 | kw static | ||
316 | kw trait | ||
317 | kw type | 316 | kw type |
317 | kw static | ||
318 | kw extern | ||
318 | kw unsafe | 319 | kw unsafe |
319 | kw use | 320 | kw return |
320 | kw while | ||
321 | "#]], | 321 | "#]], |
322 | ); | 322 | ); |
323 | check_edit( | 323 | check_edit( |
@@ -336,13 +336,13 @@ fn quux() -> i32 { | |||
336 | } | 336 | } |
337 | "#, | 337 | "#, |
338 | expect![[r#" | 338 | expect![[r#" |
339 | kw match | ||
340 | kw while | ||
341 | kw loop | ||
339 | kw if | 342 | kw if |
340 | kw if let | 343 | kw if let |
341 | kw loop | ||
342 | kw match | ||
343 | kw return | ||
344 | kw unsafe | 344 | kw unsafe |
345 | kw while | 345 | kw return |
346 | "#]], | 346 | "#]], |
347 | ); | 347 | ); |
348 | } | 348 | } |
@@ -352,8 +352,8 @@ fn quux() -> i32 { | |||
352 | check( | 352 | check( |
353 | r"trait My { <|> }", | 353 | r"trait My { <|> }", |
354 | expect![[r#" | 354 | expect![[r#" |
355 | kw const | ||
356 | kw fn | 355 | kw fn |
356 | kw const | ||
357 | kw type | 357 | kw type |
358 | kw unsafe | 358 | kw unsafe |
359 | "#]], | 359 | "#]], |
@@ -365,12 +365,12 @@ fn quux() -> i32 { | |||
365 | check( | 365 | check( |
366 | r"impl My { <|> }", | 366 | r"impl My { <|> }", |
367 | expect![[r#" | 367 | expect![[r#" |
368 | kw const | ||
369 | kw fn | 368 | kw fn |
370 | kw pub | 369 | kw const |
371 | kw pub(crate) | ||
372 | kw type | 370 | kw type |
373 | kw unsafe | 371 | kw unsafe |
372 | kw pub(crate) | ||
373 | kw pub | ||
374 | "#]], | 374 | "#]], |
375 | ); | 375 | ); |
376 | } | 376 | } |
@@ -380,25 +380,25 @@ fn quux() -> i32 { | |||
380 | check( | 380 | check( |
381 | r"fn my() { loop { <|> } }", | 381 | r"fn my() { loop { <|> } }", |
382 | expect![[r#" | 382 | expect![[r#" |
383 | kw break | ||
384 | kw const | ||
385 | kw continue | ||
386 | kw extern | ||
387 | kw fn | 383 | kw fn |
384 | kw use | ||
385 | kw impl | ||
386 | kw trait | ||
387 | kw match | ||
388 | kw while | ||
389 | kw loop | ||
388 | kw if | 390 | kw if |
389 | kw if let | 391 | kw if let |
390 | kw impl | ||
391 | kw let | 392 | kw let |
392 | kw loop | ||
393 | kw match | ||
394 | kw mod | 393 | kw mod |
395 | kw return | 394 | kw const |
396 | kw static | ||
397 | kw trait | ||
398 | kw type | 395 | kw type |
396 | kw static | ||
397 | kw extern | ||
399 | kw unsafe | 398 | kw unsafe |
400 | kw use | 399 | kw continue |
401 | kw while | 400 | kw break |
401 | kw return | ||
402 | "#]], | 402 | "#]], |
403 | ); | 403 | ); |
404 | } | 404 | } |
@@ -409,8 +409,8 @@ fn quux() -> i32 { | |||
409 | r"unsafe <|>", | 409 | r"unsafe <|>", |
410 | expect![[r#" | 410 | expect![[r#" |
411 | kw fn | 411 | kw fn |
412 | kw impl | ||
413 | kw trait | 412 | kw trait |
413 | kw impl | ||
414 | "#]], | 414 | "#]], |
415 | ); | 415 | ); |
416 | } | 416 | } |
@@ -421,8 +421,8 @@ fn quux() -> i32 { | |||
421 | r"fn my_fn() { unsafe <|> }", | 421 | r"fn my_fn() { unsafe <|> }", |
422 | expect![[r#" | 422 | expect![[r#" |
423 | kw fn | 423 | kw fn |
424 | kw impl | ||
425 | kw trait | 424 | kw trait |
425 | kw impl | ||
426 | "#]], | 426 | "#]], |
427 | ); | 427 | ); |
428 | } | 428 | } |
@@ -542,12 +542,12 @@ pub mod future { | |||
542 | check( | 542 | check( |
543 | r#"fn main() { let _ = <|> }"#, | 543 | r#"fn main() { let _ = <|> }"#, |
544 | expect![[r#" | 544 | expect![[r#" |
545 | kw match | ||
546 | kw while | ||
547 | kw loop | ||
545 | kw if | 548 | kw if |
546 | kw if let | 549 | kw if let |
547 | kw loop | ||
548 | kw match | ||
549 | kw return | 550 | kw return |
550 | kw while | ||
551 | "#]], | 551 | "#]], |
552 | ) | 552 | ) |
553 | } | 553 | } |
@@ -562,8 +562,8 @@ struct Foo { | |||
562 | } | 562 | } |
563 | "#, | 563 | "#, |
564 | expect![[r#" | 564 | expect![[r#" |
565 | kw pub | ||
566 | kw pub(crate) | 565 | kw pub(crate) |
566 | kw pub | ||
567 | "#]], | 567 | "#]], |
568 | ) | 568 | ) |
569 | } | 569 | } |
@@ -600,12 +600,12 @@ fn foo() { | |||
600 | } | 600 | } |
601 | "#, | 601 | "#, |
602 | expect![[r#" | 602 | expect![[r#" |
603 | kw match | ||
604 | kw while | ||
605 | kw loop | ||
603 | kw if | 606 | kw if |
604 | kw if let | 607 | kw if let |
605 | kw loop | ||
606 | kw match | ||
607 | kw return | 608 | kw return |
608 | kw while | ||
609 | "#]], | 609 | "#]], |
610 | ); | 610 | ); |
611 | } | 611 | } |
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs index c96f84171..f77864b77 100644 --- a/crates/completion/src/completions/mod_.rs +++ b/crates/completion/src/completions/mod_.rs | |||
@@ -170,8 +170,8 @@ mod tests { | |||
170 | fn ignored_bar() {} | 170 | fn ignored_bar() {} |
171 | "#, | 171 | "#, |
172 | expect![[r#" | 172 | expect![[r#" |
173 | md bar; | ||
174 | md foo; | 173 | md foo; |
174 | md bar; | ||
175 | "#]], | 175 | "#]], |
176 | ); | 176 | ); |
177 | } | 177 | } |
@@ -207,8 +207,8 @@ mod tests { | |||
207 | fn ignored_bar() {} | 207 | fn ignored_bar() {} |
208 | "#, | 208 | "#, |
209 | expect![[r#" | 209 | expect![[r#" |
210 | md bar; | ||
211 | md foo; | 210 | md foo; |
211 | md bar; | ||
212 | "#]], | 212 | "#]], |
213 | ); | 213 | ); |
214 | } | 214 | } |
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs index 4f63ff0ef..4d56731ec 100644 --- a/crates/completion/src/completions/pattern.rs +++ b/crates/completion/src/completions/pattern.rs | |||
@@ -23,7 +23,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
23 | def, | 23 | def, |
24 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 24 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) |
25 | | hir::ModuleDef::Adt(hir::Adt::Struct(..)) | 25 | | hir::ModuleDef::Adt(hir::Adt::Struct(..)) |
26 | | hir::ModuleDef::EnumVariant(..) | 26 | | hir::ModuleDef::Variant(..) |
27 | | hir::ModuleDef::Const(..) | 27 | | hir::ModuleDef::Const(..) |
28 | | hir::ModuleDef::Module(..) | 28 | | hir::ModuleDef::Module(..) |
29 | ) | 29 | ) |
@@ -66,10 +66,10 @@ fn foo() { | |||
66 | } | 66 | } |
67 | "#, | 67 | "#, |
68 | expect![[r#" | 68 | expect![[r#" |
69 | st Bar | ||
70 | en E | 69 | en E |
71 | ev X () | ||
72 | ct Z | 70 | ct Z |
71 | st Bar | ||
72 | ev X () | ||
73 | md m | 73 | md m |
74 | "#]], | 74 | "#]], |
75 | ); | 75 | ); |
diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs index c8ba63cd3..d6db82a93 100644 --- a/crates/completion/src/completions/postfix.rs +++ b/crates/completion/src/completions/postfix.rs | |||
@@ -315,20 +315,20 @@ fn main() { | |||
315 | } | 315 | } |
316 | "#, | 316 | "#, |
317 | expect![[r#" | 317 | expect![[r#" |
318 | sn box Box::new(expr) | ||
319 | sn call function(expr) | ||
320 | sn dbg dbg!(expr) | ||
321 | sn dbgr dbg!(&expr) | ||
322 | sn if if expr {} | 318 | sn if if expr {} |
323 | sn let let | 319 | sn while while expr {} |
324 | sn letm let mut | ||
325 | sn match match expr {} | ||
326 | sn not !expr | 320 | sn not !expr |
327 | sn ok Ok(expr) | ||
328 | sn ref &expr | 321 | sn ref &expr |
329 | sn refm &mut expr | 322 | sn refm &mut expr |
323 | sn match match expr {} | ||
324 | sn box Box::new(expr) | ||
325 | sn ok Ok(expr) | ||
330 | sn some Some(expr) | 326 | sn some Some(expr) |
331 | sn while while expr {} | 327 | sn dbg dbg!(expr) |
328 | sn dbgr dbg!(&expr) | ||
329 | sn call function(expr) | ||
330 | sn let let | ||
331 | sn letm let mut | ||
332 | "#]], | 332 | "#]], |
333 | ); | 333 | ); |
334 | } | 334 | } |
@@ -347,18 +347,18 @@ fn main() { | |||
347 | } | 347 | } |
348 | "#, | 348 | "#, |
349 | expect![[r#" | 349 | expect![[r#" |
350 | sn box Box::new(expr) | ||
351 | sn call function(expr) | ||
352 | sn dbg dbg!(expr) | ||
353 | sn dbgr dbg!(&expr) | ||
354 | sn if if expr {} | 350 | sn if if expr {} |
355 | sn match match expr {} | 351 | sn while while expr {} |
356 | sn not !expr | 352 | sn not !expr |
357 | sn ok Ok(expr) | ||
358 | sn ref &expr | 353 | sn ref &expr |
359 | sn refm &mut expr | 354 | sn refm &mut expr |
355 | sn match match expr {} | ||
356 | sn box Box::new(expr) | ||
357 | sn ok Ok(expr) | ||
360 | sn some Some(expr) | 358 | sn some Some(expr) |
361 | sn while while expr {} | 359 | sn dbg dbg!(expr) |
360 | sn dbgr dbg!(&expr) | ||
361 | sn call function(expr) | ||
362 | "#]], | 362 | "#]], |
363 | ); | 363 | ); |
364 | } | 364 | } |
@@ -373,17 +373,17 @@ fn main() { | |||
373 | } | 373 | } |
374 | "#, | 374 | "#, |
375 | expect![[r#" | 375 | expect![[r#" |
376 | sn ref &expr | ||
377 | sn refm &mut expr | ||
378 | sn match match expr {} | ||
376 | sn box Box::new(expr) | 379 | sn box Box::new(expr) |
377 | sn call function(expr) | 380 | sn ok Ok(expr) |
381 | sn some Some(expr) | ||
378 | sn dbg dbg!(expr) | 382 | sn dbg dbg!(expr) |
379 | sn dbgr dbg!(&expr) | 383 | sn dbgr dbg!(&expr) |
384 | sn call function(expr) | ||
380 | sn let let | 385 | sn let let |
381 | sn letm let mut | 386 | sn letm let mut |
382 | sn match match expr {} | ||
383 | sn ok Ok(expr) | ||
384 | sn ref &expr | ||
385 | sn refm &mut expr | ||
386 | sn some Some(expr) | ||
387 | "#]], | 387 | "#]], |
388 | ) | 388 | ) |
389 | } | 389 | } |
@@ -398,20 +398,20 @@ fn main() { | |||
398 | } | 398 | } |
399 | "#, | 399 | "#, |
400 | expect![[r#" | 400 | expect![[r#" |
401 | sn box Box::new(expr) | ||
402 | sn call function(expr) | ||
403 | sn dbg dbg!(expr) | ||
404 | sn dbgr dbg!(&expr) | ||
405 | sn if if expr {} | 401 | sn if if expr {} |
406 | sn let let | 402 | sn while while expr {} |
407 | sn letm let mut | ||
408 | sn match match expr {} | ||
409 | sn not !expr | 403 | sn not !expr |
410 | sn ok Ok(expr) | ||
411 | sn ref &expr | 404 | sn ref &expr |
412 | sn refm &mut expr | 405 | sn refm &mut expr |
406 | sn match match expr {} | ||
407 | sn box Box::new(expr) | ||
408 | sn ok Ok(expr) | ||
413 | sn some Some(expr) | 409 | sn some Some(expr) |
414 | sn while while expr {} | 410 | sn dbg dbg!(expr) |
411 | sn dbgr dbg!(&expr) | ||
412 | sn call function(expr) | ||
413 | sn let let | ||
414 | sn letm let mut | ||
415 | "#]], | 415 | "#]], |
416 | ); | 416 | ); |
417 | } | 417 | } |
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs index bc23bea3f..1300f00b2 100644 --- a/crates/completion/src/completions/qualified_path.rs +++ b/crates/completion/src/completions/qualified_path.rs | |||
@@ -199,22 +199,22 @@ use self::{foo::*, bar<|>}; | |||
199 | check_builtin( | 199 | check_builtin( |
200 | r#"fn main() { let _: <|> = 92; }"#, | 200 | r#"fn main() { let _: <|> = 92; }"#, |
201 | expect![[r#" | 201 | expect![[r#" |
202 | bt u32 | ||
202 | bt bool | 203 | bt bool |
203 | bt char | 204 | bt u8 |
205 | bt isize | ||
206 | bt u16 | ||
207 | bt u64 | ||
208 | bt u128 | ||
204 | bt f32 | 209 | bt f32 |
205 | bt f64 | ||
206 | bt i128 | 210 | bt i128 |
207 | bt i16 | 211 | bt i16 |
208 | bt i32 | 212 | bt str |
209 | bt i64 | 213 | bt i64 |
214 | bt char | ||
215 | bt f64 | ||
216 | bt i32 | ||
210 | bt i8 | 217 | bt i8 |
211 | bt isize | ||
212 | bt str | ||
213 | bt u128 | ||
214 | bt u16 | ||
215 | bt u32 | ||
216 | bt u64 | ||
217 | bt u8 | ||
218 | bt usize | 218 | bt usize |
219 | "#]], | 219 | "#]], |
220 | ); | 220 | ); |
@@ -279,8 +279,8 @@ struct Spam; | |||
279 | use crate::Sp<|> | 279 | use crate::Sp<|> |
280 | "#, | 280 | "#, |
281 | expect![[r#" | 281 | expect![[r#" |
282 | st Spam | ||
283 | md foo | 282 | md foo |
283 | st Spam | ||
284 | "#]], | 284 | "#]], |
285 | ); | 285 | ); |
286 | } | 286 | } |
@@ -296,8 +296,8 @@ struct Spam; | |||
296 | use crate::{Sp<|>}; | 296 | use crate::{Sp<|>}; |
297 | "#, | 297 | "#, |
298 | expect![[r#" | 298 | expect![[r#" |
299 | st Spam | ||
300 | md foo | 299 | md foo |
300 | st Spam | ||
301 | "#]], | 301 | "#]], |
302 | ); | 302 | ); |
303 | } | 303 | } |
@@ -330,8 +330,8 @@ enum E { Foo, Bar(i32) } | |||
330 | fn foo() { let _ = E::<|> } | 330 | fn foo() { let _ = E::<|> } |
331 | "#, | 331 | "#, |
332 | expect![[r#" | 332 | expect![[r#" |
333 | ev Bar(…) (i32) | ||
334 | ev Foo () | 333 | ev Foo () |
334 | ev Bar(…) (i32) | ||
335 | "#]], | 335 | "#]], |
336 | ); | 336 | ); |
337 | } | 337 | } |
@@ -353,10 +353,10 @@ impl S { | |||
353 | fn foo() { let _ = S::<|> } | 353 | fn foo() { let _ = S::<|> } |
354 | "#, | 354 | "#, |
355 | expect![[r#" | 355 | expect![[r#" |
356 | ct C const C: i32 = 42; | ||
357 | ta T type T = i32; | ||
358 | fn a() fn a() | 356 | fn a() fn a() |
359 | me b(…) fn b(&self) | 357 | me b(…) fn b(&self) |
358 | ct C const C: i32 = 42; | ||
359 | ta T type T = i32; | ||
360 | "#]], | 360 | "#]], |
361 | ); | 361 | ); |
362 | } | 362 | } |
@@ -381,9 +381,9 @@ mod m { | |||
381 | fn foo() { let _ = S::<|> } | 381 | fn foo() { let _ = S::<|> } |
382 | "#, | 382 | "#, |
383 | expect![[r#" | 383 | expect![[r#" |
384 | fn public_method() pub(crate) fn public_method() | ||
384 | ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; | 385 | ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; |
385 | ta PublicType pub(crate) type PublicType = u32; | 386 | ta PublicType pub(crate) type PublicType = u32; |
386 | fn public_method() pub(crate) fn public_method() | ||
387 | "#]], | 387 | "#]], |
388 | ); | 388 | ); |
389 | } | 389 | } |
@@ -503,14 +503,14 @@ trait Sub: Super { | |||
503 | fn foo<T: Sub>() { T::<|> } | 503 | fn foo<T: Sub>() { T::<|> } |
504 | "#, | 504 | "#, |
505 | expect![[r#" | 505 | expect![[r#" |
506 | ct C2 const C2: (); | ||
507 | ct CONST const CONST: u8; | ||
508 | ta SubTy type SubTy; | 506 | ta SubTy type SubTy; |
509 | ta Ty type Ty; | 507 | ta Ty type Ty; |
510 | fn func() fn func() | 508 | ct C2 const C2: (); |
511 | me method(…) fn method(&self) | ||
512 | fn subfunc() fn subfunc() | 509 | fn subfunc() fn subfunc() |
513 | me submethod(…) fn submethod(&self) | 510 | me submethod(…) fn submethod(&self) |
511 | ct CONST const CONST: u8; | ||
512 | fn func() fn func() | ||
513 | me method(…) fn method(&self) | ||
514 | "#]], | 514 | "#]], |
515 | ); | 515 | ); |
516 | } | 516 | } |
@@ -543,12 +543,12 @@ impl<T> Sub for Wrap<T> { | |||
543 | } | 543 | } |
544 | "#, | 544 | "#, |
545 | expect![[r#" | 545 | expect![[r#" |
546 | ct C2 const C2: () = (); | ||
547 | ct CONST const CONST: u8 = 0; | ||
548 | ta SubTy type SubTy; | 546 | ta SubTy type SubTy; |
549 | ta Ty type Ty; | 547 | ta Ty type Ty; |
548 | ct CONST const CONST: u8 = 0; | ||
550 | fn func() fn func() | 549 | fn func() fn func() |
551 | me method(…) fn method(&self) | 550 | me method(…) fn method(&self) |
551 | ct C2 const C2: () = (); | ||
552 | fn subfunc() fn subfunc() | 552 | fn subfunc() fn subfunc() |
553 | me submethod(…) fn submethod(&self) | 553 | me submethod(…) fn submethod(&self) |
554 | "#]], | 554 | "#]], |
@@ -567,8 +567,8 @@ impl T { fn bar() {} } | |||
567 | fn main() { T::<|>; } | 567 | fn main() { T::<|>; } |
568 | "#, | 568 | "#, |
569 | expect![[r#" | 569 | expect![[r#" |
570 | fn bar() fn bar() | ||
571 | fn foo() fn foo() | 570 | fn foo() fn foo() |
571 | fn bar() fn bar() | ||
572 | "#]], | 572 | "#]], |
573 | ); | 573 | ); |
574 | } | 574 | } |
@@ -583,9 +583,9 @@ macro_rules! foo { () => {} } | |||
583 | fn main() { let _ = crate::<|> } | 583 | fn main() { let _ = crate::<|> } |
584 | "#, | 584 | "#, |
585 | expect![[r##" | 585 | expect![[r##" |
586 | fn main() fn main() | ||
586 | ma foo!(…) #[macro_export] | 587 | ma foo!(…) #[macro_export] |
587 | macro_rules! foo | 588 | macro_rules! foo |
588 | fn main() fn main() | ||
589 | "##]], | 589 | "##]], |
590 | ); | 590 | ); |
591 | } | 591 | } |
@@ -603,8 +603,8 @@ mod a { | |||
603 | } | 603 | } |
604 | "#, | 604 | "#, |
605 | expect![[r#" | 605 | expect![[r#" |
606 | ct A | ||
607 | md b | 606 | md b |
607 | ct A | ||
608 | "#]], | 608 | "#]], |
609 | ); | 609 | ); |
610 | } | 610 | } |
@@ -628,8 +628,8 @@ mod p { | |||
628 | "#, | 628 | "#, |
629 | expect![[r#" | 629 | expect![[r#" |
630 | ct RIGHT_CONST | 630 | ct RIGHT_CONST |
631 | st RightType | ||
632 | fn right_fn() fn wrong_fn() | 631 | fn right_fn() fn wrong_fn() |
632 | st RightType | ||
633 | "#]], | 633 | "#]], |
634 | ); | 634 | ); |
635 | 635 | ||
@@ -675,8 +675,8 @@ fn main() { m!(self::f<|>); } | |||
675 | fn foo() {} | 675 | fn foo() {} |
676 | "#, | 676 | "#, |
677 | expect![[r#" | 677 | expect![[r#" |
678 | fn foo() fn foo() | ||
679 | fn main() fn main() | 678 | fn main() fn main() |
679 | fn foo() fn foo() | ||
680 | "#]], | 680 | "#]], |
681 | ); | 681 | ); |
682 | } | 682 | } |
@@ -747,8 +747,8 @@ fn main() { | |||
747 | } | 747 | } |
748 | "#, | 748 | "#, |
749 | expect![[r#" | 749 | expect![[r#" |
750 | fn foo(…) fn foo(a: i32, b: i32) | ||
751 | fn main() fn main() | 750 | fn main() fn main() |
751 | fn foo(…) fn foo(a: i32, b: i32) | ||
752 | "#]], | 752 | "#]], |
753 | ); | 753 | ); |
754 | } | 754 | } |
diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs index eaa44c97d..91bf4a8ad 100644 --- a/crates/completion/src/completions/record.rs +++ b/crates/completion/src/completions/record.rs | |||
@@ -94,9 +94,9 @@ fn process(f: S) { | |||
94 | check_snippet( | 94 | check_snippet( |
95 | test_code, | 95 | test_code, |
96 | expect![[r#" | 96 | expect![[r#" |
97 | fd ..Default::default() | ||
98 | sn pd | 97 | sn pd |
99 | sn ppd | 98 | sn ppd |
99 | fd ..Default::default() | ||
100 | "#]], | 100 | "#]], |
101 | ); | 101 | ); |
102 | } | 102 | } |
@@ -160,8 +160,8 @@ fn process(e: E) { | |||
160 | } | 160 | } |
161 | "#, | 161 | "#, |
162 | expect![[r#" | 162 | expect![[r#" |
163 | fd bar () | ||
164 | fd foo u32 | 163 | fd foo u32 |
164 | fd bar () | ||
165 | "#]], | 165 | "#]], |
166 | ); | 166 | ); |
167 | } | 167 | } |
diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs index 6f0c00078..842590130 100644 --- a/crates/completion/src/completions/snippet.rs +++ b/crates/completion/src/completions/snippet.rs | |||
@@ -105,9 +105,9 @@ mod tests { | |||
105 | } | 105 | } |
106 | "#, | 106 | "#, |
107 | expect![[r#" | 107 | expect![[r#" |
108 | sn macro_rules | ||
109 | sn tfn (Test function) | ||
110 | sn tmod (Test module) | 108 | sn tmod (Test module) |
109 | sn tfn (Test function) | ||
110 | sn macro_rules | ||
111 | "#]], | 111 | "#]], |
112 | ) | 112 | ) |
113 | } | 113 | } |
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs index e2fe44aff..c4e0d0669 100644 --- a/crates/completion/src/completions/trait_impl.rs +++ b/crates/completion/src/completions/trait_impl.rs | |||
@@ -266,10 +266,10 @@ impl Test for T { | |||
266 | } | 266 | } |
267 | "#, | 267 | "#, |
268 | expect![[" | 268 | expect![[" |
269 | ta type TestType = \n\ | ||
269 | ct const TEST_CONST: u16 = \n\ | 270 | ct const TEST_CONST: u16 = \n\ |
270 | fn fn test() | 271 | fn fn test() |
271 | ta type TestType = \n\ | 272 | "]], |
272 | "]], | ||
273 | ); | 273 | ); |
274 | } | 274 | } |
275 | 275 | ||
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index b9315f6c0..099ffb4d4 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Completion of names from the current scope, e.g. locals and imported items. | 1 | //! Completion of names from the current scope, e.g. locals and imported items. |
2 | 2 | ||
3 | use either::Either; | 3 | use either::Either; |
4 | use hir::{Adt, ModuleDef, ScopeDef, Type}; | 4 | use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type}; |
5 | use ide_db::helpers::insert_use::ImportScope; | 5 | use ide_db::helpers::insert_use::ImportScope; |
6 | use ide_db::imports_locator; | 6 | use ide_db::imports_locator; |
7 | use syntax::AstNode; | 7 | use syntax::AstNode; |
@@ -126,7 +126,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<() | |||
126 | let anchor = ctx.name_ref_syntax.as_ref()?; | 126 | let anchor = ctx.name_ref_syntax.as_ref()?; |
127 | let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; | 127 | let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; |
128 | 128 | ||
129 | let possible_imports = imports_locator::find_similar_imports( | 129 | let mut all_mod_paths = imports_locator::find_similar_imports( |
130 | &ctx.sema, | 130 | &ctx.sema, |
131 | ctx.krate?, | 131 | ctx.krate?, |
132 | Some(100), | 132 | Some(100), |
@@ -144,33 +144,65 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<() | |||
144 | }) | 144 | }) |
145 | }) | 145 | }) |
146 | .filter(|(mod_path, _)| mod_path.len() > 1) | 146 | .filter(|(mod_path, _)| mod_path.len() > 1) |
147 | .filter_map(|(import_path, definition)| { | 147 | .collect::<Vec<_>>(); |
148 | |||
149 | let user_input_lowercased = potential_import_name.to_lowercase(); | ||
150 | all_mod_paths.sort_by_cached_key(|(mod_path, _)| { | ||
151 | compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased) | ||
152 | }); | ||
153 | |||
154 | acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| { | ||
148 | render_resolution_with_import( | 155 | render_resolution_with_import( |
149 | RenderContext::new(ctx), | 156 | RenderContext::new(ctx), |
150 | ImportEdit { import_path, import_scope: import_scope.clone() }, | 157 | ImportEdit { import_path, import_scope: import_scope.clone() }, |
151 | &definition, | 158 | &definition, |
152 | ) | 159 | ) |
153 | }); | 160 | })); |
154 | |||
155 | acc.add_all(possible_imports); | ||
156 | Some(()) | 161 | Some(()) |
157 | } | 162 | } |
158 | 163 | ||
164 | fn compute_fuzzy_completion_order_key( | ||
165 | proposed_mod_path: &ModPath, | ||
166 | user_input_lowercased: &str, | ||
167 | ) -> usize { | ||
168 | mark::hit!(certain_fuzzy_order_test); | ||
169 | let proposed_import_name = match proposed_mod_path.segments.last() { | ||
170 | Some(name) => name.to_string().to_lowercase(), | ||
171 | None => return usize::MAX, | ||
172 | }; | ||
173 | match proposed_import_name.match_indices(user_input_lowercased).next() { | ||
174 | Some((first_matching_index, _)) => first_matching_index, | ||
175 | None => usize::MAX, | ||
176 | } | ||
177 | } | ||
178 | |||
159 | #[cfg(test)] | 179 | #[cfg(test)] |
160 | mod tests { | 180 | mod tests { |
161 | use expect_test::{expect, Expect}; | 181 | use expect_test::{expect, Expect}; |
162 | use test_utils::mark; | 182 | use test_utils::mark; |
163 | 183 | ||
164 | use crate::{ | 184 | use crate::{ |
165 | test_utils::{check_edit, check_edit_with_config, completion_list}, | 185 | test_utils::{check_edit, check_edit_with_config, completion_list_with_config}, |
166 | CompletionConfig, CompletionKind, | 186 | CompletionConfig, CompletionKind, |
167 | }; | 187 | }; |
168 | 188 | ||
169 | fn check(ra_fixture: &str, expect: Expect) { | 189 | fn check(ra_fixture: &str, expect: Expect) { |
170 | let actual = completion_list(ra_fixture, CompletionKind::Reference); | 190 | check_with_config(CompletionConfig::default(), ra_fixture, expect); |
191 | } | ||
192 | |||
193 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { | ||
194 | let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference); | ||
171 | expect.assert_eq(&actual) | 195 | expect.assert_eq(&actual) |
172 | } | 196 | } |
173 | 197 | ||
198 | fn fuzzy_completion_config() -> CompletionConfig { | ||
199 | let mut completion_config = CompletionConfig::default(); | ||
200 | completion_config | ||
201 | .active_resolve_capabilities | ||
202 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
203 | completion_config | ||
204 | } | ||
205 | |||
174 | #[test] | 206 | #[test] |
175 | fn self_fulfilling_completion() { | 207 | fn self_fulfilling_completion() { |
176 | mark::check!(self_fulfilling_completion); | 208 | mark::check!(self_fulfilling_completion); |
@@ -246,9 +278,9 @@ fn quux(x: i32) { | |||
246 | } | 278 | } |
247 | "#, | 279 | "#, |
248 | expect![[r#" | 280 | expect![[r#" |
249 | fn quux(…) fn quux(x: i32) | ||
250 | bn x i32 | ||
251 | bn y i32 | 281 | bn y i32 |
282 | bn x i32 | ||
283 | fn quux(…) fn quux(x: i32) | ||
252 | "#]], | 284 | "#]], |
253 | ); | 285 | ); |
254 | } | 286 | } |
@@ -268,8 +300,8 @@ fn quux() { | |||
268 | } | 300 | } |
269 | "#, | 301 | "#, |
270 | expect![[r#" | 302 | expect![[r#" |
271 | bn a | ||
272 | bn b i32 | 303 | bn b i32 |
304 | bn a | ||
273 | fn quux() fn quux() | 305 | fn quux() fn quux() |
274 | "#]], | 306 | "#]], |
275 | ); | 307 | ); |
@@ -284,8 +316,8 @@ fn quux() { | |||
284 | } | 316 | } |
285 | "#, | 317 | "#, |
286 | expect![[r#" | 318 | expect![[r#" |
287 | fn quux() fn quux() | ||
288 | bn x | 319 | bn x |
320 | fn quux() fn quux() | ||
289 | "#]], | 321 | "#]], |
290 | ); | 322 | ); |
291 | } | 323 | } |
@@ -326,9 +358,9 @@ fn main() { | |||
326 | check( | 358 | check( |
327 | r#"struct S<T> { x: <|>}"#, | 359 | r#"struct S<T> { x: <|>}"#, |
328 | expect![[r#" | 360 | expect![[r#" |
329 | st S<…> | ||
330 | tp Self | 361 | tp Self |
331 | tp T | 362 | tp T |
363 | st S<…> | ||
332 | "#]], | 364 | "#]], |
333 | ); | 365 | ); |
334 | } | 366 | } |
@@ -353,9 +385,9 @@ enum E {} | |||
353 | fn quux() { <|> } | 385 | fn quux() { <|> } |
354 | "#, | 386 | "#, |
355 | expect![[r#" | 387 | expect![[r#" |
356 | en E | ||
357 | st S | 388 | st S |
358 | fn quux() fn quux() | 389 | fn quux() fn quux() |
390 | en E | ||
359 | "#]], | 391 | "#]], |
360 | ); | 392 | ); |
361 | } | 393 | } |
@@ -407,8 +439,8 @@ mod m { | |||
407 | } | 439 | } |
408 | "#, | 440 | "#, |
409 | expect![[r#" | 441 | expect![[r#" |
410 | st Bar | ||
411 | fn quux() fn quux() | 442 | fn quux() fn quux() |
443 | st Bar | ||
412 | "#]], | 444 | "#]], |
413 | ); | 445 | ); |
414 | } | 446 | } |
@@ -453,8 +485,8 @@ fn foo() { | |||
453 | check( | 485 | check( |
454 | r#"impl S { fn foo(&self) { <|> } }"#, | 486 | r#"impl S { fn foo(&self) { <|> } }"#, |
455 | expect![[r#" | 487 | expect![[r#" |
456 | tp Self | ||
457 | bn self &{unknown} | 488 | bn self &{unknown} |
489 | tp Self | ||
458 | "#]], | 490 | "#]], |
459 | ); | 491 | ); |
460 | } | 492 | } |
@@ -473,9 +505,9 @@ use prelude::*; | |||
473 | mod prelude { struct Option; } | 505 | mod prelude { struct Option; } |
474 | "#, | 506 | "#, |
475 | expect![[r#" | 507 | expect![[r#" |
476 | st Option | ||
477 | fn foo() fn foo() | 508 | fn foo() fn foo() |
478 | md std | 509 | md std |
510 | st Option | ||
479 | "#]], | 511 | "#]], |
480 | ); | 512 | ); |
481 | } | 513 | } |
@@ -500,10 +532,10 @@ use prelude::*; | |||
500 | mod prelude { struct String; } | 532 | mod prelude { struct String; } |
501 | "#, | 533 | "#, |
502 | expect![[r#" | 534 | expect![[r#" |
503 | st String | ||
504 | md core | ||
505 | fn foo() fn foo() | 535 | fn foo() fn foo() |
506 | md std | 536 | md std |
537 | md core | ||
538 | st String | ||
507 | "#]], | 539 | "#]], |
508 | ); | 540 | ); |
509 | } | 541 | } |
@@ -529,13 +561,13 @@ mod m2 { | |||
529 | fn main() { let v = <|> } | 561 | fn main() { let v = <|> } |
530 | "#, | 562 | "#, |
531 | expect![[r##" | 563 | expect![[r##" |
532 | ma bar!(…) macro_rules! bar | 564 | md m1 |
533 | ma baz!(…) #[macro_export] | 565 | ma baz!(…) #[macro_export] |
534 | macro_rules! baz | 566 | macro_rules! baz |
535 | ma foo!(…) macro_rules! foo | ||
536 | md m1 | ||
537 | md m2 | ||
538 | fn main() fn main() | 567 | fn main() fn main() |
568 | md m2 | ||
569 | ma bar!(…) macro_rules! bar | ||
570 | ma foo!(…) macro_rules! foo | ||
539 | "##]], | 571 | "##]], |
540 | ); | 572 | ); |
541 | } | 573 | } |
@@ -548,8 +580,8 @@ macro_rules! foo { () => {} } | |||
548 | fn foo() { <|> } | 580 | fn foo() { <|> } |
549 | "#, | 581 | "#, |
550 | expect![[r#" | 582 | expect![[r#" |
551 | ma foo!(…) macro_rules! foo | ||
552 | fn foo() fn foo() | 583 | fn foo() fn foo() |
584 | ma foo!(…) macro_rules! foo | ||
553 | "#]], | 585 | "#]], |
554 | ); | 586 | ); |
555 | } | 587 | } |
@@ -562,8 +594,8 @@ macro_rules! foo { () => {} } | |||
562 | fn main() { let x: <|> } | 594 | fn main() { let x: <|> } |
563 | "#, | 595 | "#, |
564 | expect![[r#" | 596 | expect![[r#" |
565 | ma foo!(…) macro_rules! foo | ||
566 | fn main() fn main() | 597 | fn main() fn main() |
598 | ma foo!(…) macro_rules! foo | ||
567 | "#]], | 599 | "#]], |
568 | ); | 600 | ); |
569 | } | 601 | } |
@@ -576,8 +608,8 @@ macro_rules! foo { () => {} } | |||
576 | fn main() { <|> } | 608 | fn main() { <|> } |
577 | "#, | 609 | "#, |
578 | expect![[r#" | 610 | expect![[r#" |
579 | ma foo!(…) macro_rules! foo | ||
580 | fn main() fn main() | 611 | fn main() fn main() |
612 | ma foo!(…) macro_rules! foo | ||
581 | "#]], | 613 | "#]], |
582 | ); | 614 | ); |
583 | } | 615 | } |
@@ -609,10 +641,10 @@ fn quux(x: i32) { | |||
609 | } | 641 | } |
610 | "#, | 642 | "#, |
611 | expect![[r#" | 643 | expect![[r#" |
612 | ma m!(…) macro_rules! m | ||
613 | fn quux(…) fn quux(x: i32) | ||
614 | bn x i32 | ||
615 | bn y i32 | 644 | bn y i32 |
645 | bn x i32 | ||
646 | fn quux(…) fn quux(x: i32) | ||
647 | ma m!(…) macro_rules! m | ||
616 | "#]], | 648 | "#]], |
617 | ); | 649 | ); |
618 | } | 650 | } |
@@ -628,10 +660,10 @@ fn quux(x: i32) { | |||
628 | } | 660 | } |
629 | ", | 661 | ", |
630 | expect![[r#" | 662 | expect![[r#" |
631 | ma m!(…) macro_rules! m | ||
632 | fn quux(…) fn quux(x: i32) | ||
633 | bn x i32 | ||
634 | bn y i32 | 663 | bn y i32 |
664 | bn x i32 | ||
665 | fn quux(…) fn quux(x: i32) | ||
666 | ma m!(…) macro_rules! m | ||
635 | "#]], | 667 | "#]], |
636 | ); | 668 | ); |
637 | } | 669 | } |
@@ -647,10 +679,10 @@ fn quux(x: i32) { | |||
647 | } | 679 | } |
648 | "#, | 680 | "#, |
649 | expect![[r#" | 681 | expect![[r#" |
650 | ma m!(…) macro_rules! m | ||
651 | fn quux(…) fn quux(x: i32) | ||
652 | bn x i32 | ||
653 | bn y i32 | 682 | bn y i32 |
683 | bn x i32 | ||
684 | fn quux(…) fn quux(x: i32) | ||
685 | ma m!(…) macro_rules! m | ||
654 | "#]], | 686 | "#]], |
655 | ); | 687 | ); |
656 | } | 688 | } |
@@ -664,8 +696,8 @@ use spam::Quux; | |||
664 | fn main() { <|> } | 696 | fn main() { <|> } |
665 | "#, | 697 | "#, |
666 | expect![[r#" | 698 | expect![[r#" |
667 | ?? Quux | ||
668 | fn main() fn main() | 699 | fn main() fn main() |
700 | ?? Quux | ||
669 | "#]], | 701 | "#]], |
670 | ); | 702 | ); |
671 | } | 703 | } |
@@ -681,10 +713,10 @@ fn main() { | |||
681 | } | 713 | } |
682 | "#, | 714 | "#, |
683 | expect![[r#" | 715 | expect![[r#" |
684 | en Foo | ||
685 | ev Foo::Bar () | 716 | ev Foo::Bar () |
686 | ev Foo::Baz () | 717 | ev Foo::Baz () |
687 | ev Foo::Quux () | 718 | ev Foo::Quux () |
719 | en Foo | ||
688 | "#]], | 720 | "#]], |
689 | ) | 721 | ) |
690 | } | 722 | } |
@@ -701,10 +733,10 @@ fn main() { | |||
701 | } | 733 | } |
702 | "#, | 734 | "#, |
703 | expect![[r#" | 735 | expect![[r#" |
704 | en Foo | ||
705 | ev Foo::Bar () | 736 | ev Foo::Bar () |
706 | ev Foo::Baz () | 737 | ev Foo::Baz () |
707 | ev Foo::Quux () | 738 | ev Foo::Quux () |
739 | en Foo | ||
708 | "#]], | 740 | "#]], |
709 | ) | 741 | ) |
710 | } | 742 | } |
@@ -717,10 +749,10 @@ enum Foo { Bar, Baz, Quux } | |||
717 | fn main() { let foo: Foo = Q<|> } | 749 | fn main() { let foo: Foo = Q<|> } |
718 | "#, | 750 | "#, |
719 | expect![[r#" | 751 | expect![[r#" |
720 | en Foo | ||
721 | ev Foo::Bar () | 752 | ev Foo::Bar () |
722 | ev Foo::Baz () | 753 | ev Foo::Baz () |
723 | ev Foo::Quux () | 754 | ev Foo::Quux () |
755 | en Foo | ||
724 | fn main() fn main() | 756 | fn main() fn main() |
725 | "#]], | 757 | "#]], |
726 | ) | 758 | ) |
@@ -734,9 +766,9 @@ mod m { pub enum E { V } } | |||
734 | fn f() -> m::E { V<|> } | 766 | fn f() -> m::E { V<|> } |
735 | "#, | 767 | "#, |
736 | expect![[r#" | 768 | expect![[r#" |
737 | fn f() fn f() -> m::E | ||
738 | md m | ||
739 | ev m::E::V () | 769 | ev m::E::V () |
770 | md m | ||
771 | fn f() fn f() -> m::E | ||
740 | "#]], | 772 | "#]], |
741 | ) | 773 | ) |
742 | } | 774 | } |
@@ -763,22 +795,17 @@ struct MyStruct {} | |||
763 | impl My<|> | 795 | impl My<|> |
764 | "#, | 796 | "#, |
765 | expect![[r#" | 797 | expect![[r#" |
766 | st MyStruct | ||
767 | tt MyTrait | ||
768 | tp Self | 798 | tp Self |
799 | tt MyTrait | ||
800 | st MyStruct | ||
769 | "#]], | 801 | "#]], |
770 | ) | 802 | ) |
771 | } | 803 | } |
772 | 804 | ||
773 | #[test] | 805 | #[test] |
774 | fn function_fuzzy_completion() { | 806 | fn function_fuzzy_completion() { |
775 | let mut completion_config = CompletionConfig::default(); | ||
776 | completion_config | ||
777 | .active_resolve_capabilities | ||
778 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
779 | |||
780 | check_edit_with_config( | 807 | check_edit_with_config( |
781 | completion_config, | 808 | fuzzy_completion_config(), |
782 | "stdin", | 809 | "stdin", |
783 | r#" | 810 | r#" |
784 | //- /lib.rs crate:dep | 811 | //- /lib.rs crate:dep |
@@ -803,13 +830,8 @@ fn main() { | |||
803 | 830 | ||
804 | #[test] | 831 | #[test] |
805 | fn macro_fuzzy_completion() { | 832 | fn macro_fuzzy_completion() { |
806 | let mut completion_config = CompletionConfig::default(); | ||
807 | completion_config | ||
808 | .active_resolve_capabilities | ||
809 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
810 | |||
811 | check_edit_with_config( | 833 | check_edit_with_config( |
812 | completion_config, | 834 | fuzzy_completion_config(), |
813 | "macro_with_curlies!", | 835 | "macro_with_curlies!", |
814 | r#" | 836 | r#" |
815 | //- /lib.rs crate:dep | 837 | //- /lib.rs crate:dep |
@@ -836,13 +858,8 @@ fn main() { | |||
836 | 858 | ||
837 | #[test] | 859 | #[test] |
838 | fn struct_fuzzy_completion() { | 860 | fn struct_fuzzy_completion() { |
839 | let mut completion_config = CompletionConfig::default(); | ||
840 | completion_config | ||
841 | .active_resolve_capabilities | ||
842 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
843 | |||
844 | check_edit_with_config( | 861 | check_edit_with_config( |
845 | completion_config, | 862 | fuzzy_completion_config(), |
846 | "ThirdStruct", | 863 | "ThirdStruct", |
847 | r#" | 864 | r#" |
848 | //- /lib.rs crate:dep | 865 | //- /lib.rs crate:dep |
@@ -868,4 +885,44 @@ fn main() { | |||
868 | "#, | 885 | "#, |
869 | ); | 886 | ); |
870 | } | 887 | } |
888 | |||
889 | #[test] | ||
890 | fn fuzzy_completions_come_in_specific_order() { | ||
891 | mark::check!(certain_fuzzy_order_test); | ||
892 | check_with_config( | ||
893 | fuzzy_completion_config(), | ||
894 | r#" | ||
895 | //- /lib.rs crate:dep | ||
896 | pub struct FirstStruct; | ||
897 | pub mod some_module { | ||
898 | // already imported, omitted | ||
899 | pub struct SecondStruct; | ||
900 | // does not contain all letters from the query, omitted | ||
901 | pub struct UnrelatedOne; | ||
902 | // contains all letters from the query, but not in sequence, displayed last | ||
903 | pub struct ThiiiiiirdStruct; | ||
904 | // contains all letters from the query, but not in the beginning, displayed second | ||
905 | pub struct AfterThirdStruct; | ||
906 | // contains all letters from the query in the begginning, displayed first | ||
907 | pub struct ThirdStruct; | ||
908 | } | ||
909 | |||
910 | //- /main.rs crate:main deps:dep | ||
911 | use dep::{FirstStruct, some_module::SecondStruct}; | ||
912 | |||
913 | fn main() { | ||
914 | hir<|> | ||
915 | } | ||
916 | "#, | ||
917 | expect![[r#" | ||
918 | fn main() fn main() | ||
919 | st SecondStruct | ||
920 | st FirstStruct | ||
921 | md dep | ||
922 | st dep::some_module::ThirdStruct | ||
923 | st dep::some_module::AfterThirdStruct | ||
924 | st dep::some_module::ThiiiiiirdStruct | ||
925 | "#]], | ||
926 | ); | ||
927 | } | ||
871 | } | 928 | } |
diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index b940388df..1092a4825 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | CompletionKind, CompletionScore, | 19 | CompletionKind, CompletionScore, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | use crate::render::{enum_variant::render_enum_variant, function::render_fn, macro_::render_macro}; | 22 | use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}; |
23 | 23 | ||
24 | pub(crate) fn render_field<'a>( | 24 | pub(crate) fn render_field<'a>( |
25 | ctx: RenderContext<'a>, | 25 | ctx: RenderContext<'a>, |
@@ -159,9 +159,8 @@ impl<'a> Render<'a> { | |||
159 | let item = render_fn(self.ctx, import_to_add, Some(local_name), *func); | 159 | let item = render_fn(self.ctx, import_to_add, Some(local_name), *func); |
160 | return Some(item); | 160 | return Some(item); |
161 | } | 161 | } |
162 | ScopeDef::ModuleDef(EnumVariant(var)) => { | 162 | ScopeDef::ModuleDef(Variant(var)) => { |
163 | let item = | 163 | let item = render_variant(self.ctx, import_to_add, Some(local_name), *var, None); |
164 | render_enum_variant(self.ctx, import_to_add, Some(local_name), *var, None); | ||
165 | return Some(item); | 164 | return Some(item); |
166 | } | 165 | } |
167 | ScopeDef::MacroDef(mac) => { | 166 | ScopeDef::MacroDef(mac) => { |
@@ -257,7 +256,7 @@ impl<'a> Render<'a> { | |||
257 | match resolution { | 256 | match resolution { |
258 | ScopeDef::ModuleDef(Module(it)) => it.docs(self.ctx.db()), | 257 | ScopeDef::ModuleDef(Module(it)) => it.docs(self.ctx.db()), |
259 | ScopeDef::ModuleDef(Adt(it)) => it.docs(self.ctx.db()), | 258 | ScopeDef::ModuleDef(Adt(it)) => it.docs(self.ctx.db()), |
260 | ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(self.ctx.db()), | 259 | ScopeDef::ModuleDef(Variant(it)) => it.docs(self.ctx.db()), |
261 | ScopeDef::ModuleDef(Const(it)) => it.docs(self.ctx.db()), | 260 | ScopeDef::ModuleDef(Const(it)) => it.docs(self.ctx.db()), |
262 | ScopeDef::ModuleDef(Static(it)) => it.docs(self.ctx.db()), | 261 | ScopeDef::ModuleDef(Static(it)) => it.docs(self.ctx.db()), |
263 | ScopeDef::ModuleDef(Trait(it)) => it.docs(self.ctx.db()), | 262 | ScopeDef::ModuleDef(Trait(it)) => it.docs(self.ctx.db()), |
diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs index 8e0fea6c0..7176fd9b3 100644 --- a/crates/completion/src/render/enum_variant.rs +++ b/crates/completion/src/render/enum_variant.rs | |||
@@ -9,35 +9,35 @@ use crate::{ | |||
9 | render::{builder_ext::Params, RenderContext}, | 9 | render::{builder_ext::Params, RenderContext}, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | pub(crate) fn render_enum_variant<'a>( | 12 | pub(crate) fn render_variant<'a>( |
13 | ctx: RenderContext<'a>, | 13 | ctx: RenderContext<'a>, |
14 | import_to_add: Option<ImportEdit>, | 14 | import_to_add: Option<ImportEdit>, |
15 | local_name: Option<String>, | 15 | local_name: Option<String>, |
16 | variant: hir::EnumVariant, | 16 | variant: hir::Variant, |
17 | path: Option<ModPath>, | 17 | path: Option<ModPath>, |
18 | ) -> CompletionItem { | 18 | ) -> CompletionItem { |
19 | let _p = profile::span("render_enum_variant"); | 19 | let _p = profile::span("render_enum_variant"); |
20 | EnumVariantRender::new(ctx, local_name, variant, path).render(import_to_add) | 20 | EnumRender::new(ctx, local_name, variant, path).render(import_to_add) |
21 | } | 21 | } |
22 | 22 | ||
23 | #[derive(Debug)] | 23 | #[derive(Debug)] |
24 | struct EnumVariantRender<'a> { | 24 | struct EnumRender<'a> { |
25 | ctx: RenderContext<'a>, | 25 | ctx: RenderContext<'a>, |
26 | name: String, | 26 | name: String, |
27 | variant: hir::EnumVariant, | 27 | variant: hir::Variant, |
28 | path: Option<ModPath>, | 28 | path: Option<ModPath>, |
29 | qualified_name: String, | 29 | qualified_name: String, |
30 | short_qualified_name: String, | 30 | short_qualified_name: String, |
31 | variant_kind: StructKind, | 31 | variant_kind: StructKind, |
32 | } | 32 | } |
33 | 33 | ||
34 | impl<'a> EnumVariantRender<'a> { | 34 | impl<'a> EnumRender<'a> { |
35 | fn new( | 35 | fn new( |
36 | ctx: RenderContext<'a>, | 36 | ctx: RenderContext<'a>, |
37 | local_name: Option<String>, | 37 | local_name: Option<String>, |
38 | variant: hir::EnumVariant, | 38 | variant: hir::Variant, |
39 | path: Option<ModPath>, | 39 | path: Option<ModPath>, |
40 | ) -> EnumVariantRender<'a> { | 40 | ) -> EnumRender<'a> { |
41 | let name = local_name.unwrap_or_else(|| variant.name(ctx.db()).to_string()); | 41 | let name = local_name.unwrap_or_else(|| variant.name(ctx.db()).to_string()); |
42 | let variant_kind = variant.kind(ctx.db()); | 42 | let variant_kind = variant.kind(ctx.db()); |
43 | 43 | ||
@@ -51,15 +51,7 @@ impl<'a> EnumVariantRender<'a> { | |||
51 | None => (name.to_string(), name.to_string()), | 51 | None => (name.to_string(), name.to_string()), |
52 | }; | 52 | }; |
53 | 53 | ||
54 | EnumVariantRender { | 54 | EnumRender { ctx, name, variant, path, qualified_name, short_qualified_name, variant_kind } |
55 | ctx, | ||
56 | name, | ||
57 | variant, | ||
58 | path, | ||
59 | qualified_name, | ||
60 | short_qualified_name, | ||
61 | variant_kind, | ||
62 | } | ||
63 | } | 55 | } |
64 | 56 | ||
65 | fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem { | 57 | fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem { |
diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index 6cfbd6c9b..dac79592f 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs | |||
@@ -41,6 +41,7 @@ impl<'a> MacroRender<'a> { | |||
41 | fn render(&self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> { | 41 | fn render(&self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> { |
42 | // FIXME: Currently proc-macro do not have ast-node, | 42 | // FIXME: Currently proc-macro do not have ast-node, |
43 | // such that it does not have source | 43 | // such that it does not have source |
44 | // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913 | ||
44 | if self.macro_.is_proc_macro() { | 45 | if self.macro_.is_proc_macro() { |
45 | return None; | 46 | return None; |
46 | } | 47 | } |
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs index db896b2df..eb0c16f52 100644 --- a/crates/completion/src/test_utils.rs +++ b/crates/completion/src/test_utils.rs | |||
@@ -47,9 +47,8 @@ pub(crate) fn completion_list_with_config( | |||
47 | code: &str, | 47 | code: &str, |
48 | kind: CompletionKind, | 48 | kind: CompletionKind, |
49 | ) -> String { | 49 | ) -> String { |
50 | let mut kind_completions: Vec<CompletionItem> = | 50 | let kind_completions: Vec<CompletionItem> = |
51 | get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect(); | 51 | get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect(); |
52 | kind_completions.sort_by_key(|c| c.label().to_owned()); | ||
53 | let label_width = kind_completions | 52 | let label_width = kind_completions |
54 | .iter() | 53 | .iter() |
55 | .map(|it| monospace_width(it.label())) | 54 | .map(|it| monospace_width(it.label())) |
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 1f2ee2580..d32ce37ed 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs | |||
@@ -10,8 +10,8 @@ use hir_ty::db::HirDatabase; | |||
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Adt, Const, Enum, EnumVariant, Field, Function, MacroDef, Module, ModuleDef, Static, Struct, | 13 | Adt, Const, Enum, Field, Function, MacroDef, Module, ModuleDef, Static, Struct, Trait, |
14 | Trait, TypeAlias, Union, | 14 | TypeAlias, Union, Variant, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait HasAttrs { | 17 | pub trait HasAttrs { |
@@ -53,7 +53,7 @@ macro_rules! impl_has_attrs { | |||
53 | 53 | ||
54 | impl_has_attrs![ | 54 | impl_has_attrs![ |
55 | (Field, FieldId), | 55 | (Field, FieldId), |
56 | (EnumVariant, EnumVariantId), | 56 | (Variant, EnumVariantId), |
57 | (Static, StaticId), | 57 | (Static, StaticId), |
58 | (Const, ConstId), | 58 | (Const, ConstId), |
59 | (Trait, TraitId), | 59 | (Trait, TraitId), |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index afe229c32..73ca6ba9f 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -161,7 +161,7 @@ pub enum ModuleDef { | |||
161 | Function(Function), | 161 | Function(Function), |
162 | Adt(Adt), | 162 | Adt(Adt), |
163 | // Can't be directly declared, but can be imported. | 163 | // Can't be directly declared, but can be imported. |
164 | EnumVariant(EnumVariant), | 164 | Variant(Variant), |
165 | Const(Const), | 165 | Const(Const), |
166 | Static(Static), | 166 | Static(Static), |
167 | Trait(Trait), | 167 | Trait(Trait), |
@@ -172,7 +172,7 @@ impl_from!( | |||
172 | Module, | 172 | Module, |
173 | Function, | 173 | Function, |
174 | Adt(Struct, Enum, Union), | 174 | Adt(Struct, Enum, Union), |
175 | EnumVariant, | 175 | Variant, |
176 | Const, | 176 | Const, |
177 | Static, | 177 | Static, |
178 | Trait, | 178 | Trait, |
@@ -186,7 +186,7 @@ impl From<VariantDef> for ModuleDef { | |||
186 | match var { | 186 | match var { |
187 | VariantDef::Struct(t) => Adt::from(t).into(), | 187 | VariantDef::Struct(t) => Adt::from(t).into(), |
188 | VariantDef::Union(t) => Adt::from(t).into(), | 188 | VariantDef::Union(t) => Adt::from(t).into(), |
189 | VariantDef::EnumVariant(t) => t.into(), | 189 | VariantDef::Variant(t) => t.into(), |
190 | } | 190 | } |
191 | } | 191 | } |
192 | } | 192 | } |
@@ -197,7 +197,7 @@ impl ModuleDef { | |||
197 | ModuleDef::Module(it) => it.parent(db), | 197 | ModuleDef::Module(it) => it.parent(db), |
198 | ModuleDef::Function(it) => Some(it.module(db)), | 198 | ModuleDef::Function(it) => Some(it.module(db)), |
199 | ModuleDef::Adt(it) => Some(it.module(db)), | 199 | ModuleDef::Adt(it) => Some(it.module(db)), |
200 | ModuleDef::EnumVariant(it) => Some(it.module(db)), | 200 | ModuleDef::Variant(it) => Some(it.module(db)), |
201 | ModuleDef::Const(it) => Some(it.module(db)), | 201 | ModuleDef::Const(it) => Some(it.module(db)), |
202 | ModuleDef::Static(it) => Some(it.module(db)), | 202 | ModuleDef::Static(it) => Some(it.module(db)), |
203 | ModuleDef::Trait(it) => Some(it.module(db)), | 203 | ModuleDef::Trait(it) => Some(it.module(db)), |
@@ -221,7 +221,7 @@ impl ModuleDef { | |||
221 | ModuleDef::Module(it) => it.parent(db)?, | 221 | ModuleDef::Module(it) => it.parent(db)?, |
222 | ModuleDef::Function(it) => return Some(it.visibility(db)), | 222 | ModuleDef::Function(it) => return Some(it.visibility(db)), |
223 | ModuleDef::Adt(it) => it.module(db), | 223 | ModuleDef::Adt(it) => it.module(db), |
224 | ModuleDef::EnumVariant(it) => { | 224 | ModuleDef::Variant(it) => { |
225 | let parent = it.parent_enum(db); | 225 | let parent = it.parent_enum(db); |
226 | let module = it.module(db); | 226 | let module = it.module(db); |
227 | return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent))); | 227 | return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent))); |
@@ -241,7 +241,7 @@ impl ModuleDef { | |||
241 | ModuleDef::Adt(it) => Some(it.name(db)), | 241 | ModuleDef::Adt(it) => Some(it.name(db)), |
242 | ModuleDef::Trait(it) => Some(it.name(db)), | 242 | ModuleDef::Trait(it) => Some(it.name(db)), |
243 | ModuleDef::Function(it) => Some(it.name(db)), | 243 | ModuleDef::Function(it) => Some(it.name(db)), |
244 | ModuleDef::EnumVariant(it) => Some(it.name(db)), | 244 | ModuleDef::Variant(it) => Some(it.name(db)), |
245 | ModuleDef::TypeAlias(it) => Some(it.name(db)), | 245 | ModuleDef::TypeAlias(it) => Some(it.name(db)), |
246 | ModuleDef::Module(it) => it.name(db), | 246 | ModuleDef::Module(it) => it.name(db), |
247 | ModuleDef::Const(it) => it.name(db), | 247 | ModuleDef::Const(it) => it.name(db), |
@@ -455,7 +455,7 @@ impl Field { | |||
455 | let generic_def_id: GenericDefId = match self.parent { | 455 | let generic_def_id: GenericDefId = match self.parent { |
456 | VariantDef::Struct(it) => it.id.into(), | 456 | VariantDef::Struct(it) => it.id.into(), |
457 | VariantDef::Union(it) => it.id.into(), | 457 | VariantDef::Union(it) => it.id.into(), |
458 | VariantDef::EnumVariant(it) => it.parent.id.into(), | 458 | VariantDef::Variant(it) => it.parent.id.into(), |
459 | }; | 459 | }; |
460 | let substs = Substs::type_params(db, generic_def_id); | 460 | let substs = Substs::type_params(db, generic_def_id); |
461 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); | 461 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); |
@@ -566,12 +566,8 @@ impl Enum { | |||
566 | db.enum_data(self.id).name.clone() | 566 | db.enum_data(self.id).name.clone() |
567 | } | 567 | } |
568 | 568 | ||
569 | pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> { | 569 | pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> { |
570 | db.enum_data(self.id) | 570 | db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect() |
571 | .variants | ||
572 | .iter() | ||
573 | .map(|(id, _)| EnumVariant { parent: self, id }) | ||
574 | .collect() | ||
575 | } | 571 | } |
576 | 572 | ||
577 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 573 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
@@ -580,12 +576,12 @@ impl Enum { | |||
580 | } | 576 | } |
581 | 577 | ||
582 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 578 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
583 | pub struct EnumVariant { | 579 | pub struct Variant { |
584 | pub(crate) parent: Enum, | 580 | pub(crate) parent: Enum, |
585 | pub(crate) id: LocalEnumVariantId, | 581 | pub(crate) id: LocalEnumVariantId, |
586 | } | 582 | } |
587 | 583 | ||
588 | impl EnumVariant { | 584 | impl Variant { |
589 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 585 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
590 | self.parent.module(db) | 586 | self.parent.module(db) |
591 | } | 587 | } |
@@ -662,16 +658,16 @@ impl Adt { | |||
662 | pub enum VariantDef { | 658 | pub enum VariantDef { |
663 | Struct(Struct), | 659 | Struct(Struct), |
664 | Union(Union), | 660 | Union(Union), |
665 | EnumVariant(EnumVariant), | 661 | Variant(Variant), |
666 | } | 662 | } |
667 | impl_from!(Struct, Union, EnumVariant for VariantDef); | 663 | impl_from!(Struct, Union, Variant for VariantDef); |
668 | 664 | ||
669 | impl VariantDef { | 665 | impl VariantDef { |
670 | pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { | 666 | pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { |
671 | match self { | 667 | match self { |
672 | VariantDef::Struct(it) => it.fields(db), | 668 | VariantDef::Struct(it) => it.fields(db), |
673 | VariantDef::Union(it) => it.fields(db), | 669 | VariantDef::Union(it) => it.fields(db), |
674 | VariantDef::EnumVariant(it) => it.fields(db), | 670 | VariantDef::Variant(it) => it.fields(db), |
675 | } | 671 | } |
676 | } | 672 | } |
677 | 673 | ||
@@ -679,7 +675,7 @@ impl VariantDef { | |||
679 | match self { | 675 | match self { |
680 | VariantDef::Struct(it) => it.module(db), | 676 | VariantDef::Struct(it) => it.module(db), |
681 | VariantDef::Union(it) => it.module(db), | 677 | VariantDef::Union(it) => it.module(db), |
682 | VariantDef::EnumVariant(it) => it.module(db), | 678 | VariantDef::Variant(it) => it.module(db), |
683 | } | 679 | } |
684 | } | 680 | } |
685 | 681 | ||
@@ -687,7 +683,7 @@ impl VariantDef { | |||
687 | match self { | 683 | match self { |
688 | VariantDef::Struct(s) => s.name(db), | 684 | VariantDef::Struct(s) => s.name(db), |
689 | VariantDef::Union(u) => u.name(db), | 685 | VariantDef::Union(u) => u.name(db), |
690 | VariantDef::EnumVariant(e) => e.name(db), | 686 | VariantDef::Variant(e) => e.name(db), |
691 | } | 687 | } |
692 | } | 688 | } |
693 | 689 | ||
@@ -695,7 +691,7 @@ impl VariantDef { | |||
695 | match self { | 691 | match self { |
696 | VariantDef::Struct(it) => it.variant_data(db), | 692 | VariantDef::Struct(it) => it.variant_data(db), |
697 | VariantDef::Union(it) => it.variant_data(db), | 693 | VariantDef::Union(it) => it.variant_data(db), |
698 | VariantDef::EnumVariant(it) => it.variant_data(db), | 694 | VariantDef::Variant(it) => it.variant_data(db), |
699 | } | 695 | } |
700 | } | 696 | } |
701 | } | 697 | } |
@@ -983,6 +979,12 @@ impl MacroDef { | |||
983 | 979 | ||
984 | /// XXX: this parses the file | 980 | /// XXX: this parses the file |
985 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 981 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
982 | // FIXME: Currently proc-macro do not have ast-node, | ||
983 | // such that it does not have source | ||
984 | // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913 | ||
985 | if self.is_proc_macro() { | ||
986 | return None; | ||
987 | } | ||
986 | self.source(db).value.name().map(|it| it.as_name()) | 988 | self.source(db).value.name().map(|it| it.as_name()) |
987 | } | 989 | } |
988 | 990 | ||
@@ -1089,7 +1091,7 @@ pub enum GenericDef { | |||
1089 | Impl(Impl), | 1091 | Impl(Impl), |
1090 | // enum variants cannot have generics themselves, but their parent enums | 1092 | // enum variants cannot have generics themselves, but their parent enums |
1091 | // can, and this makes some code easier to write | 1093 | // can, and this makes some code easier to write |
1092 | EnumVariant(EnumVariant), | 1094 | Variant(Variant), |
1093 | // consts can have type parameters from their parents (i.e. associated consts of traits) | 1095 | // consts can have type parameters from their parents (i.e. associated consts of traits) |
1094 | Const(Const), | 1096 | Const(Const), |
1095 | } | 1097 | } |
@@ -1099,7 +1101,7 @@ impl_from!( | |||
1099 | Trait, | 1101 | Trait, |
1100 | TypeAlias, | 1102 | TypeAlias, |
1101 | Impl, | 1103 | Impl, |
1102 | EnumVariant, | 1104 | Variant, |
1103 | Const | 1105 | Const |
1104 | for GenericDef | 1106 | for GenericDef |
1105 | ); | 1107 | ); |
@@ -1283,14 +1285,12 @@ impl Impl { | |||
1283 | impls.for_trait(trait_.id).map(Self::from).collect() | 1285 | impls.for_trait(trait_.id).map(Self::from).collect() |
1284 | } | 1286 | } |
1285 | 1287 | ||
1288 | // FIXME: the return type is wrong. This should be a hir version of | ||
1289 | // `TraitRef` (ie, resolved `TypeRef`). | ||
1286 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1290 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1287 | db.impl_data(self.id).target_trait.clone() | 1291 | db.impl_data(self.id).target_trait.clone() |
1288 | } | 1292 | } |
1289 | 1293 | ||
1290 | pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef { | ||
1291 | db.impl_data(self.id).target_type.clone() | ||
1292 | } | ||
1293 | |||
1294 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { | 1294 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { |
1295 | let impl_data = db.impl_data(self.id); | 1295 | let impl_data = db.impl_data(self.id); |
1296 | let resolver = self.id.resolver(db.upcast()); | 1296 | let resolver = self.id.resolver(db.upcast()); |
@@ -1324,6 +1324,7 @@ impl Impl { | |||
1324 | let item = src.file_id.is_builtin_derive(db.upcast())?; | 1324 | let item = src.file_id.is_builtin_derive(db.upcast())?; |
1325 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); | 1325 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); |
1326 | 1326 | ||
1327 | // FIXME: handle `cfg_attr` | ||
1327 | let attr = item | 1328 | let attr = item |
1328 | .value | 1329 | .value |
1329 | .attrs() | 1330 | .attrs() |
@@ -1841,7 +1842,7 @@ pub struct Callable { | |||
1841 | pub enum CallableKind { | 1842 | pub enum CallableKind { |
1842 | Function(Function), | 1843 | Function(Function), |
1843 | TupleStruct(Struct), | 1844 | TupleStruct(Struct), |
1844 | TupleEnumVariant(EnumVariant), | 1845 | TupleEnumVariant(Variant), |
1845 | Closure, | 1846 | Closure, |
1846 | } | 1847 | } |
1847 | 1848 | ||
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index 8d0f84508..8e0c571b8 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs | |||
@@ -9,8 +9,7 @@ use hir_def::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Adt, AssocItem, DefWithBody, EnumVariant, Field, GenericDef, Local, MacroDef, ModuleDef, | 12 | Adt, AssocItem, DefWithBody, Field, GenericDef, Local, MacroDef, ModuleDef, Variant, VariantDef, |
13 | VariantDef, | ||
14 | }; | 13 | }; |
15 | 14 | ||
16 | macro_rules! from_id { | 15 | macro_rules! from_id { |
@@ -65,14 +64,14 @@ impl From<Adt> for AdtId { | |||
65 | } | 64 | } |
66 | } | 65 | } |
67 | 66 | ||
68 | impl From<EnumVariantId> for EnumVariant { | 67 | impl From<EnumVariantId> for Variant { |
69 | fn from(id: EnumVariantId) -> Self { | 68 | fn from(id: EnumVariantId) -> Self { |
70 | EnumVariant { parent: id.parent.into(), id: id.local_id } | 69 | Variant { parent: id.parent.into(), id: id.local_id } |
71 | } | 70 | } |
72 | } | 71 | } |
73 | 72 | ||
74 | impl From<EnumVariant> for EnumVariantId { | 73 | impl From<Variant> for EnumVariantId { |
75 | fn from(def: EnumVariant) -> Self { | 74 | fn from(def: Variant) -> Self { |
76 | EnumVariantId { parent: def.parent.id, local_id: def.id } | 75 | EnumVariantId { parent: def.parent.id, local_id: def.id } |
77 | } | 76 | } |
78 | } | 77 | } |
@@ -83,7 +82,7 @@ impl From<ModuleDefId> for ModuleDef { | |||
83 | ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), | 82 | ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), |
84 | ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), | 83 | ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), |
85 | ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), | 84 | ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), |
86 | ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()), | 85 | ModuleDefId::EnumVariantId(it) => ModuleDef::Variant(it.into()), |
87 | ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), | 86 | ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), |
88 | ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), | 87 | ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), |
89 | ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), | 88 | ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), |
@@ -99,7 +98,7 @@ impl From<ModuleDef> for ModuleDefId { | |||
99 | ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()), | 98 | ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()), |
100 | ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()), | 99 | ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()), |
101 | ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), | 100 | ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), |
102 | ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()), | 101 | ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()), |
103 | ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), | 102 | ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), |
104 | ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), | 103 | ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), |
105 | ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), | 104 | ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), |
@@ -147,7 +146,7 @@ impl From<GenericDef> for GenericDefId { | |||
147 | GenericDef::Trait(it) => GenericDefId::TraitId(it.id), | 146 | GenericDef::Trait(it) => GenericDefId::TraitId(it.id), |
148 | GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), | 147 | GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), |
149 | GenericDef::Impl(it) => GenericDefId::ImplId(it.id), | 148 | GenericDef::Impl(it) => GenericDefId::ImplId(it.id), |
150 | GenericDef::EnumVariant(it) => { | 149 | GenericDef::Variant(it) => { |
151 | GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) | 150 | GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) |
152 | } | 151 | } |
153 | GenericDef::Const(it) => GenericDefId::ConstId(it.id), | 152 | GenericDef::Const(it) => GenericDefId::ConstId(it.id), |
@@ -164,7 +163,7 @@ impl From<GenericDefId> for GenericDef { | |||
164 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | 163 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), |
165 | GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), | 164 | GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), |
166 | GenericDefId::EnumVariantId(it) => { | 165 | GenericDefId::EnumVariantId(it) => { |
167 | GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) | 166 | GenericDef::Variant(Variant { parent: it.parent.into(), id: it.local_id }) |
168 | } | 167 | } |
169 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), | 168 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), |
170 | } | 169 | } |
@@ -185,7 +184,7 @@ impl From<VariantId> for VariantDef { | |||
185 | fn from(def: VariantId) -> Self { | 184 | fn from(def: VariantId) -> Self { |
186 | match def { | 185 | match def { |
187 | VariantId::StructId(it) => VariantDef::Struct(it.into()), | 186 | VariantId::StructId(it) => VariantDef::Struct(it.into()), |
188 | VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()), | 187 | VariantId::EnumVariantId(it) => VariantDef::Variant(it.into()), |
189 | VariantId::UnionId(it) => VariantDef::Union(it.into()), | 188 | VariantId::UnionId(it) => VariantDef::Union(it.into()), |
190 | } | 189 | } |
191 | } | 190 | } |
@@ -195,7 +194,7 @@ impl From<VariantDef> for VariantId { | |||
195 | fn from(def: VariantDef) -> Self { | 194 | fn from(def: VariantDef) -> Self { |
196 | match def { | 195 | match def { |
197 | VariantDef::Struct(it) => VariantId::StructId(it.id), | 196 | VariantDef::Struct(it) => VariantId::StructId(it.id), |
198 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), | 197 | VariantDef::Variant(it) => VariantId::EnumVariantId(it.into()), |
199 | VariantDef::Union(it) => VariantId::UnionId(it.id), | 198 | VariantDef::Union(it) => VariantId::UnionId(it.id), |
200 | } | 199 | } |
201 | } | 200 | } |
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index c5b81b252..0dc07c33e 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -10,8 +10,8 @@ use hir_expand::InFile; | |||
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, Impl, LifetimeParam, | 13 | db::HirDatabase, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef, |
14 | MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, | 14 | Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait HasSource { | 17 | pub trait HasSource { |
@@ -73,7 +73,7 @@ impl HasSource for Enum { | |||
73 | self.id.lookup(db.upcast()).source(db.upcast()) | 73 | self.id.lookup(db.upcast()).source(db.upcast()) |
74 | } | 74 | } |
75 | } | 75 | } |
76 | impl HasSource for EnumVariant { | 76 | impl HasSource for Variant { |
77 | type Ast = ast::Variant; | 77 | type Ast = ast::Variant; |
78 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> { | 78 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> { |
79 | self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()) | 79 | self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()) |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 3f4f8d8e4..bdd270c58 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -34,9 +34,9 @@ pub use crate::{ | |||
34 | attrs::{HasAttrs, Namespace}, | 34 | attrs::{HasAttrs, Namespace}, |
35 | code_model::{ | 35 | code_model::{ |
36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, | 36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, |
37 | Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, | 37 | Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, GenericDef, |
38 | GenericDef, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, | 38 | HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, |
39 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, | 39 | Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, |
40 | }, | 40 | }, |
41 | has_source::HasSource, | 41 | has_source::HasSource, |
42 | semantics::{PathResolution, Semantics, SemanticsScope}, | 42 | semantics::{PathResolution, Semantics, SemanticsScope}, |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 83ec91f58..25ebf73d8 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -51,7 +51,7 @@ impl PathResolution { | |||
51 | Some(TypeNs::BuiltinType(*builtin)) | 51 | Some(TypeNs::BuiltinType(*builtin)) |
52 | } | 52 | } |
53 | PathResolution::Def(ModuleDef::Const(_)) | 53 | PathResolution::Def(ModuleDef::Const(_)) |
54 | | PathResolution::Def(ModuleDef::EnumVariant(_)) | 54 | | PathResolution::Def(ModuleDef::Variant(_)) |
55 | | PathResolution::Def(ModuleDef::Function(_)) | 55 | | PathResolution::Def(ModuleDef::Function(_)) |
56 | | PathResolution::Def(ModuleDef::Module(_)) | 56 | | PathResolution::Def(ModuleDef::Module(_)) |
57 | | PathResolution::Def(ModuleDef::Static(_)) | 57 | | PathResolution::Def(ModuleDef::Static(_)) |
@@ -715,7 +715,7 @@ to_def_impls![ | |||
715 | (crate::Function, ast::Fn, fn_to_def), | 715 | (crate::Function, ast::Fn, fn_to_def), |
716 | (crate::Field, ast::RecordField, record_field_to_def), | 716 | (crate::Field, ast::RecordField, record_field_to_def), |
717 | (crate::Field, ast::TupleField, tuple_field_to_def), | 717 | (crate::Field, ast::TupleField, tuple_field_to_def), |
718 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), | 718 | (crate::Variant, ast::Variant, enum_variant_to_def), |
719 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 719 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
720 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | 720 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), |
721 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), | 721 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index bf0c959fe..bddc49c05 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -28,8 +28,8 @@ use syntax::{ | |||
28 | }; | 28 | }; |
29 | 29 | ||
30 | use crate::{ | 30 | use crate::{ |
31 | db::HirDatabase, semantics::PathResolution, Adt, Const, EnumVariant, Field, Function, Local, | 31 | db::HirDatabase, semantics::PathResolution, Adt, Const, Field, Function, Local, MacroDef, |
32 | MacroDef, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, | 32 | ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Variant, |
33 | }; | 33 | }; |
34 | use base_db::CrateId; | 34 | use base_db::CrateId; |
35 | 35 | ||
@@ -230,7 +230,7 @@ impl SourceAnalyzer { | |||
230 | if let Some(VariantId::EnumVariantId(variant)) = | 230 | if let Some(VariantId::EnumVariantId(variant)) = |
231 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 231 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) |
232 | { | 232 | { |
233 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | 233 | return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
@@ -242,7 +242,7 @@ impl SourceAnalyzer { | |||
242 | if let Some(VariantId::EnumVariantId(variant)) = | 242 | if let Some(VariantId::EnumVariantId(variant)) = |
243 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | 243 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) |
244 | { | 244 | { |
245 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | 245 | return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); |
246 | } | 246 | } |
247 | } | 247 | } |
248 | 248 | ||
@@ -251,7 +251,7 @@ impl SourceAnalyzer { | |||
251 | if let Some(VariantId::EnumVariantId(variant)) = | 251 | if let Some(VariantId::EnumVariantId(variant)) = |
252 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 252 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) |
253 | { | 253 | { |
254 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | 254 | return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); |
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
@@ -260,7 +260,7 @@ impl SourceAnalyzer { | |||
260 | if let Some(VariantId::EnumVariantId(variant)) = | 260 | if let Some(VariantId::EnumVariantId(variant)) = |
261 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | 261 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) |
262 | { | 262 | { |
263 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | 263 | return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); |
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
@@ -459,7 +459,7 @@ pub(crate) fn resolve_hir_path( | |||
459 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 459 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
460 | PathResolution::Def(Adt::from(it).into()) | 460 | PathResolution::Def(Adt::from(it).into()) |
461 | } | 461 | } |
462 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 462 | TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), |
463 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | 463 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
464 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | 464 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
465 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 465 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
@@ -477,7 +477,7 @@ pub(crate) fn resolve_hir_path( | |||
477 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | 477 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), |
478 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | 478 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), |
479 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | 479 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), |
480 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 480 | ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), |
481 | ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), | 481 | ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), |
482 | }; | 482 | }; |
483 | Some(res) | 483 | Some(res) |
@@ -526,7 +526,7 @@ fn resolve_hir_path_qualifier( | |||
526 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 526 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
527 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | 527 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
528 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()), | 528 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()), |
529 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 529 | TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), |
530 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | 530 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
531 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | 531 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
532 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 532 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs index eafa3abb6..236d6f1b7 100644 --- a/crates/hir_def/src/adt.rs +++ b/crates/hir_def/src/adt.rs | |||
@@ -3,6 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use arena::{map::ArenaMap, Arena}; | 5 | use arena::{map::ArenaMap, Arena}; |
6 | use base_db::CrateId; | ||
6 | use either::Either; | 7 | use either::Either; |
7 | use hir_expand::{ | 8 | use hir_expand::{ |
8 | name::{AsName, Name}, | 9 | name::{AsName, Name}, |
@@ -66,8 +67,13 @@ pub enum ReprKind { | |||
66 | Other, | 67 | Other, |
67 | } | 68 | } |
68 | 69 | ||
69 | fn repr_from_value(item_tree: &ItemTree, of: AttrOwner) -> Option<ReprKind> { | 70 | fn repr_from_value( |
70 | item_tree.attrs(of).by_key("repr").tt_values().find_map(parse_repr_tt) | 71 | db: &dyn DefDatabase, |
72 | krate: CrateId, | ||
73 | item_tree: &ItemTree, | ||
74 | of: AttrOwner, | ||
75 | ) -> Option<ReprKind> { | ||
76 | item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt) | ||
71 | } | 77 | } |
72 | 78 | ||
73 | fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { | 79 | fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { |
@@ -86,12 +92,13 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { | |||
86 | impl StructData { | 92 | impl StructData { |
87 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { | 93 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { |
88 | let loc = id.lookup(db); | 94 | let loc = id.lookup(db); |
95 | let krate = loc.container.module(db).krate; | ||
89 | let item_tree = db.item_tree(loc.id.file_id); | 96 | let item_tree = db.item_tree(loc.id.file_id); |
90 | let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); | 97 | let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); |
91 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 98 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); |
92 | 99 | ||
93 | let strukt = &item_tree[loc.id.value]; | 100 | let strukt = &item_tree[loc.id.value]; |
94 | let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields, None); | 101 | let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None); |
95 | Arc::new(StructData { | 102 | Arc::new(StructData { |
96 | name: strukt.name.clone(), | 103 | name: strukt.name.clone(), |
97 | variant_data: Arc::new(variant_data), | 104 | variant_data: Arc::new(variant_data), |
@@ -100,12 +107,13 @@ impl StructData { | |||
100 | } | 107 | } |
101 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { | 108 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { |
102 | let loc = id.lookup(db); | 109 | let loc = id.lookup(db); |
110 | let krate = loc.container.module(db).krate; | ||
103 | let item_tree = db.item_tree(loc.id.file_id); | 111 | let item_tree = db.item_tree(loc.id.file_id); |
104 | let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); | 112 | let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); |
105 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 113 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); |
106 | 114 | ||
107 | let union = &item_tree[loc.id.value]; | 115 | let union = &item_tree[loc.id.value]; |
108 | let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields, None); | 116 | let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None); |
109 | 117 | ||
110 | Arc::new(StructData { | 118 | Arc::new(StructData { |
111 | name: union.name.clone(), | 119 | name: union.name.clone(), |
@@ -118,16 +126,23 @@ impl StructData { | |||
118 | impl EnumData { | 126 | impl EnumData { |
119 | pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { | 127 | pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { |
120 | let loc = e.lookup(db); | 128 | let loc = e.lookup(db); |
129 | let krate = loc.container.module(db).krate; | ||
121 | let item_tree = db.item_tree(loc.id.file_id); | 130 | let item_tree = db.item_tree(loc.id.file_id); |
122 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 131 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); |
123 | 132 | ||
124 | let enum_ = &item_tree[loc.id.value]; | 133 | let enum_ = &item_tree[loc.id.value]; |
125 | let mut variants = Arena::new(); | 134 | let mut variants = Arena::new(); |
126 | for var_id in enum_.variants.clone() { | 135 | for var_id in enum_.variants.clone() { |
127 | if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) { | 136 | if item_tree.attrs(db, krate, var_id.into()).is_cfg_enabled(&cfg_options) { |
128 | let var = &item_tree[var_id]; | 137 | let var = &item_tree[var_id]; |
129 | let var_data = | 138 | let var_data = lower_fields( |
130 | lower_fields(&item_tree, &cfg_options, &var.fields, Some(enum_.visibility)); | 139 | db, |
140 | krate, | ||
141 | &item_tree, | ||
142 | &cfg_options, | ||
143 | &var.fields, | ||
144 | Some(enum_.visibility), | ||
145 | ); | ||
131 | 146 | ||
132 | variants.alloc(EnumVariantData { | 147 | variants.alloc(EnumVariantData { |
133 | name: var.name.clone(), | 148 | name: var.name.clone(), |
@@ -170,7 +185,7 @@ fn lower_enum( | |||
170 | .variant_list() | 185 | .variant_list() |
171 | .into_iter() | 186 | .into_iter() |
172 | .flat_map(|it| it.variants()) | 187 | .flat_map(|it| it.variants()) |
173 | .filter(|var| expander.is_cfg_enabled(var)); | 188 | .filter(|var| expander.is_cfg_enabled(db, var)); |
174 | for var in variants { | 189 | for var in variants { |
175 | trace.alloc( | 190 | trace.alloc( |
176 | || var.clone(), | 191 | || var.clone(), |
@@ -262,7 +277,7 @@ fn lower_struct( | |||
262 | match &ast.value { | 277 | match &ast.value { |
263 | ast::StructKind::Tuple(fl) => { | 278 | ast::StructKind::Tuple(fl) => { |
264 | for (i, fd) in fl.fields().enumerate() { | 279 | for (i, fd) in fl.fields().enumerate() { |
265 | if !expander.is_cfg_enabled(&fd) { | 280 | if !expander.is_cfg_enabled(db, &fd) { |
266 | continue; | 281 | continue; |
267 | } | 282 | } |
268 | 283 | ||
@@ -279,7 +294,7 @@ fn lower_struct( | |||
279 | } | 294 | } |
280 | ast::StructKind::Record(fl) => { | 295 | ast::StructKind::Record(fl) => { |
281 | for fd in fl.fields() { | 296 | for fd in fl.fields() { |
282 | if !expander.is_cfg_enabled(&fd) { | 297 | if !expander.is_cfg_enabled(db, &fd) { |
283 | continue; | 298 | continue; |
284 | } | 299 | } |
285 | 300 | ||
@@ -299,6 +314,8 @@ fn lower_struct( | |||
299 | } | 314 | } |
300 | 315 | ||
301 | fn lower_fields( | 316 | fn lower_fields( |
317 | db: &dyn DefDatabase, | ||
318 | krate: CrateId, | ||
302 | item_tree: &ItemTree, | 319 | item_tree: &ItemTree, |
303 | cfg_options: &CfgOptions, | 320 | cfg_options: &CfgOptions, |
304 | fields: &Fields, | 321 | fields: &Fields, |
@@ -308,7 +325,7 @@ fn lower_fields( | |||
308 | Fields::Record(flds) => { | 325 | Fields::Record(flds) => { |
309 | let mut arena = Arena::new(); | 326 | let mut arena = Arena::new(); |
310 | for field_id in flds.clone() { | 327 | for field_id in flds.clone() { |
311 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | 328 | if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) { |
312 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); | 329 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); |
313 | } | 330 | } |
314 | } | 331 | } |
@@ -317,7 +334,7 @@ fn lower_fields( | |||
317 | Fields::Tuple(flds) => { | 334 | Fields::Tuple(flds) => { |
318 | let mut arena = Arena::new(); | 335 | let mut arena = Arena::new(); |
319 | for field_id in flds.clone() { | 336 | for field_id in flds.clone() { |
320 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | 337 | if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) { |
321 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); | 338 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); |
322 | } | 339 | } |
323 | } | 340 | } |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index c64b78445..042e119b1 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -2,22 +2,24 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use base_db::CrateId; | ||
5 | use cfg::{CfgExpr, CfgOptions}; | 6 | use cfg::{CfgExpr, CfgOptions}; |
6 | use either::Either; | 7 | use either::Either; |
7 | use hir_expand::{hygiene::Hygiene, AstId, InFile}; | 8 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; |
8 | use itertools::Itertools; | 9 | use itertools::Itertools; |
9 | use mbe::ast_to_token_tree; | 10 | use mbe::ast_to_token_tree; |
10 | use syntax::{ | 11 | use syntax::{ |
11 | ast::{self, AstNode, AttrsOwner}, | 12 | ast::{self, AstNode, AttrsOwner}, |
12 | match_ast, AstToken, SmolStr, SyntaxNode, | 13 | match_ast, AstToken, SmolStr, SyntaxNode, |
13 | }; | 14 | }; |
15 | use test_utils::mark; | ||
14 | use tt::Subtree; | 16 | use tt::Subtree; |
15 | 17 | ||
16 | use crate::{ | 18 | use crate::{ |
17 | db::DefDatabase, | 19 | db::DefDatabase, |
18 | item_tree::{ItemTreeId, ItemTreeNode}, | 20 | item_tree::{ItemTreeId, ItemTreeNode}, |
19 | nameres::ModuleSource, | 21 | nameres::ModuleSource, |
20 | path::ModPath, | 22 | path::{ModPath, PathKind}, |
21 | src::HasChildSource, | 23 | src::HasChildSource, |
22 | AdtId, AttrDefId, Lookup, | 24 | AdtId, AttrDefId, Lookup, |
23 | }; | 25 | }; |
@@ -38,12 +40,16 @@ impl From<Documentation> for String { | |||
38 | } | 40 | } |
39 | } | 41 | } |
40 | 42 | ||
43 | /// Syntactical attributes, without filtering of `cfg_attr`s. | ||
41 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 44 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
42 | pub struct Attrs { | 45 | pub(crate) struct RawAttrs { |
43 | entries: Option<Arc<[Attr]>>, | 46 | entries: Option<Arc<[Attr]>>, |
44 | } | 47 | } |
45 | 48 | ||
46 | impl ops::Deref for Attrs { | 49 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
50 | pub struct Attrs(RawAttrs); | ||
51 | |||
52 | impl ops::Deref for RawAttrs { | ||
47 | type Target = [Attr]; | 53 | type Target = [Attr]; |
48 | 54 | ||
49 | fn deref(&self) -> &[Attr] { | 55 | fn deref(&self) -> &[Attr] { |
@@ -54,19 +60,147 @@ impl ops::Deref for Attrs { | |||
54 | } | 60 | } |
55 | } | 61 | } |
56 | 62 | ||
63 | impl ops::Deref for Attrs { | ||
64 | type Target = [Attr]; | ||
65 | |||
66 | fn deref(&self) -> &[Attr] { | ||
67 | match &self.0.entries { | ||
68 | Some(it) => &*it, | ||
69 | None => &[], | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl RawAttrs { | ||
75 | pub(crate) const EMPTY: Self = Self { entries: None }; | ||
76 | |||
77 | pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self { | ||
78 | let attrs: Vec<_> = collect_attrs(owner).collect(); | ||
79 | let entries = if attrs.is_empty() { | ||
80 | // Avoid heap allocation | ||
81 | None | ||
82 | } else { | ||
83 | Some( | ||
84 | attrs | ||
85 | .into_iter() | ||
86 | .enumerate() | ||
87 | .flat_map(|(i, attr)| match attr { | ||
88 | Either::Left(attr) => Attr::from_src(attr, hygiene).map(|attr| (i, attr)), | ||
89 | Either::Right(comment) => comment.doc_comment().map(|doc| { | ||
90 | ( | ||
91 | i, | ||
92 | Attr { | ||
93 | index: 0, | ||
94 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | ||
95 | path: ModPath::from(hir_expand::name!(doc)), | ||
96 | }, | ||
97 | ) | ||
98 | }), | ||
99 | }) | ||
100 | .map(|(i, attr)| Attr { index: i as u32, ..attr }) | ||
101 | .collect(), | ||
102 | ) | ||
103 | }; | ||
104 | Self { entries } | ||
105 | } | ||
106 | |||
107 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self { | ||
108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | ||
109 | Self::new(owner.value, &hygiene) | ||
110 | } | ||
111 | |||
112 | pub(crate) fn merge(&self, other: Self) -> Self { | ||
113 | match (&self.entries, &other.entries) { | ||
114 | (None, None) => Self::EMPTY, | ||
115 | (Some(entries), None) | (None, Some(entries)) => { | ||
116 | Self { entries: Some(entries.clone()) } | ||
117 | } | ||
118 | (Some(a), Some(b)) => { | ||
119 | Self { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. | ||
125 | pub(crate) fn filter(self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { | ||
126 | let has_cfg_attrs = self.iter().any(|attr| { | ||
127 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]) | ||
128 | }); | ||
129 | if !has_cfg_attrs { | ||
130 | return Attrs(self); | ||
131 | } | ||
132 | |||
133 | let crate_graph = db.crate_graph(); | ||
134 | let new_attrs = self | ||
135 | .iter() | ||
136 | .filter_map(|attr| { | ||
137 | let attr = attr.clone(); | ||
138 | let is_cfg_attr = | ||
139 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); | ||
140 | if !is_cfg_attr { | ||
141 | return Some(attr); | ||
142 | } | ||
143 | |||
144 | let subtree = match &attr.input { | ||
145 | Some(AttrInput::TokenTree(it)) => it, | ||
146 | _ => return Some(attr), | ||
147 | }; | ||
148 | |||
149 | // Input subtree is: `(cfg, attr)` | ||
150 | // Split it up into a `cfg` and an `attr` subtree. | ||
151 | // FIXME: There should be a common API for this. | ||
152 | let mut saw_comma = false; | ||
153 | let (mut cfg, attr): (Vec<_>, Vec<_>) = | ||
154 | subtree.clone().token_trees.into_iter().partition(|tree| { | ||
155 | if saw_comma { | ||
156 | return false; | ||
157 | } | ||
158 | |||
159 | match tree { | ||
160 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
161 | saw_comma = true; | ||
162 | } | ||
163 | _ => {} | ||
164 | } | ||
165 | |||
166 | true | ||
167 | }); | ||
168 | cfg.pop(); // `,` ends up in here | ||
169 | |||
170 | let attr = Subtree { delimiter: None, token_trees: attr }; | ||
171 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg }; | ||
172 | let cfg = CfgExpr::parse(&cfg); | ||
173 | |||
174 | let cfg_options = &crate_graph[krate].cfg_options; | ||
175 | if cfg_options.check(&cfg) == Some(false) { | ||
176 | None | ||
177 | } else { | ||
178 | mark::hit!(cfg_attr_active); | ||
179 | |||
180 | let attr = ast::Attr::parse(&format!("#[{}]", attr)).ok()?; | ||
181 | let hygiene = Hygiene::new_unhygienic(); // FIXME | ||
182 | Attr::from_src(attr, &hygiene) | ||
183 | } | ||
184 | }) | ||
185 | .collect(); | ||
186 | |||
187 | Attrs(RawAttrs { entries: Some(new_attrs) }) | ||
188 | } | ||
189 | } | ||
190 | |||
57 | impl Attrs { | 191 | impl Attrs { |
58 | pub const EMPTY: Attrs = Attrs { entries: None }; | 192 | pub const EMPTY: Self = Self(RawAttrs::EMPTY); |
59 | 193 | ||
60 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { | 194 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { |
61 | match def { | 195 | let raw_attrs = match def { |
62 | AttrDefId::ModuleId(module) => { | 196 | AttrDefId::ModuleId(module) => { |
63 | let def_map = db.crate_def_map(module.krate); | 197 | let def_map = db.crate_def_map(module.krate); |
64 | let mod_data = &def_map[module.local_id]; | 198 | let mod_data = &def_map[module.local_id]; |
65 | match mod_data.declaration_source(db) { | 199 | match mod_data.declaration_source(db) { |
66 | Some(it) => { | 200 | Some(it) => { |
67 | Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner)) | 201 | RawAttrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner)) |
68 | } | 202 | } |
69 | None => Attrs::from_attrs_owner( | 203 | None => RawAttrs::from_attrs_owner( |
70 | db, | 204 | db, |
71 | mod_data.definition_source(db).as_ref().map(|src| match src { | 205 | mod_data.definition_source(db).as_ref().map(|src| match src { |
72 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, | 206 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, |
@@ -78,14 +212,14 @@ impl Attrs { | |||
78 | AttrDefId::FieldId(it) => { | 212 | AttrDefId::FieldId(it) => { |
79 | let src = it.parent.child_source(db); | 213 | let src = it.parent.child_source(db); |
80 | match &src.value[it.local_id] { | 214 | match &src.value[it.local_id] { |
81 | Either::Left(_tuple) => Attrs::default(), | 215 | Either::Left(_tuple) => RawAttrs::default(), |
82 | Either::Right(record) => Attrs::from_attrs_owner(db, src.with_value(record)), | 216 | Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)), |
83 | } | 217 | } |
84 | } | 218 | } |
85 | AttrDefId::EnumVariantId(var_id) => { | 219 | AttrDefId::EnumVariantId(var_id) => { |
86 | let src = var_id.parent.child_source(db); | 220 | let src = var_id.parent.child_source(db); |
87 | let src = src.as_ref().map(|it| &it[var_id.local_id]); | 221 | let src = src.as_ref().map(|it| &it[var_id.local_id]); |
88 | Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) | 222 | RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) |
89 | } | 223 | } |
90 | AttrDefId::AdtId(it) => match it { | 224 | AttrDefId::AdtId(it) => match it { |
91 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 225 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
@@ -101,55 +235,9 @@ impl Attrs { | |||
101 | AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 235 | AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
102 | AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 236 | AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
103 | AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 237 | AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
104 | } | ||
105 | } | ||
106 | |||
107 | pub fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { | ||
108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | ||
109 | Attrs::new(owner.value, &hygiene) | ||
110 | } | ||
111 | |||
112 | pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { | ||
113 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | ||
114 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); | ||
115 | |||
116 | let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); | ||
117 | let attrs = outer_attrs | ||
118 | .chain(inner_attrs.into_iter().flatten()) | ||
119 | .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene))); | ||
120 | |||
121 | let outer_docs = | ||
122 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); | ||
123 | let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| { | ||
124 | ( | ||
125 | docs_text.syntax().text_range().start(), | ||
126 | docs_text.doc_comment().map(|doc| Attr { | ||
127 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | ||
128 | path: ModPath::from(hir_expand::name!(doc)), | ||
129 | }), | ||
130 | ) | ||
131 | }); | ||
132 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | ||
133 | let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect(); | ||
134 | let entries = if attrs.is_empty() { | ||
135 | // Avoid heap allocation | ||
136 | None | ||
137 | } else { | ||
138 | Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect()) | ||
139 | }; | 238 | }; |
140 | Attrs { entries } | ||
141 | } | ||
142 | 239 | ||
143 | pub fn merge(&self, other: Attrs) -> Attrs { | 240 | raw_attrs.filter(db, def.krate(db)) |
144 | match (&self.entries, &other.entries) { | ||
145 | (None, None) => Attrs { entries: None }, | ||
146 | (Some(entries), None) | (None, Some(entries)) => { | ||
147 | Attrs { entries: Some(entries.clone()) } | ||
148 | } | ||
149 | (Some(a), Some(b)) => { | ||
150 | Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } | ||
151 | } | ||
152 | } | ||
153 | } | 241 | } |
154 | 242 | ||
155 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { | 243 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { |
@@ -157,7 +245,6 @@ impl Attrs { | |||
157 | } | 245 | } |
158 | 246 | ||
159 | pub fn cfg(&self) -> Option<CfgExpr> { | 247 | pub fn cfg(&self) -> Option<CfgExpr> { |
160 | // FIXME: handle cfg_attr :-) | ||
161 | let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>(); | 248 | let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>(); |
162 | match cfgs.len() { | 249 | match cfgs.len() { |
163 | 0 => None, | 250 | 0 => None, |
@@ -228,6 +315,7 @@ fn inner_attributes( | |||
228 | 315 | ||
229 | #[derive(Debug, Clone, PartialEq, Eq)] | 316 | #[derive(Debug, Clone, PartialEq, Eq)] |
230 | pub struct Attr { | 317 | pub struct Attr { |
318 | index: u32, | ||
231 | pub(crate) path: ModPath, | 319 | pub(crate) path: ModPath, |
232 | pub(crate) input: Option<AttrInput>, | 320 | pub(crate) input: Option<AttrInput>, |
233 | } | 321 | } |
@@ -254,7 +342,59 @@ impl Attr { | |||
254 | } else { | 342 | } else { |
255 | None | 343 | None |
256 | }; | 344 | }; |
257 | Some(Attr { path, input }) | 345 | Some(Attr { index: 0, path, input }) |
346 | } | ||
347 | |||
348 | /// Maps this lowered `Attr` back to its original syntax node. | ||
349 | /// | ||
350 | /// `owner` must be the original owner of the attribute. | ||
351 | /// | ||
352 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of | ||
353 | /// the attribute represented by `Attr`. | ||
354 | pub fn to_src(&self, owner: &dyn AttrsOwner) -> Either<ast::Attr, ast::Comment> { | ||
355 | collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| { | ||
356 | panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax()) | ||
357 | }) | ||
358 | } | ||
359 | |||
360 | /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths | ||
361 | /// to derive macros. | ||
362 | /// | ||
363 | /// Returns `None` when the attribute is not a well-formed `#[derive]` attribute. | ||
364 | pub(crate) fn parse_derive(&self) -> Option<impl Iterator<Item = ModPath>> { | ||
365 | if self.path.as_ident() != Some(&hir_expand::name![derive]) { | ||
366 | return None; | ||
367 | } | ||
368 | |||
369 | match &self.input { | ||
370 | Some(AttrInput::TokenTree(args)) => { | ||
371 | let mut counter = 0; | ||
372 | let paths = args | ||
373 | .token_trees | ||
374 | .iter() | ||
375 | .group_by(move |tt| { | ||
376 | match tt { | ||
377 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
378 | counter += 1; | ||
379 | } | ||
380 | _ => {} | ||
381 | } | ||
382 | counter | ||
383 | }) | ||
384 | .into_iter() | ||
385 | .map(|(_, tts)| { | ||
386 | let segments = tts.filter_map(|tt| match tt { | ||
387 | tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()), | ||
388 | _ => None, | ||
389 | }); | ||
390 | ModPath::from_segments(PathKind::Plain, segments) | ||
391 | }) | ||
392 | .collect::<Vec<_>>(); | ||
393 | |||
394 | Some(paths.into_iter()) | ||
395 | } | ||
396 | _ => None, | ||
397 | } | ||
258 | } | 398 | } |
259 | } | 399 | } |
260 | 400 | ||
@@ -283,7 +423,7 @@ impl<'a> AttrQuery<'a> { | |||
283 | self.attrs().next().is_some() | 423 | self.attrs().next().is_some() |
284 | } | 424 | } |
285 | 425 | ||
286 | fn attrs(self) -> impl Iterator<Item = &'a Attr> { | 426 | pub(crate) fn attrs(self) -> impl Iterator<Item = &'a Attr> { |
287 | let key = self.key; | 427 | let key = self.key; |
288 | self.attrs | 428 | self.attrs |
289 | .iter() | 429 | .iter() |
@@ -291,16 +431,36 @@ impl<'a> AttrQuery<'a> { | |||
291 | } | 431 | } |
292 | } | 432 | } |
293 | 433 | ||
294 | fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> Attrs | 434 | fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> RawAttrs |
295 | where | 435 | where |
296 | N: ast::AttrsOwner, | 436 | N: ast::AttrsOwner, |
297 | { | 437 | { |
298 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); | 438 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); |
299 | Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) | 439 | RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) |
300 | } | 440 | } |
301 | 441 | ||
302 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { | 442 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs { |
303 | let tree = db.item_tree(id.file_id); | 443 | let tree = db.item_tree(id.file_id); |
304 | let mod_item = N::id_to_mod_item(id.value); | 444 | let mod_item = N::id_to_mod_item(id.value); |
305 | tree.attrs(mod_item.into()).clone() | 445 | tree.raw_attrs(mod_item.into()).clone() |
446 | } | ||
447 | |||
448 | fn collect_attrs(owner: &dyn AttrsOwner) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { | ||
449 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | ||
450 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); | ||
451 | |||
452 | let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); | ||
453 | let attrs = outer_attrs | ||
454 | .chain(inner_attrs.into_iter().flatten()) | ||
455 | .map(|attr| (attr.syntax().text_range().start(), Either::Left(attr))); | ||
456 | |||
457 | let outer_docs = | ||
458 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); | ||
459 | let docs = outer_docs | ||
460 | .chain(inner_docs.into_iter().flatten()) | ||
461 | .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text))); | ||
462 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | ||
463 | let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect(); | ||
464 | |||
465 | attrs.into_iter().map(|(_, attr)| attr) | ||
306 | } | 466 | } |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index c5d6f5fb0..998b82601 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -24,7 +24,7 @@ use test_utils::mark; | |||
24 | pub(crate) use lower::LowerCtx; | 24 | pub(crate) use lower::LowerCtx; |
25 | 25 | ||
26 | use crate::{ | 26 | use crate::{ |
27 | attr::Attrs, | 27 | attr::{Attrs, RawAttrs}, |
28 | db::DefDatabase, | 28 | db::DefDatabase, |
29 | expr::{Expr, ExprId, Pat, PatId}, | 29 | expr::{Expr, ExprId, Pat, PatId}, |
30 | item_scope::BuiltinShadowMode, | 30 | item_scope::BuiltinShadowMode, |
@@ -40,6 +40,7 @@ use crate::{ | |||
40 | pub(crate) struct CfgExpander { | 40 | pub(crate) struct CfgExpander { |
41 | cfg_options: CfgOptions, | 41 | cfg_options: CfgOptions, |
42 | hygiene: Hygiene, | 42 | hygiene: Hygiene, |
43 | krate: CrateId, | ||
43 | } | 44 | } |
44 | 45 | ||
45 | pub(crate) struct Expander { | 46 | pub(crate) struct Expander { |
@@ -65,15 +66,15 @@ impl CfgExpander { | |||
65 | ) -> CfgExpander { | 66 | ) -> CfgExpander { |
66 | let hygiene = Hygiene::new(db.upcast(), current_file_id); | 67 | let hygiene = Hygiene::new(db.upcast(), current_file_id); |
67 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); | 68 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); |
68 | CfgExpander { cfg_options, hygiene } | 69 | CfgExpander { cfg_options, hygiene, krate } |
69 | } | 70 | } |
70 | 71 | ||
71 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | 72 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { |
72 | Attrs::new(owner, &self.hygiene) | 73 | RawAttrs::new(owner, &self.hygiene).filter(db, self.krate) |
73 | } | 74 | } |
74 | 75 | ||
75 | pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool { | 76 | pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool { |
76 | let attrs = self.parse_attrs(owner); | 77 | let attrs = self.parse_attrs(db, owner); |
77 | attrs.is_cfg_enabled(&self.cfg_options) | 78 | attrs.is_cfg_enabled(&self.cfg_options) |
78 | } | 79 | } |
79 | } | 80 | } |
@@ -189,8 +190,8 @@ impl Expander { | |||
189 | InFile { file_id: self.current_file_id, value } | 190 | InFile { file_id: self.current_file_id, value } |
190 | } | 191 | } |
191 | 192 | ||
192 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | 193 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { |
193 | self.cfg_expander.parse_attrs(owner) | 194 | self.cfg_expander.parse_attrs(db, owner) |
194 | } | 195 | } |
195 | 196 | ||
196 | pub(crate) fn cfg_options(&self) -> &CfgOptions { | 197 | pub(crate) fn cfg_options(&self) -> &CfgOptions { |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 3b3d74987..0f404be1b 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -963,7 +963,7 @@ impl ExprCollector<'_> { | |||
963 | /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when | 963 | /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when |
964 | /// not. | 964 | /// not. |
965 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { | 965 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { |
966 | match self.expander.parse_attrs(owner).cfg() { | 966 | match self.expander.parse_attrs(self.db, owner).cfg() { |
967 | Some(cfg) => { | 967 | Some(cfg) => { |
968 | if self.expander.cfg_options().check(&cfg) != Some(false) { | 968 | if self.expander.cfg_options().check(&cfg) != Some(false) { |
969 | return Some(()); | 969 | return Some(()); |
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index dd3a906af..e7b7724f7 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -35,6 +35,7 @@ pub struct FunctionData { | |||
35 | impl FunctionData { | 35 | impl FunctionData { |
36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { | 36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { |
37 | let loc = func.lookup(db); | 37 | let loc = func.lookup(db); |
38 | let krate = loc.container.module(db).krate; | ||
38 | let item_tree = db.item_tree(loc.id.file_id); | 39 | let item_tree = db.item_tree(loc.id.file_id); |
39 | let func = &item_tree[loc.id.value]; | 40 | let func = &item_tree[loc.id.value]; |
40 | 41 | ||
@@ -42,7 +43,7 @@ impl FunctionData { | |||
42 | name: func.name.clone(), | 43 | name: func.name.clone(), |
43 | params: func.params.to_vec(), | 44 | params: func.params.to_vec(), |
44 | ret_type: func.ret_type.clone(), | 45 | ret_type: func.ret_type.clone(), |
45 | attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), | 46 | attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()).clone(), |
46 | has_self_param: func.has_self_param, | 47 | has_self_param: func.has_self_param, |
47 | has_body: func.has_body, | 48 | has_body: func.has_body, |
48 | is_unsafe: func.is_unsafe, | 49 | is_unsafe: func.is_unsafe, |
@@ -233,7 +234,7 @@ fn collect_items( | |||
233 | match item { | 234 | match item { |
234 | AssocItem::Function(id) => { | 235 | AssocItem::Function(id) => { |
235 | let item = &item_tree[id]; | 236 | let item = &item_tree[id]; |
236 | let attrs = item_tree.attrs(ModItem::from(id).into()); | 237 | let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into()); |
237 | if !attrs.is_cfg_enabled(&cfg_options) { | 238 | if !attrs.is_cfg_enabled(&cfg_options) { |
238 | continue; | 239 | continue; |
239 | } | 240 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index b8e09e3af..100dbf5d6 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -12,7 +12,8 @@ use std::{ | |||
12 | }; | 12 | }; |
13 | 13 | ||
14 | use arena::{Arena, Idx, RawId}; | 14 | use arena::{Arena, Idx, RawId}; |
15 | use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; | 15 | use ast::{AstNode, NameOwner, StructKind}; |
16 | use base_db::CrateId; | ||
16 | use either::Either; | 17 | use either::Either; |
17 | use hir_expand::{ | 18 | use hir_expand::{ |
18 | ast_id_map::FileAstId, | 19 | ast_id_map::FileAstId, |
@@ -26,7 +27,7 @@ use syntax::{ast, match_ast}; | |||
26 | use test_utils::mark; | 27 | use test_utils::mark; |
27 | 28 | ||
28 | use crate::{ | 29 | use crate::{ |
29 | attr::Attrs, | 30 | attr::{Attrs, RawAttrs}, |
30 | db::DefDatabase, | 31 | db::DefDatabase, |
31 | generics::GenericParams, | 32 | generics::GenericParams, |
32 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, | 33 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, |
@@ -67,7 +68,7 @@ impl GenericParamsId { | |||
67 | #[derive(Debug, Eq, PartialEq)] | 68 | #[derive(Debug, Eq, PartialEq)] |
68 | pub struct ItemTree { | 69 | pub struct ItemTree { |
69 | top_level: SmallVec<[ModItem; 1]>, | 70 | top_level: SmallVec<[ModItem; 1]>, |
70 | attrs: FxHashMap<AttrOwner, Attrs>, | 71 | attrs: FxHashMap<AttrOwner, RawAttrs>, |
71 | inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, | 72 | inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, |
72 | 73 | ||
73 | data: Option<Box<ItemTreeData>>, | 74 | data: Option<Box<ItemTreeData>>, |
@@ -88,7 +89,7 @@ impl ItemTree { | |||
88 | let mut item_tree = match_ast! { | 89 | let mut item_tree = match_ast! { |
89 | match syntax { | 90 | match syntax { |
90 | ast::SourceFile(file) => { | 91 | ast::SourceFile(file) => { |
91 | top_attrs = Some(Attrs::new(&file, &hygiene)); | 92 | top_attrs = Some(RawAttrs::new(&file, &hygiene)); |
92 | ctx.lower_module_items(&file) | 93 | ctx.lower_module_items(&file) |
93 | }, | 94 | }, |
94 | ast::MacroItems(items) => { | 95 | ast::MacroItems(items) => { |
@@ -180,12 +181,16 @@ impl ItemTree { | |||
180 | } | 181 | } |
181 | 182 | ||
182 | /// Returns the inner attributes of the source file. | 183 | /// Returns the inner attributes of the source file. |
183 | pub fn top_level_attrs(&self) -> &Attrs { | 184 | pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { |
184 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) | 185 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate) |
185 | } | 186 | } |
186 | 187 | ||
187 | pub fn attrs(&self, of: AttrOwner) -> &Attrs { | 188 | pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs { |
188 | self.attrs.get(&of).unwrap_or(&Attrs::EMPTY) | 189 | self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY) |
190 | } | ||
191 | |||
192 | pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs { | ||
193 | self.raw_attrs(of).clone().filter(db, krate) | ||
189 | } | 194 | } |
190 | 195 | ||
191 | /// Returns the lowered inner items that `ast` corresponds to. | 196 | /// Returns the lowered inner items that `ast` corresponds to. |
@@ -490,7 +495,6 @@ pub struct Import { | |||
490 | pub alias: Option<ImportAlias>, | 495 | pub alias: Option<ImportAlias>, |
491 | pub visibility: RawVisibilityId, | 496 | pub visibility: RawVisibilityId, |
492 | pub is_glob: bool, | 497 | pub is_glob: bool, |
493 | pub is_prelude: bool, | ||
494 | /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many | 498 | /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many |
495 | /// `Import`s can map to the same `use` item. | 499 | /// `Import`s can map to the same `use` item. |
496 | pub ast_id: FileAstId<ast::Use>, | 500 | pub ast_id: FileAstId<ast::Use>, |
@@ -506,8 +510,6 @@ pub struct ExternCrate { | |||
506 | pub name: Name, | 510 | pub name: Name, |
507 | pub alias: Option<ImportAlias>, | 511 | pub alias: Option<ImportAlias>, |
508 | pub visibility: RawVisibilityId, | 512 | pub visibility: RawVisibilityId, |
509 | /// Whether this is a `#[macro_use] extern crate ...`. | ||
510 | pub is_macro_use: bool, | ||
511 | pub ast_id: FileAstId<ast::ExternCrate>, | 513 | pub ast_id: FileAstId<ast::ExternCrate>, |
512 | } | 514 | } |
513 | 515 | ||
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 7de385ee8..3b206ef85 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -10,7 +10,6 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | attr::Attrs, | ||
14 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, | 13 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, |
15 | type_ref::LifetimeRef, | 14 | type_ref::LifetimeRef, |
16 | }; | 15 | }; |
@@ -105,7 +104,7 @@ impl Ctx { | |||
105 | | ast::Item::MacroDef(_) => {} | 104 | | ast::Item::MacroDef(_) => {} |
106 | }; | 105 | }; |
107 | 106 | ||
108 | let attrs = Attrs::new(item, &self.hygiene); | 107 | let attrs = RawAttrs::new(item, &self.hygiene); |
109 | let items = match item { | 108 | let items = match item { |
110 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), | 109 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), |
111 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), | 110 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), |
@@ -138,7 +137,7 @@ impl Ctx { | |||
138 | items | 137 | items |
139 | } | 138 | } |
140 | 139 | ||
141 | fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) { | 140 | fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) { |
142 | match self.tree.attrs.entry(item) { | 141 | match self.tree.attrs.entry(item) { |
143 | Entry::Occupied(mut entry) => { | 142 | Entry::Occupied(mut entry) => { |
144 | *entry.get_mut() = entry.get().merge(attrs); | 143 | *entry.get_mut() = entry.get().merge(attrs); |
@@ -205,7 +204,7 @@ impl Ctx { | |||
205 | for field in fields.fields() { | 204 | for field in fields.fields() { |
206 | if let Some(data) = self.lower_record_field(&field) { | 205 | if let Some(data) = self.lower_record_field(&field) { |
207 | let idx = self.data().fields.alloc(data); | 206 | let idx = self.data().fields.alloc(data); |
208 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 207 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
209 | } | 208 | } |
210 | } | 209 | } |
211 | let end = self.next_field_idx(); | 210 | let end = self.next_field_idx(); |
@@ -225,7 +224,7 @@ impl Ctx { | |||
225 | for (i, field) in fields.fields().enumerate() { | 224 | for (i, field) in fields.fields().enumerate() { |
226 | let data = self.lower_tuple_field(i, &field); | 225 | let data = self.lower_tuple_field(i, &field); |
227 | let idx = self.data().fields.alloc(data); | 226 | let idx = self.data().fields.alloc(data); |
228 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 227 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
229 | } | 228 | } |
230 | let end = self.next_field_idx(); | 229 | let end = self.next_field_idx(); |
231 | IdRange::new(start..end) | 230 | IdRange::new(start..end) |
@@ -270,7 +269,7 @@ impl Ctx { | |||
270 | for variant in variants.variants() { | 269 | for variant in variants.variants() { |
271 | if let Some(data) = self.lower_variant(&variant) { | 270 | if let Some(data) = self.lower_variant(&variant) { |
272 | let idx = self.data().variants.alloc(data); | 271 | let idx = self.data().variants.alloc(data); |
273 | self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene)); | 272 | self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene)); |
274 | } | 273 | } |
275 | } | 274 | } |
276 | let end = self.next_variant_idx(); | 275 | let end = self.next_variant_idx(); |
@@ -438,7 +437,7 @@ impl Ctx { | |||
438 | self.with_inherited_visibility(visibility, |this| { | 437 | self.with_inherited_visibility(visibility, |this| { |
439 | list.assoc_items() | 438 | list.assoc_items() |
440 | .filter_map(|item| { | 439 | .filter_map(|item| { |
441 | let attrs = Attrs::new(&item, &this.hygiene); | 440 | let attrs = RawAttrs::new(&item, &this.hygiene); |
442 | this.collect_inner_items(item.syntax()); | 441 | this.collect_inner_items(item.syntax()); |
443 | this.lower_assoc_item(&item).map(|item| { | 442 | this.lower_assoc_item(&item).map(|item| { |
444 | this.add_attrs(ModItem::from(item).into(), attrs); | 443 | this.add_attrs(ModItem::from(item).into(), attrs); |
@@ -475,7 +474,7 @@ impl Ctx { | |||
475 | .filter_map(|item| { | 474 | .filter_map(|item| { |
476 | self.collect_inner_items(item.syntax()); | 475 | self.collect_inner_items(item.syntax()); |
477 | let assoc = self.lower_assoc_item(&item)?; | 476 | let assoc = self.lower_assoc_item(&item)?; |
478 | let attrs = Attrs::new(&item, &self.hygiene); | 477 | let attrs = RawAttrs::new(&item, &self.hygiene); |
479 | self.add_attrs(ModItem::from(assoc).into(), attrs); | 478 | self.add_attrs(ModItem::from(assoc).into(), attrs); |
480 | Some(assoc) | 479 | Some(assoc) |
481 | }) | 480 | }) |
@@ -486,8 +485,6 @@ impl Ctx { | |||
486 | } | 485 | } |
487 | 486 | ||
488 | fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> { | 487 | fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> { |
489 | // FIXME: cfg_attr | ||
490 | let is_prelude = use_item.has_atom_attr("prelude_import"); | ||
491 | let visibility = self.lower_visibility(use_item); | 488 | let visibility = self.lower_visibility(use_item); |
492 | let ast_id = self.source_ast_id_map.ast_id(use_item); | 489 | let ast_id = self.source_ast_id_map.ast_id(use_item); |
493 | 490 | ||
@@ -503,7 +500,6 @@ impl Ctx { | |||
503 | alias, | 500 | alias, |
504 | visibility, | 501 | visibility, |
505 | is_glob, | 502 | is_glob, |
506 | is_prelude, | ||
507 | ast_id, | 503 | ast_id, |
508 | index: imports.len(), | 504 | index: imports.len(), |
509 | }))); | 505 | }))); |
@@ -523,10 +519,8 @@ impl Ctx { | |||
523 | }); | 519 | }); |
524 | let visibility = self.lower_visibility(extern_crate); | 520 | let visibility = self.lower_visibility(extern_crate); |
525 | let ast_id = self.source_ast_id_map.ast_id(extern_crate); | 521 | let ast_id = self.source_ast_id_map.ast_id(extern_crate); |
526 | // FIXME: cfg_attr | ||
527 | let is_macro_use = extern_crate.has_atom_attr("macro_use"); | ||
528 | 522 | ||
529 | let res = ExternCrate { name, alias, visibility, is_macro_use, ast_id }; | 523 | let res = ExternCrate { name, alias, visibility, ast_id }; |
530 | Some(id(self.data().extern_crates.alloc(res))) | 524 | Some(id(self.data().extern_crates.alloc(res))) |
531 | } | 525 | } |
532 | 526 | ||
@@ -560,7 +554,7 @@ impl Ctx { | |||
560 | list.extern_items() | 554 | list.extern_items() |
561 | .filter_map(|item| { | 555 | .filter_map(|item| { |
562 | self.collect_inner_items(item.syntax()); | 556 | self.collect_inner_items(item.syntax()); |
563 | let attrs = Attrs::new(&item, &self.hygiene); | 557 | let attrs = RawAttrs::new(&item, &self.hygiene); |
564 | let id: ModItem = match item { | 558 | let id: ModItem = match item { |
565 | ast::ExternItem::Fn(ast) => { | 559 | ast::ExternItem::Fn(ast) => { |
566 | let func_id = self.lower_function(&ast)?; | 560 | let func_id = self.lower_function(&ast)?; |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 7e2199a9c..ba09a9126 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -425,6 +425,16 @@ impl HasModule for AdtId { | |||
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
428 | impl HasModule for VariantId { | ||
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | ||
430 | match self { | ||
431 | VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), | ||
432 | VariantId::StructId(it) => it.lookup(db).container.module(db), | ||
433 | VariantId::UnionId(it) => it.lookup(db).container.module(db), | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | |||
428 | impl HasModule for DefWithBodyId { | 438 | impl HasModule for DefWithBodyId { |
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | 439 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { |
430 | match self { | 440 | match self { |
@@ -465,6 +475,26 @@ impl HasModule for StaticLoc { | |||
465 | } | 475 | } |
466 | } | 476 | } |
467 | 477 | ||
478 | impl AttrDefId { | ||
479 | pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { | ||
480 | match self { | ||
481 | AttrDefId::ModuleId(it) => it.krate, | ||
482 | AttrDefId::FieldId(it) => it.parent.module(db).krate, | ||
483 | AttrDefId::AdtId(it) => it.module(db).krate, | ||
484 | AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, | ||
485 | AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate, | ||
486 | AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, | ||
487 | AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, | ||
488 | AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate, | ||
489 | AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, | ||
490 | AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate, | ||
491 | // FIXME: `MacroDefId` should store the defining module, then this can implement | ||
492 | // `HasModule` | ||
493 | AttrDefId::MacroDefId(it) => it.krate, | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
468 | /// A helper trait for converting to MacroCallId | 498 | /// A helper trait for converting to MacroCallId |
469 | pub trait AsMacroCall { | 499 | pub trait AsMacroCall { |
470 | fn as_call_id( | 500 | fn as_call_id( |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 1936348fb..a636ec77d 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -136,23 +136,35 @@ struct Import { | |||
136 | } | 136 | } |
137 | 137 | ||
138 | impl Import { | 138 | impl Import { |
139 | fn from_use(tree: &ItemTree, id: ItemTreeId<item_tree::Import>) -> Self { | 139 | fn from_use( |
140 | db: &dyn DefDatabase, | ||
141 | krate: CrateId, | ||
142 | tree: &ItemTree, | ||
143 | id: ItemTreeId<item_tree::Import>, | ||
144 | ) -> Self { | ||
140 | let it = &tree[id.value]; | 145 | let it = &tree[id.value]; |
146 | let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); | ||
141 | let visibility = &tree[it.visibility]; | 147 | let visibility = &tree[it.visibility]; |
142 | Self { | 148 | Self { |
143 | path: it.path.clone(), | 149 | path: it.path.clone(), |
144 | alias: it.alias.clone(), | 150 | alias: it.alias.clone(), |
145 | visibility: visibility.clone(), | 151 | visibility: visibility.clone(), |
146 | is_glob: it.is_glob, | 152 | is_glob: it.is_glob, |
147 | is_prelude: it.is_prelude, | 153 | is_prelude: attrs.by_key("prelude_import").exists(), |
148 | is_extern_crate: false, | 154 | is_extern_crate: false, |
149 | is_macro_use: false, | 155 | is_macro_use: false, |
150 | source: ImportSource::Import(id), | 156 | source: ImportSource::Import(id), |
151 | } | 157 | } |
152 | } | 158 | } |
153 | 159 | ||
154 | fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) -> Self { | 160 | fn from_extern_crate( |
161 | db: &dyn DefDatabase, | ||
162 | krate: CrateId, | ||
163 | tree: &ItemTree, | ||
164 | id: ItemTreeId<item_tree::ExternCrate>, | ||
165 | ) -> Self { | ||
155 | let it = &tree[id.value]; | 166 | let it = &tree[id.value]; |
167 | let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); | ||
156 | let visibility = &tree[it.visibility]; | 168 | let visibility = &tree[it.visibility]; |
157 | Self { | 169 | Self { |
158 | path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), | 170 | path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), |
@@ -161,7 +173,7 @@ impl Import { | |||
161 | is_glob: false, | 173 | is_glob: false, |
162 | is_prelude: false, | 174 | is_prelude: false, |
163 | is_extern_crate: true, | 175 | is_extern_crate: true, |
164 | is_macro_use: it.is_macro_use, | 176 | is_macro_use: attrs.by_key("macro_use").exists(), |
165 | source: ImportSource::ExternCrate(id), | 177 | source: ImportSource::ExternCrate(id), |
166 | } | 178 | } |
167 | } | 179 | } |
@@ -221,17 +233,20 @@ impl DefCollector<'_> { | |||
221 | let item_tree = self.db.item_tree(file_id.into()); | 233 | let item_tree = self.db.item_tree(file_id.into()); |
222 | let module_id = self.def_map.root; | 234 | let module_id = self.def_map.root; |
223 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; | 235 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; |
224 | let mut root_collector = ModCollector { | 236 | if item_tree |
225 | def_collector: &mut *self, | 237 | .top_level_attrs(self.db, self.def_map.krate) |
226 | macro_depth: 0, | 238 | .cfg() |
227 | module_id, | 239 | .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) |
228 | file_id: file_id.into(), | ||
229 | item_tree: &item_tree, | ||
230 | mod_dir: ModDir::root(), | ||
231 | }; | ||
232 | if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg)) | ||
233 | { | 240 | { |
234 | root_collector.collect(item_tree.top_level_items()); | 241 | ModCollector { |
242 | def_collector: &mut *self, | ||
243 | macro_depth: 0, | ||
244 | module_id, | ||
245 | file_id: file_id.into(), | ||
246 | item_tree: &item_tree, | ||
247 | mod_dir: ModDir::root(), | ||
248 | } | ||
249 | .collect(item_tree.top_level_items()); | ||
235 | } | 250 | } |
236 | 251 | ||
237 | // main name resolution fixed-point loop. | 252 | // main name resolution fixed-point loop. |
@@ -905,6 +920,8 @@ struct ModCollector<'a, 'b> { | |||
905 | 920 | ||
906 | impl ModCollector<'_, '_> { | 921 | impl ModCollector<'_, '_> { |
907 | fn collect(&mut self, items: &[ModItem]) { | 922 | fn collect(&mut self, items: &[ModItem]) { |
923 | let krate = self.def_collector.def_map.krate; | ||
924 | |||
908 | // Note: don't assert that inserted value is fresh: it's simply not true | 925 | // Note: don't assert that inserted value is fresh: it's simply not true |
909 | // for macros. | 926 | // for macros. |
910 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); | 927 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); |
@@ -921,11 +938,16 @@ impl ModCollector<'_, '_> { | |||
921 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 938 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
922 | // any other items. | 939 | // any other items. |
923 | for item in items { | 940 | for item in items { |
924 | let attrs = self.item_tree.attrs((*item).into()); | 941 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into()); |
925 | if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { | 942 | if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { |
926 | if let ModItem::ExternCrate(id) = item { | 943 | if let ModItem::ExternCrate(id) = item { |
927 | let import = self.item_tree[*id].clone(); | 944 | let import = self.item_tree[*id].clone(); |
928 | if import.is_macro_use { | 945 | let attrs = self.item_tree.attrs( |
946 | self.def_collector.db, | ||
947 | krate, | ||
948 | ModItem::from(*id).into(), | ||
949 | ); | ||
950 | if attrs.by_key("macro_use").exists() { | ||
929 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); | 951 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); |
930 | } | 952 | } |
931 | } | 953 | } |
@@ -933,7 +955,7 @@ impl ModCollector<'_, '_> { | |||
933 | } | 955 | } |
934 | 956 | ||
935 | for &item in items { | 957 | for &item in items { |
936 | let attrs = self.item_tree.attrs(item.into()); | 958 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into()); |
937 | if let Some(cfg) = attrs.cfg() { | 959 | if let Some(cfg) = attrs.cfg() { |
938 | if !self.is_cfg_enabled(&cfg) { | 960 | if !self.is_cfg_enabled(&cfg) { |
939 | self.emit_unconfigured_diagnostic(item, &cfg); | 961 | self.emit_unconfigured_diagnostic(item, &cfg); |
@@ -946,11 +968,13 @@ impl ModCollector<'_, '_> { | |||
946 | 968 | ||
947 | let mut def = None; | 969 | let mut def = None; |
948 | match item { | 970 | match item { |
949 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), | 971 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs), |
950 | ModItem::Import(import_id) => { | 972 | ModItem::Import(import_id) => { |
951 | self.def_collector.unresolved_imports.push(ImportDirective { | 973 | self.def_collector.unresolved_imports.push(ImportDirective { |
952 | module_id: self.module_id, | 974 | module_id: self.module_id, |
953 | import: Import::from_use( | 975 | import: Import::from_use( |
976 | self.def_collector.db, | ||
977 | krate, | ||
954 | &self.item_tree, | 978 | &self.item_tree, |
955 | InFile::new(self.file_id, import_id), | 979 | InFile::new(self.file_id, import_id), |
956 | ), | 980 | ), |
@@ -961,6 +985,8 @@ impl ModCollector<'_, '_> { | |||
961 | self.def_collector.unresolved_imports.push(ImportDirective { | 985 | self.def_collector.unresolved_imports.push(ImportDirective { |
962 | module_id: self.module_id, | 986 | module_id: self.module_id, |
963 | import: Import::from_extern_crate( | 987 | import: Import::from_extern_crate( |
988 | self.def_collector.db, | ||
989 | krate, | ||
964 | &self.item_tree, | 990 | &self.item_tree, |
965 | InFile::new(self.file_id, import_id), | 991 | InFile::new(self.file_id, import_id), |
966 | ), | 992 | ), |
@@ -975,7 +1001,11 @@ impl ModCollector<'_, '_> { | |||
975 | 1001 | ||
976 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it | 1002 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it |
977 | // to define builtin macros, so we support at least that part. | 1003 | // to define builtin macros, so we support at least that part. |
978 | let attrs = self.item_tree.attrs(ModItem::from(id).into()); | 1004 | let attrs = self.item_tree.attrs( |
1005 | self.def_collector.db, | ||
1006 | krate, | ||
1007 | ModItem::from(id).into(), | ||
1008 | ); | ||
979 | if attrs.by_key("rustc_builtin_macro").exists() { | 1009 | if attrs.by_key("rustc_builtin_macro").exists() { |
980 | let krate = self.def_collector.def_map.krate; | 1010 | let krate = self.def_collector.def_map.krate; |
981 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) | 1011 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) |
@@ -1012,7 +1042,7 @@ impl ModCollector<'_, '_> { | |||
1012 | ModItem::Function(id) => { | 1042 | ModItem::Function(id) => { |
1013 | let func = &self.item_tree[id]; | 1043 | let func = &self.item_tree[id]; |
1014 | 1044 | ||
1015 | self.collect_proc_macro_def(&func.name, attrs); | 1045 | self.collect_proc_macro_def(&func.name, &attrs); |
1016 | 1046 | ||
1017 | def = Some(DefData { | 1047 | def = Some(DefData { |
1018 | id: FunctionLoc { | 1048 | id: FunctionLoc { |
@@ -1032,7 +1062,7 @@ impl ModCollector<'_, '_> { | |||
1032 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1062 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1033 | // in which case we don't add the invocation, just a single attribute | 1063 | // in which case we don't add the invocation, just a single attribute |
1034 | // macro invocation | 1064 | // macro invocation |
1035 | self.collect_derives(attrs, it.ast_id.upcast()); | 1065 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1036 | 1066 | ||
1037 | def = Some(DefData { | 1067 | def = Some(DefData { |
1038 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1068 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1049,7 +1079,7 @@ impl ModCollector<'_, '_> { | |||
1049 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1079 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1050 | // in which case we don't add the invocation, just a single attribute | 1080 | // in which case we don't add the invocation, just a single attribute |
1051 | // macro invocation | 1081 | // macro invocation |
1052 | self.collect_derives(attrs, it.ast_id.upcast()); | 1082 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1053 | 1083 | ||
1054 | def = Some(DefData { | 1084 | def = Some(DefData { |
1055 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1085 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1066,7 +1096,7 @@ impl ModCollector<'_, '_> { | |||
1066 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1096 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1067 | // in which case we don't add the invocation, just a single attribute | 1097 | // in which case we don't add the invocation, just a single attribute |
1068 | // macro invocation | 1098 | // macro invocation |
1069 | self.collect_derives(attrs, it.ast_id.upcast()); | 1099 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1070 | 1100 | ||
1071 | def = Some(DefData { | 1101 | def = Some(DefData { |
1072 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1102 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1259,20 +1289,20 @@ impl ModCollector<'_, '_> { | |||
1259 | } | 1289 | } |
1260 | 1290 | ||
1261 | fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) { | 1291 | fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) { |
1262 | for derive_subtree in attrs.by_key("derive").tt_values() { | 1292 | for derive in attrs.by_key("derive").attrs() { |
1263 | // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree | 1293 | match derive.parse_derive() { |
1264 | for tt in &derive_subtree.token_trees { | 1294 | Some(derive_macros) => { |
1265 | let ident = match &tt { | 1295 | for path in derive_macros { |
1266 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident, | 1296 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); |
1267 | tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok | 1297 | self.def_collector |
1268 | _ => continue, // anything else would be an error (which we currently ignore) | 1298 | .unexpanded_attribute_macros |
1269 | }; | 1299 | .push(DeriveDirective { module_id: self.module_id, ast_id }); |
1270 | let path = ModPath::from_tt_ident(ident); | 1300 | } |
1271 | 1301 | } | |
1272 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); | 1302 | None => { |
1273 | self.def_collector | 1303 | // FIXME: diagnose |
1274 | .unexpanded_attribute_macros | 1304 | log::debug!("malformed derive: {:?}", derive); |
1275 | .push(DeriveDirective { module_id: self.module_id, ast_id }); | 1305 | } |
1276 | } | 1306 | } |
1277 | } | 1307 | } |
1278 | } | 1308 | } |
@@ -1303,8 +1333,9 @@ impl ModCollector<'_, '_> { | |||
1303 | } | 1333 | } |
1304 | 1334 | ||
1305 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { | 1335 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { |
1336 | let krate = self.def_collector.def_map.krate; | ||
1306 | let mac = &self.item_tree[id]; | 1337 | let mac = &self.item_tree[id]; |
1307 | let attrs = self.item_tree.attrs(ModItem::from(id).into()); | 1338 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); |
1308 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); | 1339 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); |
1309 | 1340 | ||
1310 | let export_attr = attrs.by_key("macro_export"); | 1341 | let export_attr = attrs.by_key("macro_export"); |
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index a4d1fb8f3..c459fa66d 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs | |||
@@ -13,8 +13,8 @@ use test_utils::mark; | |||
13 | 13 | ||
14 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; | 14 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; |
15 | 15 | ||
16 | fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { | 16 | fn compute_crate_def_map(ra_fixture: &str) -> Arc<CrateDefMap> { |
17 | let db = TestDB::with_files(fixture); | 17 | let db = TestDB::with_files(ra_fixture); |
18 | let krate = db.crate_graph().iter().next().unwrap(); | 18 | let krate = db.crate_graph().iter().next().unwrap(); |
19 | db.crate_def_map(krate) | 19 | db.crate_def_map(krate) |
20 | } | 20 | } |
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index 1a7b98831..58d69d3c6 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use base_db::fixture::WithFixture; | 1 | use base_db::fixture::WithFixture; |
2 | use test_utils::mark; | ||
2 | 3 | ||
3 | use crate::test_db::TestDB; | 4 | use crate::test_db::TestDB; |
4 | 5 | ||
@@ -119,3 +120,20 @@ fn inactive_item() { | |||
119 | "#, | 120 | "#, |
120 | ); | 121 | ); |
121 | } | 122 | } |
123 | |||
124 | /// Tests that `cfg` attributes behind `cfg_attr` is handled properly. | ||
125 | #[test] | ||
126 | fn inactive_via_cfg_attr() { | ||
127 | mark::check!(cfg_attr_active); | ||
128 | check_diagnostics( | ||
129 | r#" | ||
130 | //- /lib.rs | ||
131 | #[cfg_attr(not(never), cfg(no))] fn f() {} | ||
132 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled | ||
133 | |||
134 | #[cfg_attr(not(never), cfg(not(no)))] fn f() {} | ||
135 | |||
136 | #[cfg_attr(never, cfg(no))] fn g() {} | ||
137 | "#, | ||
138 | ); | ||
139 | } | ||
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs index 6fe2ee78a..f9bf5bc72 100644 --- a/crates/hir_def/src/nameres/tests/macros.rs +++ b/crates/hir_def/src/nameres/tests/macros.rs | |||
@@ -632,11 +632,11 @@ pub struct bar; | |||
632 | #[test] | 632 | #[test] |
633 | fn expand_derive() { | 633 | fn expand_derive() { |
634 | let map = compute_crate_def_map( | 634 | let map = compute_crate_def_map( |
635 | " | 635 | r#" |
636 | //- /main.rs crate:main deps:core | 636 | //- /main.rs crate:main deps:core |
637 | use core::*; | 637 | use core::Copy; |
638 | 638 | ||
639 | #[derive(Copy, Clone)] | 639 | #[derive(Copy, core::Clone)] |
640 | struct Foo; | 640 | struct Foo; |
641 | 641 | ||
642 | //- /core.rs crate:core | 642 | //- /core.rs crate:core |
@@ -645,7 +645,7 @@ fn expand_derive() { | |||
645 | 645 | ||
646 | #[rustc_builtin_macro] | 646 | #[rustc_builtin_macro] |
647 | pub macro Clone {} | 647 | pub macro Clone {} |
648 | ", | 648 | "#, |
649 | ); | 649 | ); |
650 | assert_eq!(map.modules[map.root].scope.impls().len(), 2); | 650 | assert_eq!(map.modules[map.root].scope.impls().len(), 2); |
651 | } | 651 | } |
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 00a69a8a6..e2bf85bbc 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -9,11 +9,8 @@ use std::{ | |||
9 | 9 | ||
10 | use crate::{body::LowerCtx, type_ref::LifetimeRef}; | 10 | use crate::{body::LowerCtx, type_ref::LifetimeRef}; |
11 | use base_db::CrateId; | 11 | use base_db::CrateId; |
12 | use hir_expand::{ | 12 | use hir_expand::{hygiene::Hygiene, name::Name}; |
13 | hygiene::Hygiene, | 13 | use syntax::ast; |
14 | name::{AsName, Name}, | ||
15 | }; | ||
16 | use syntax::ast::{self}; | ||
17 | 14 | ||
18 | use crate::{ | 15 | use crate::{ |
19 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
@@ -56,11 +53,6 @@ impl ModPath { | |||
56 | ModPath { kind, segments } | 53 | ModPath { kind, segments } |
57 | } | 54 | } |
58 | 55 | ||
59 | /// Converts an `tt::Ident` into a single-identifier `Path`. | ||
60 | pub(crate) fn from_tt_ident(ident: &tt::Ident) -> ModPath { | ||
61 | ident.as_name().into() | ||
62 | } | ||
63 | |||
64 | /// Calls `cb` with all paths, represented by this use item. | 56 | /// Calls `cb` with all paths, represented by this use item. |
65 | pub(crate) fn expand_use_item( | 57 | pub(crate) fn expand_use_item( |
66 | item_src: InFile<ast::Use>, | 58 | item_src: InFile<ast::Use>, |
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 7fb4caea3..2f44876a8 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -152,7 +152,9 @@ pub mod known { | |||
152 | str, | 152 | str, |
153 | // Special names | 153 | // Special names |
154 | macro_rules, | 154 | macro_rules, |
155 | derive, | ||
155 | doc, | 156 | doc, |
157 | cfg_attr, | ||
156 | // Components of known path (value or mod name) | 158 | // Components of known path (value or mod name) |
157 | std, | 159 | std, |
158 | core, | 160 | core, |
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 8ad50a2ee..60e0cd4ad 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs | |||
@@ -181,8 +181,8 @@ fn caller() { | |||
181 | call<|>ee(); | 181 | call<|>ee(); |
182 | } | 182 | } |
183 | "#, | 183 | "#, |
184 | "callee FN FileId(0) 0..14 3..9", | 184 | "callee Function FileId(0) 0..14 3..9", |
185 | &["caller FN FileId(0) 15..44 18..24 : [33..39]"], | 185 | &["caller Function FileId(0) 15..44 18..24 : [33..39]"], |
186 | &[], | 186 | &[], |
187 | ); | 187 | ); |
188 | } | 188 | } |
@@ -197,8 +197,8 @@ fn caller() { | |||
197 | callee(); | 197 | callee(); |
198 | } | 198 | } |
199 | "#, | 199 | "#, |
200 | "callee FN FileId(0) 0..14 3..9", | 200 | "callee Function FileId(0) 0..14 3..9", |
201 | &["caller FN FileId(0) 15..44 18..24 : [33..39]"], | 201 | &["caller Function FileId(0) 15..44 18..24 : [33..39]"], |
202 | &[], | 202 | &[], |
203 | ); | 203 | ); |
204 | } | 204 | } |
@@ -214,8 +214,8 @@ fn caller() { | |||
214 | callee(); | 214 | callee(); |
215 | } | 215 | } |
216 | "#, | 216 | "#, |
217 | "callee FN FileId(0) 0..14 3..9", | 217 | "callee Function FileId(0) 0..14 3..9", |
218 | &["caller FN FileId(0) 15..58 18..24 : [33..39, 47..53]"], | 218 | &["caller Function FileId(0) 15..58 18..24 : [33..39, 47..53]"], |
219 | &[], | 219 | &[], |
220 | ); | 220 | ); |
221 | } | 221 | } |
@@ -234,10 +234,10 @@ fn caller2() { | |||
234 | callee(); | 234 | callee(); |
235 | } | 235 | } |
236 | "#, | 236 | "#, |
237 | "callee FN FileId(0) 0..14 3..9", | 237 | "callee Function FileId(0) 0..14 3..9", |
238 | &[ | 238 | &[ |
239 | "caller1 FN FileId(0) 15..45 18..25 : [34..40]", | 239 | "caller1 Function FileId(0) 15..45 18..25 : [34..40]", |
240 | "caller2 FN FileId(0) 47..77 50..57 : [66..72]", | 240 | "caller2 Function FileId(0) 47..77 50..57 : [66..72]", |
241 | ], | 241 | ], |
242 | &[], | 242 | &[], |
243 | ); | 243 | ); |
@@ -263,10 +263,10 @@ mod tests { | |||
263 | } | 263 | } |
264 | } | 264 | } |
265 | "#, | 265 | "#, |
266 | "callee FN FileId(0) 0..14 3..9", | 266 | "callee Function FileId(0) 0..14 3..9", |
267 | &[ | 267 | &[ |
268 | "caller1 FN FileId(0) 15..45 18..25 : [34..40]", | 268 | "caller1 Function FileId(0) 15..45 18..25 : [34..40]", |
269 | "test_caller FN FileId(0) 95..149 110..121 : [134..140]", | 269 | "test_caller Function FileId(0) 95..149 110..121 : [134..140]", |
270 | ], | 270 | ], |
271 | &[], | 271 | &[], |
272 | ); | 272 | ); |
@@ -287,8 +287,8 @@ fn caller() { | |||
287 | //- /foo/mod.rs | 287 | //- /foo/mod.rs |
288 | pub fn callee() {} | 288 | pub fn callee() {} |
289 | "#, | 289 | "#, |
290 | "callee FN FileId(1) 0..18 7..13", | 290 | "callee Function FileId(1) 0..18 7..13", |
291 | &["caller FN FileId(0) 27..56 30..36 : [45..51]"], | 291 | &["caller Function FileId(0) 27..56 30..36 : [45..51]"], |
292 | &[], | 292 | &[], |
293 | ); | 293 | ); |
294 | } | 294 | } |
@@ -304,9 +304,9 @@ fn call<|>er() { | |||
304 | callee(); | 304 | callee(); |
305 | } | 305 | } |
306 | "#, | 306 | "#, |
307 | "caller FN FileId(0) 15..58 18..24", | 307 | "caller Function FileId(0) 15..58 18..24", |
308 | &[], | 308 | &[], |
309 | &["callee FN FileId(0) 0..14 3..9 : [33..39, 47..53]"], | 309 | &["callee Function FileId(0) 0..14 3..9 : [33..39, 47..53]"], |
310 | ); | 310 | ); |
311 | } | 311 | } |
312 | 312 | ||
@@ -325,9 +325,9 @@ fn call<|>er() { | |||
325 | //- /foo/mod.rs | 325 | //- /foo/mod.rs |
326 | pub fn callee() {} | 326 | pub fn callee() {} |
327 | "#, | 327 | "#, |
328 | "caller FN FileId(0) 27..56 30..36", | 328 | "caller Function FileId(0) 27..56 30..36", |
329 | &[], | 329 | &[], |
330 | &["callee FN FileId(1) 0..18 7..13 : [45..51]"], | 330 | &["callee Function FileId(1) 0..18 7..13 : [45..51]"], |
331 | ); | 331 | ); |
332 | } | 332 | } |
333 | 333 | ||
@@ -348,9 +348,9 @@ fn caller3() { | |||
348 | 348 | ||
349 | } | 349 | } |
350 | "#, | 350 | "#, |
351 | "caller2 FN FileId(0) 33..64 36..43", | 351 | "caller2 Function FileId(0) 33..64 36..43", |
352 | &["caller1 FN FileId(0) 0..31 3..10 : [19..26]"], | 352 | &["caller1 Function FileId(0) 0..31 3..10 : [19..26]"], |
353 | &["caller3 FN FileId(0) 66..83 69..76 : [52..59]"], | 353 | &["caller3 Function FileId(0) 66..83 69..76 : [52..59]"], |
354 | ); | 354 | ); |
355 | } | 355 | } |
356 | 356 | ||
@@ -368,9 +368,9 @@ fn main() { | |||
368 | a<|>() | 368 | a<|>() |
369 | } | 369 | } |
370 | "#, | 370 | "#, |
371 | "a FN FileId(0) 0..18 3..4", | 371 | "a Function FileId(0) 0..18 3..4", |
372 | &["main FN FileId(0) 31..52 34..38 : [47..48]"], | 372 | &["main Function FileId(0) 31..52 34..38 : [47..48]"], |
373 | &["b FN FileId(0) 20..29 23..24 : [13..14]"], | 373 | &["b Function FileId(0) 20..29 23..24 : [13..14]"], |
374 | ); | 374 | ); |
375 | 375 | ||
376 | check_hierarchy( | 376 | check_hierarchy( |
@@ -385,8 +385,8 @@ fn main() { | |||
385 | a() | 385 | a() |
386 | } | 386 | } |
387 | "#, | 387 | "#, |
388 | "b FN FileId(0) 20..29 23..24", | 388 | "b Function FileId(0) 20..29 23..24", |
389 | &["a FN FileId(0) 0..18 3..4 : [13..14]"], | 389 | &["a Function FileId(0) 0..18 3..4 : [13..14]"], |
390 | &[], | 390 | &[], |
391 | ); | 391 | ); |
392 | } | 392 | } |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 13240672f..e8b896623 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -166,7 +166,7 @@ fn missing_record_expr_field_fix( | |||
166 | def_file_id = source.file_id; | 166 | def_file_id = source.file_id; |
167 | source.value.record_field_list()? | 167 | source.value.record_field_list()? |
168 | } | 168 | } |
169 | VariantDef::EnumVariant(e) => { | 169 | VariantDef::Variant(e) => { |
170 | module = e.module(sema.db); | 170 | module = e.module(sema.db); |
171 | let source = e.source(sema.db); | 171 | let source = e.source(sema.db); |
172 | def_file_id = source.file_id; | 172 | def_file_id = source.file_id; |
diff --git a/crates/ide/src/display.rs b/crates/ide/src/display.rs index 0650915c5..bae9e40df 100644 --- a/crates/ide/src/display.rs +++ b/crates/ide/src/display.rs | |||
@@ -1,10 +1,9 @@ | |||
1 | //! This module contains utilities for turning SyntaxNodes and HIR types | 1 | //! This module contains utilities for turning SyntaxNodes and HIR types |
2 | //! into types that may be used to render in a UI. | 2 | //! into types that may be used to render in a UI. |
3 | 3 | ||
4 | mod navigation_target; | 4 | pub(crate) mod navigation_target; |
5 | mod short_label; | 5 | mod short_label; |
6 | 6 | ||
7 | pub use navigation_target::NavigationTarget; | ||
8 | pub(crate) use navigation_target::{ToNav, TryToNav}; | 7 | pub(crate) use navigation_target::{ToNav, TryToNav}; |
9 | pub(crate) use short_label::ShortLabel; | 8 | pub(crate) use short_label::ShortLabel; |
10 | 9 | ||
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 54b33a98e..cd8ec54fa 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -1,28 +1,51 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::fmt; | ||
4 | |||
3 | use either::Either; | 5 | use either::Either; |
4 | use hir::{ | 6 | use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource}; |
5 | AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirFileId, InFile, ModuleSource, | 7 | use ide_db::{ |
8 | base_db::{FileId, SourceDatabase}, | ||
9 | symbol_index::FileSymbolKind, | ||
6 | }; | 10 | }; |
7 | use ide_db::base_db::{FileId, SourceDatabase}; | ||
8 | use ide_db::{defs::Definition, RootDatabase}; | 11 | use ide_db::{defs::Definition, RootDatabase}; |
9 | use syntax::{ | 12 | use syntax::{ |
10 | ast::{self, NameOwner}, | 13 | ast::{self, NameOwner}, |
11 | match_ast, AstNode, SmolStr, | 14 | match_ast, AstNode, SmolStr, TextRange, |
12 | SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM}, | ||
13 | TextRange, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | use crate::FileSymbol; | 17 | use crate::FileSymbol; |
17 | 18 | ||
18 | use super::short_label::ShortLabel; | 19 | use super::short_label::ShortLabel; |
19 | 20 | ||
21 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
22 | pub enum SymbolKind { | ||
23 | Module, | ||
24 | Impl, | ||
25 | Field, | ||
26 | TypeParam, | ||
27 | LifetimeParam, | ||
28 | ValueParam, | ||
29 | SelfParam, | ||
30 | Local, | ||
31 | Function, | ||
32 | Const, | ||
33 | Static, | ||
34 | Struct, | ||
35 | Enum, | ||
36 | Variant, | ||
37 | Union, | ||
38 | TypeAlias, | ||
39 | Trait, | ||
40 | Macro, | ||
41 | } | ||
42 | |||
20 | /// `NavigationTarget` represents and element in the editor's UI which you can | 43 | /// `NavigationTarget` represents and element in the editor's UI which you can |
21 | /// click on to navigate to a particular piece of code. | 44 | /// click on to navigate to a particular piece of code. |
22 | /// | 45 | /// |
23 | /// Typically, a `NavigationTarget` corresponds to some element in the source | 46 | /// Typically, a `NavigationTarget` corresponds to some element in the source |
24 | /// code, like a function or a struct, but this is not strictly required. | 47 | /// code, like a function or a struct, but this is not strictly required. |
25 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 48 | #[derive(Clone, PartialEq, Eq, Hash)] |
26 | pub struct NavigationTarget { | 49 | pub struct NavigationTarget { |
27 | pub file_id: FileId, | 50 | pub file_id: FileId, |
28 | /// Range which encompasses the whole element. | 51 | /// Range which encompasses the whole element. |
@@ -42,12 +65,30 @@ pub struct NavigationTarget { | |||
42 | /// Clients should place the cursor on this range when navigating to this target. | 65 | /// Clients should place the cursor on this range when navigating to this target. |
43 | pub focus_range: Option<TextRange>, | 66 | pub focus_range: Option<TextRange>, |
44 | pub name: SmolStr, | 67 | pub name: SmolStr, |
45 | pub kind: SyntaxKind, | 68 | pub kind: Option<SymbolKind>, |
46 | pub container_name: Option<SmolStr>, | 69 | pub container_name: Option<SmolStr>, |
47 | pub description: Option<String>, | 70 | pub description: Option<String>, |
48 | pub docs: Option<Documentation>, | 71 | pub docs: Option<Documentation>, |
49 | } | 72 | } |
50 | 73 | ||
74 | impl fmt::Debug for NavigationTarget { | ||
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
76 | let mut f = f.debug_struct("NavigationTarget"); | ||
77 | macro_rules! opt { | ||
78 | ($($name:ident)*) => {$( | ||
79 | if let Some(it) = &self.$name { | ||
80 | f.field(stringify!($name), it); | ||
81 | } | ||
82 | )*} | ||
83 | } | ||
84 | f.field("file_id", &self.file_id).field("full_range", &self.full_range); | ||
85 | opt!(focus_range); | ||
86 | f.field("name", &self.name); | ||
87 | opt!(kind container_name description docs); | ||
88 | f.finish() | ||
89 | } | ||
90 | } | ||
91 | |||
51 | pub(crate) trait ToNav { | 92 | pub(crate) trait ToNav { |
52 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; | 93 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; |
53 | } | 94 | } |
@@ -71,7 +112,7 @@ impl NavigationTarget { | |||
71 | name, | 112 | name, |
72 | None, | 113 | None, |
73 | frange.range, | 114 | frange.range, |
74 | src.value.syntax().kind(), | 115 | SymbolKind::Module, |
75 | ); | 116 | ); |
76 | res.docs = module.attrs(db).docs(); | 117 | res.docs = module.attrs(db).docs(); |
77 | res.description = src.value.short_label(); | 118 | res.description = src.value.short_label(); |
@@ -88,8 +129,13 @@ impl NavigationTarget { | |||
88 | 129 | ||
89 | #[cfg(test)] | 130 | #[cfg(test)] |
90 | pub(crate) fn debug_render(&self) -> String { | 131 | pub(crate) fn debug_render(&self) -> String { |
91 | let mut buf = | 132 | let mut buf = format!( |
92 | format!("{} {:?} {:?} {:?}", self.name, self.kind, self.file_id, self.full_range); | 133 | "{} {:?} {:?} {:?}", |
134 | self.name, | ||
135 | self.kind.unwrap(), | ||
136 | self.file_id, | ||
137 | self.full_range | ||
138 | ); | ||
93 | if let Some(focus_range) = self.focus_range { | 139 | if let Some(focus_range) = self.focus_range { |
94 | buf.push_str(&format!(" {:?}", focus_range)) | 140 | buf.push_str(&format!(" {:?}", focus_range)) |
95 | } | 141 | } |
@@ -103,6 +149,7 @@ impl NavigationTarget { | |||
103 | pub(crate) fn from_named( | 149 | pub(crate) fn from_named( |
104 | db: &RootDatabase, | 150 | db: &RootDatabase, |
105 | node: InFile<&dyn ast::NameOwner>, | 151 | node: InFile<&dyn ast::NameOwner>, |
152 | kind: SymbolKind, | ||
106 | ) -> NavigationTarget { | 153 | ) -> NavigationTarget { |
107 | let name = | 154 | let name = |
108 | node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); | 155 | node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); |
@@ -110,32 +157,7 @@ impl NavigationTarget { | |||
110 | node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range); | 157 | node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range); |
111 | let frange = node.map(|it| it.syntax()).original_file_range(db); | 158 | let frange = node.map(|it| it.syntax()).original_file_range(db); |
112 | 159 | ||
113 | NavigationTarget::from_syntax( | 160 | NavigationTarget::from_syntax(frange.file_id, name, focus_range, frange.range, kind) |
114 | frange.file_id, | ||
115 | name, | ||
116 | focus_range, | ||
117 | frange.range, | ||
118 | node.value.syntax().kind(), | ||
119 | ) | ||
120 | } | ||
121 | |||
122 | /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner` | ||
123 | pub(crate) fn from_doc_commented( | ||
124 | db: &RootDatabase, | ||
125 | named: InFile<&dyn ast::NameOwner>, | ||
126 | node: InFile<&dyn ast::DocCommentsOwner>, | ||
127 | ) -> NavigationTarget { | ||
128 | let name = | ||
129 | named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); | ||
130 | let frange = node.map(|it| it.syntax()).original_file_range(db); | ||
131 | |||
132 | NavigationTarget::from_syntax( | ||
133 | frange.file_id, | ||
134 | name, | ||
135 | None, | ||
136 | frange.range, | ||
137 | node.value.syntax().kind(), | ||
138 | ) | ||
139 | } | 161 | } |
140 | 162 | ||
141 | fn from_syntax( | 163 | fn from_syntax( |
@@ -143,12 +165,12 @@ impl NavigationTarget { | |||
143 | name: SmolStr, | 165 | name: SmolStr, |
144 | focus_range: Option<TextRange>, | 166 | focus_range: Option<TextRange>, |
145 | full_range: TextRange, | 167 | full_range: TextRange, |
146 | kind: SyntaxKind, | 168 | kind: SymbolKind, |
147 | ) -> NavigationTarget { | 169 | ) -> NavigationTarget { |
148 | NavigationTarget { | 170 | NavigationTarget { |
149 | file_id, | 171 | file_id, |
150 | name, | 172 | name, |
151 | kind, | 173 | kind: Some(kind), |
152 | full_range, | 174 | full_range, |
153 | focus_range, | 175 | focus_range, |
154 | container_name: None, | 176 | container_name: None, |
@@ -163,12 +185,22 @@ impl ToNav for FileSymbol { | |||
163 | NavigationTarget { | 185 | NavigationTarget { |
164 | file_id: self.file_id, | 186 | file_id: self.file_id, |
165 | name: self.name.clone(), | 187 | name: self.name.clone(), |
166 | kind: self.kind, | 188 | kind: Some(match self.kind { |
189 | FileSymbolKind::Function => SymbolKind::Function, | ||
190 | FileSymbolKind::Struct => SymbolKind::Struct, | ||
191 | FileSymbolKind::Enum => SymbolKind::Enum, | ||
192 | FileSymbolKind::Trait => SymbolKind::Trait, | ||
193 | FileSymbolKind::Module => SymbolKind::Module, | ||
194 | FileSymbolKind::TypeAlias => SymbolKind::TypeAlias, | ||
195 | FileSymbolKind::Const => SymbolKind::Const, | ||
196 | FileSymbolKind::Static => SymbolKind::Static, | ||
197 | FileSymbolKind::Macro => SymbolKind::Macro, | ||
198 | }), | ||
167 | full_range: self.range, | 199 | full_range: self.range, |
168 | focus_range: self.name_range, | 200 | focus_range: self.name_range, |
169 | container_name: self.container_name.clone(), | 201 | container_name: self.container_name.clone(), |
170 | description: description_from_symbol(db, self), | 202 | description: description_from_symbol(db, self), |
171 | docs: docs_from_symbol(db, self), | 203 | docs: None, |
172 | } | 204 | } |
173 | } | 205 | } |
174 | } | 206 | } |
@@ -176,7 +208,15 @@ impl ToNav for FileSymbol { | |||
176 | impl TryToNav for Definition { | 208 | impl TryToNav for Definition { |
177 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | 209 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { |
178 | match self { | 210 | match self { |
179 | Definition::Macro(it) => Some(it.to_nav(db)), | 211 | Definition::Macro(it) => { |
212 | // FIXME: Currently proc-macro do not have ast-node, | ||
213 | // such that it does not have source | ||
214 | // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913 | ||
215 | if it.is_proc_macro() { | ||
216 | return None; | ||
217 | } | ||
218 | Some(it.to_nav(db)) | ||
219 | } | ||
180 | Definition::Field(it) => Some(it.to_nav(db)), | 220 | Definition::Field(it) => Some(it.to_nav(db)), |
181 | Definition::ModuleDef(it) => it.try_to_nav(db), | 221 | Definition::ModuleDef(it) => it.try_to_nav(db), |
182 | Definition::SelfType(it) => Some(it.to_nav(db)), | 222 | Definition::SelfType(it) => Some(it.to_nav(db)), |
@@ -193,7 +233,7 @@ impl TryToNav for hir::ModuleDef { | |||
193 | hir::ModuleDef::Module(it) => it.to_nav(db), | 233 | hir::ModuleDef::Module(it) => it.to_nav(db), |
194 | hir::ModuleDef::Function(it) => it.to_nav(db), | 234 | hir::ModuleDef::Function(it) => it.to_nav(db), |
195 | hir::ModuleDef::Adt(it) => it.to_nav(db), | 235 | hir::ModuleDef::Adt(it) => it.to_nav(db), |
196 | hir::ModuleDef::EnumVariant(it) => it.to_nav(db), | 236 | hir::ModuleDef::Variant(it) => it.to_nav(db), |
197 | hir::ModuleDef::Const(it) => it.to_nav(db), | 237 | hir::ModuleDef::Const(it) => it.to_nav(db), |
198 | hir::ModuleDef::Static(it) => it.to_nav(db), | 238 | hir::ModuleDef::Static(it) => it.to_nav(db), |
199 | hir::ModuleDef::Trait(it) => it.to_nav(db), | 239 | hir::ModuleDef::Trait(it) => it.to_nav(db), |
@@ -204,16 +244,36 @@ impl TryToNav for hir::ModuleDef { | |||
204 | } | 244 | } |
205 | } | 245 | } |
206 | 246 | ||
207 | pub(crate) trait ToNavFromAst {} | 247 | pub(crate) trait ToNavFromAst { |
208 | impl ToNavFromAst for hir::Function {} | 248 | const KIND: SymbolKind; |
209 | impl ToNavFromAst for hir::Const {} | 249 | } |
210 | impl ToNavFromAst for hir::Static {} | 250 | impl ToNavFromAst for hir::Function { |
211 | impl ToNavFromAst for hir::Struct {} | 251 | const KIND: SymbolKind = SymbolKind::Function; |
212 | impl ToNavFromAst for hir::Enum {} | 252 | } |
213 | impl ToNavFromAst for hir::EnumVariant {} | 253 | impl ToNavFromAst for hir::Const { |
214 | impl ToNavFromAst for hir::Union {} | 254 | const KIND: SymbolKind = SymbolKind::Const; |
215 | impl ToNavFromAst for hir::TypeAlias {} | 255 | } |
216 | impl ToNavFromAst for hir::Trait {} | 256 | impl ToNavFromAst for hir::Static { |
257 | const KIND: SymbolKind = SymbolKind::Static; | ||
258 | } | ||
259 | impl ToNavFromAst for hir::Struct { | ||
260 | const KIND: SymbolKind = SymbolKind::Struct; | ||
261 | } | ||
262 | impl ToNavFromAst for hir::Enum { | ||
263 | const KIND: SymbolKind = SymbolKind::Enum; | ||
264 | } | ||
265 | impl ToNavFromAst for hir::Variant { | ||
266 | const KIND: SymbolKind = SymbolKind::Variant; | ||
267 | } | ||
268 | impl ToNavFromAst for hir::Union { | ||
269 | const KIND: SymbolKind = SymbolKind::Union; | ||
270 | } | ||
271 | impl ToNavFromAst for hir::TypeAlias { | ||
272 | const KIND: SymbolKind = SymbolKind::TypeAlias; | ||
273 | } | ||
274 | impl ToNavFromAst for hir::Trait { | ||
275 | const KIND: SymbolKind = SymbolKind::Trait; | ||
276 | } | ||
217 | 277 | ||
218 | impl<D> ToNav for D | 278 | impl<D> ToNav for D |
219 | where | 279 | where |
@@ -222,8 +282,11 @@ where | |||
222 | { | 282 | { |
223 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 283 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
224 | let src = self.source(db); | 284 | let src = self.source(db); |
225 | let mut res = | 285 | let mut res = NavigationTarget::from_named( |
226 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); | 286 | db, |
287 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | ||
288 | D::KIND, | ||
289 | ); | ||
227 | res.docs = self.docs(db); | 290 | res.docs = self.docs(db); |
228 | res.description = src.value.short_label(); | 291 | res.description = src.value.short_label(); |
229 | res | 292 | res |
@@ -241,7 +304,7 @@ impl ToNav for hir::Module { | |||
241 | } | 304 | } |
242 | }; | 305 | }; |
243 | let frange = src.with_value(syntax).original_file_range(db); | 306 | let frange = src.with_value(syntax).original_file_range(db); |
244 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) | 307 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module) |
245 | } | 308 | } |
246 | } | 309 | } |
247 | 310 | ||
@@ -265,7 +328,7 @@ impl ToNav for hir::Impl { | |||
265 | "impl".into(), | 328 | "impl".into(), |
266 | focus_range, | 329 | focus_range, |
267 | frange.range, | 330 | frange.range, |
268 | src.value.syntax().kind(), | 331 | SymbolKind::Impl, |
269 | ) | 332 | ) |
270 | } | 333 | } |
271 | } | 334 | } |
@@ -276,7 +339,8 @@ impl ToNav for hir::Field { | |||
276 | 339 | ||
277 | match &src.value { | 340 | match &src.value { |
278 | FieldSource::Named(it) => { | 341 | FieldSource::Named(it) => { |
279 | let mut res = NavigationTarget::from_named(db, src.with_value(it)); | 342 | let mut res = |
343 | NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field); | ||
280 | res.docs = self.docs(db); | 344 | res.docs = self.docs(db); |
281 | res.description = it.short_label(); | 345 | res.description = it.short_label(); |
282 | res | 346 | res |
@@ -288,7 +352,7 @@ impl ToNav for hir::Field { | |||
288 | "".into(), | 352 | "".into(), |
289 | None, | 353 | None, |
290 | frange.range, | 354 | frange.range, |
291 | it.syntax().kind(), | 355 | SymbolKind::Field, |
292 | ) | 356 | ) |
293 | } | 357 | } |
294 | } | 358 | } |
@@ -299,8 +363,11 @@ impl ToNav for hir::MacroDef { | |||
299 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 363 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
300 | let src = self.source(db); | 364 | let src = self.source(db); |
301 | log::debug!("nav target {:#?}", src.value.syntax()); | 365 | log::debug!("nav target {:#?}", src.value.syntax()); |
302 | let mut res = | 366 | let mut res = NavigationTarget::from_named( |
303 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); | 367 | db, |
368 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | ||
369 | SymbolKind::Macro, | ||
370 | ); | ||
304 | res.docs = self.docs(db); | 371 | res.docs = self.docs(db); |
305 | res | 372 | res |
306 | } | 373 | } |
@@ -340,10 +407,11 @@ impl ToNav for hir::Local { | |||
340 | Some(it) => it.to_string().into(), | 407 | Some(it) => it.to_string().into(), |
341 | None => "".into(), | 408 | None => "".into(), |
342 | }; | 409 | }; |
410 | let kind = if self.is_param(db) { SymbolKind::ValueParam } else { SymbolKind::Local }; | ||
343 | NavigationTarget { | 411 | NavigationTarget { |
344 | file_id: full_range.file_id, | 412 | file_id: full_range.file_id, |
345 | name, | 413 | name, |
346 | kind: IDENT_PAT, | 414 | kind: Some(kind), |
347 | full_range: full_range.range, | 415 | full_range: full_range.range, |
348 | focus_range: None, | 416 | focus_range: None, |
349 | container_name: None, | 417 | container_name: None, |
@@ -367,7 +435,7 @@ impl ToNav for hir::TypeParam { | |||
367 | NavigationTarget { | 435 | NavigationTarget { |
368 | file_id: src.file_id.original_file(db), | 436 | file_id: src.file_id.original_file(db), |
369 | name: self.name(db).to_string().into(), | 437 | name: self.name(db).to_string().into(), |
370 | kind: TYPE_PARAM, | 438 | kind: Some(SymbolKind::TypeParam), |
371 | full_range, | 439 | full_range, |
372 | focus_range, | 440 | focus_range, |
373 | container_name: None, | 441 | container_name: None, |
@@ -384,7 +452,7 @@ impl ToNav for hir::LifetimeParam { | |||
384 | NavigationTarget { | 452 | NavigationTarget { |
385 | file_id: src.file_id.original_file(db), | 453 | file_id: src.file_id.original_file(db), |
386 | name: self.name(db).to_string().into(), | 454 | name: self.name(db).to_string().into(), |
387 | kind: LIFETIME_PARAM, | 455 | kind: Some(SymbolKind::LifetimeParam), |
388 | full_range, | 456 | full_range, |
389 | focus_range: Some(full_range), | 457 | focus_range: Some(full_range), |
390 | container_name: None, | 458 | container_name: None, |
@@ -394,30 +462,6 @@ impl ToNav for hir::LifetimeParam { | |||
394 | } | 462 | } |
395 | } | 463 | } |
396 | 464 | ||
397 | pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<Documentation> { | ||
398 | let parse = db.parse(symbol.file_id); | ||
399 | let node = symbol.ptr.to_node(parse.tree().syntax()); | ||
400 | let file_id = HirFileId::from(symbol.file_id); | ||
401 | |||
402 | let it = match_ast! { | ||
403 | match node { | ||
404 | ast::Fn(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
405 | ast::Struct(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
406 | ast::Enum(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
407 | ast::Trait(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
408 | ast::Module(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
409 | ast::TypeAlias(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
410 | ast::Const(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
411 | ast::Static(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
412 | ast::RecordField(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
413 | ast::Variant(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
414 | ast::MacroCall(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
415 | _ => return None, | ||
416 | } | ||
417 | }; | ||
418 | it.docs() | ||
419 | } | ||
420 | |||
421 | /// Get a description of a symbol. | 465 | /// Get a description of a symbol. |
422 | /// | 466 | /// |
423 | /// e.g. `struct Name`, `enum Name`, `fn Name` | 467 | /// e.g. `struct Name`, `enum Name`, `fn Name` |
@@ -465,34 +509,21 @@ fn foo() { enum FooInner { } } | |||
465 | 0, | 509 | 0, |
466 | ), | 510 | ), |
467 | full_range: 0..17, | 511 | full_range: 0..17, |
468 | focus_range: Some( | 512 | focus_range: 5..13, |
469 | 5..13, | ||
470 | ), | ||
471 | name: "FooInner", | 513 | name: "FooInner", |
472 | kind: ENUM, | 514 | kind: Enum, |
473 | container_name: None, | 515 | description: "enum FooInner", |
474 | description: Some( | ||
475 | "enum FooInner", | ||
476 | ), | ||
477 | docs: None, | ||
478 | }, | 516 | }, |
479 | NavigationTarget { | 517 | NavigationTarget { |
480 | file_id: FileId( | 518 | file_id: FileId( |
481 | 0, | 519 | 0, |
482 | ), | 520 | ), |
483 | full_range: 29..46, | 521 | full_range: 29..46, |
484 | focus_range: Some( | 522 | focus_range: 34..42, |
485 | 34..42, | ||
486 | ), | ||
487 | name: "FooInner", | 523 | name: "FooInner", |
488 | kind: ENUM, | 524 | kind: Enum, |
489 | container_name: Some( | 525 | container_name: "foo", |
490 | "foo", | 526 | description: "enum FooInner", |
491 | ), | ||
492 | description: Some( | ||
493 | "enum FooInner", | ||
494 | ), | ||
495 | docs: None, | ||
496 | }, | 527 | }, |
497 | ] | 528 | ] |
498 | "#]] | 529 | "#]] |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 79c081cac..b61ea0b3e 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -181,7 +181,7 @@ fn rewrite_intra_doc_link( | |||
181 | ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), | 181 | ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), |
182 | ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), | 182 | ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), |
183 | ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), | 183 | ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), |
184 | ModuleDef::EnumVariant(it) => it.resolve_doc_path(db, link, ns), | 184 | ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns), |
185 | ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), | 185 | ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), |
186 | ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), | 186 | ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), |
187 | ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), | 187 | ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), |
@@ -390,7 +390,7 @@ fn get_symbol_filename(db: &dyn HirDatabase, definition: &ModuleDef) -> Option<S | |||
390 | ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), | 390 | ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), |
391 | ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()), | 391 | ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()), |
392 | ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), | 392 | ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), |
393 | ModuleDef::EnumVariant(ev) => { | 393 | ModuleDef::Variant(ev) => { |
394 | format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) | 394 | format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) |
395 | } | 395 | } |
396 | ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), | 396 | ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), |
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index c51531391..32556dad3 100644 --- a/crates/ide/src/file_structure.rs +++ b/crates/ide/src/file_structure.rs | |||
@@ -1,15 +1,17 @@ | |||
1 | use syntax::{ | 1 | use syntax::{ |
2 | ast::{self, AttrsOwner, GenericParamsOwner, NameOwner}, | 2 | ast::{self, AttrsOwner, GenericParamsOwner, NameOwner}, |
3 | match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, WalkEvent, | 3 | match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use crate::SymbolKind; | ||
7 | |||
6 | #[derive(Debug, Clone)] | 8 | #[derive(Debug, Clone)] |
7 | pub struct StructureNode { | 9 | pub struct StructureNode { |
8 | pub parent: Option<usize>, | 10 | pub parent: Option<usize>, |
9 | pub label: String, | 11 | pub label: String, |
10 | pub navigation_range: TextRange, | 12 | pub navigation_range: TextRange, |
11 | pub node_range: TextRange, | 13 | pub node_range: TextRange, |
12 | pub kind: SyntaxKind, | 14 | pub kind: SymbolKind, |
13 | pub detail: Option<String>, | 15 | pub detail: Option<String>, |
14 | pub deprecated: bool, | 16 | pub deprecated: bool, |
15 | } | 17 | } |
@@ -51,25 +53,27 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> { | |||
51 | } | 53 | } |
52 | 54 | ||
53 | fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | 55 | fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { |
54 | fn decl<N: NameOwner + AttrsOwner>(node: N) -> Option<StructureNode> { | 56 | fn decl<N: NameOwner + AttrsOwner>(node: N, kind: SymbolKind) -> Option<StructureNode> { |
55 | decl_with_detail(&node, None) | 57 | decl_with_detail(&node, None, kind) |
56 | } | 58 | } |
57 | 59 | ||
58 | fn decl_with_type_ref<N: NameOwner + AttrsOwner>( | 60 | fn decl_with_type_ref<N: NameOwner + AttrsOwner>( |
59 | node: &N, | 61 | node: &N, |
60 | type_ref: Option<ast::Type>, | 62 | type_ref: Option<ast::Type>, |
63 | kind: SymbolKind, | ||
61 | ) -> Option<StructureNode> { | 64 | ) -> Option<StructureNode> { |
62 | let detail = type_ref.map(|type_ref| { | 65 | let detail = type_ref.map(|type_ref| { |
63 | let mut detail = String::new(); | 66 | let mut detail = String::new(); |
64 | collapse_ws(type_ref.syntax(), &mut detail); | 67 | collapse_ws(type_ref.syntax(), &mut detail); |
65 | detail | 68 | detail |
66 | }); | 69 | }); |
67 | decl_with_detail(node, detail) | 70 | decl_with_detail(node, detail, kind) |
68 | } | 71 | } |
69 | 72 | ||
70 | fn decl_with_detail<N: NameOwner + AttrsOwner>( | 73 | fn decl_with_detail<N: NameOwner + AttrsOwner>( |
71 | node: &N, | 74 | node: &N, |
72 | detail: Option<String>, | 75 | detail: Option<String>, |
76 | kind: SymbolKind, | ||
73 | ) -> Option<StructureNode> { | 77 | ) -> Option<StructureNode> { |
74 | let name = node.name()?; | 78 | let name = node.name()?; |
75 | 79 | ||
@@ -78,7 +82,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
78 | label: name.text().to_string(), | 82 | label: name.text().to_string(), |
79 | navigation_range: name.syntax().text_range(), | 83 | navigation_range: name.syntax().text_range(), |
80 | node_range: node.syntax().text_range(), | 84 | node_range: node.syntax().text_range(), |
81 | kind: node.syntax().kind(), | 85 | kind, |
82 | detail, | 86 | detail, |
83 | deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"), | 87 | deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"), |
84 | }) | 88 | }) |
@@ -117,18 +121,18 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
117 | collapse_ws(ret_type.syntax(), &mut detail); | 121 | collapse_ws(ret_type.syntax(), &mut detail); |
118 | } | 122 | } |
119 | 123 | ||
120 | decl_with_detail(&it, Some(detail)) | 124 | decl_with_detail(&it, Some(detail), SymbolKind::Function) |
121 | }, | 125 | }, |
122 | ast::Struct(it) => decl(it), | 126 | ast::Struct(it) => decl(it, SymbolKind::Struct), |
123 | ast::Union(it) => decl(it), | 127 | ast::Union(it) => decl(it, SymbolKind::Union), |
124 | ast::Enum(it) => decl(it), | 128 | ast::Enum(it) => decl(it, SymbolKind::Enum), |
125 | ast::Variant(it) => decl(it), | 129 | ast::Variant(it) => decl(it, SymbolKind::Variant), |
126 | ast::Trait(it) => decl(it), | 130 | ast::Trait(it) => decl(it, SymbolKind::Trait), |
127 | ast::Module(it) => decl(it), | 131 | ast::Module(it) => decl(it, SymbolKind::Module), |
128 | ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty()), | 132 | ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias), |
129 | ast::RecordField(it) => decl_with_type_ref(&it, it.ty()), | 133 | ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field), |
130 | ast::Const(it) => decl_with_type_ref(&it, it.ty()), | 134 | ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const), |
131 | ast::Static(it) => decl_with_type_ref(&it, it.ty()), | 135 | ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static), |
132 | ast::Impl(it) => { | 136 | ast::Impl(it) => { |
133 | let target_type = it.self_ty()?; | 137 | let target_type = it.self_ty()?; |
134 | let target_trait = it.trait_(); | 138 | let target_trait = it.trait_(); |
@@ -144,13 +148,13 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
144 | label, | 148 | label, |
145 | navigation_range: target_type.syntax().text_range(), | 149 | navigation_range: target_type.syntax().text_range(), |
146 | node_range: it.syntax().text_range(), | 150 | node_range: it.syntax().text_range(), |
147 | kind: it.syntax().kind(), | 151 | kind: SymbolKind::Impl, |
148 | detail: None, | 152 | detail: None, |
149 | deprecated: false, | 153 | deprecated: false, |
150 | }; | 154 | }; |
151 | Some(node) | 155 | Some(node) |
152 | }, | 156 | }, |
153 | ast::MacroRules(it) => decl(it), | 157 | ast::MacroRules(it) => decl(it, SymbolKind::Macro), |
154 | _ => None, | 158 | _ => None, |
155 | } | 159 | } |
156 | } | 160 | } |
@@ -222,7 +226,7 @@ fn very_obsolete() {} | |||
222 | label: "Foo", | 226 | label: "Foo", |
223 | navigation_range: 8..11, | 227 | navigation_range: 8..11, |
224 | node_range: 1..26, | 228 | node_range: 1..26, |
225 | kind: STRUCT, | 229 | kind: Struct, |
226 | detail: None, | 230 | detail: None, |
227 | deprecated: false, | 231 | deprecated: false, |
228 | }, | 232 | }, |
@@ -233,7 +237,7 @@ fn very_obsolete() {} | |||
233 | label: "x", | 237 | label: "x", |
234 | navigation_range: 18..19, | 238 | navigation_range: 18..19, |
235 | node_range: 18..24, | 239 | node_range: 18..24, |
236 | kind: RECORD_FIELD, | 240 | kind: Field, |
237 | detail: Some( | 241 | detail: Some( |
238 | "i32", | 242 | "i32", |
239 | ), | 243 | ), |
@@ -244,7 +248,7 @@ fn very_obsolete() {} | |||
244 | label: "m", | 248 | label: "m", |
245 | navigation_range: 32..33, | 249 | navigation_range: 32..33, |
246 | node_range: 28..158, | 250 | node_range: 28..158, |
247 | kind: MODULE, | 251 | kind: Module, |
248 | detail: None, | 252 | detail: None, |
249 | deprecated: false, | 253 | deprecated: false, |
250 | }, | 254 | }, |
@@ -255,7 +259,7 @@ fn very_obsolete() {} | |||
255 | label: "bar1", | 259 | label: "bar1", |
256 | navigation_range: 43..47, | 260 | navigation_range: 43..47, |
257 | node_range: 40..52, | 261 | node_range: 40..52, |
258 | kind: FN, | 262 | kind: Function, |
259 | detail: Some( | 263 | detail: Some( |
260 | "fn()", | 264 | "fn()", |
261 | ), | 265 | ), |
@@ -268,7 +272,7 @@ fn very_obsolete() {} | |||
268 | label: "bar2", | 272 | label: "bar2", |
269 | navigation_range: 60..64, | 273 | navigation_range: 60..64, |
270 | node_range: 57..81, | 274 | node_range: 57..81, |
271 | kind: FN, | 275 | kind: Function, |
272 | detail: Some( | 276 | detail: Some( |
273 | "fn<T>(t: T) -> T", | 277 | "fn<T>(t: T) -> T", |
274 | ), | 278 | ), |
@@ -281,7 +285,7 @@ fn very_obsolete() {} | |||
281 | label: "bar3", | 285 | label: "bar3", |
282 | navigation_range: 89..93, | 286 | navigation_range: 89..93, |
283 | node_range: 86..156, | 287 | node_range: 86..156, |
284 | kind: FN, | 288 | kind: Function, |
285 | detail: Some( | 289 | detail: Some( |
286 | "fn<A, B>(a: A, b: B) -> Vec< u32 >", | 290 | "fn<A, B>(a: A, b: B) -> Vec< u32 >", |
287 | ), | 291 | ), |
@@ -292,7 +296,7 @@ fn very_obsolete() {} | |||
292 | label: "E", | 296 | label: "E", |
293 | navigation_range: 165..166, | 297 | navigation_range: 165..166, |
294 | node_range: 160..180, | 298 | node_range: 160..180, |
295 | kind: ENUM, | 299 | kind: Enum, |
296 | detail: None, | 300 | detail: None, |
297 | deprecated: false, | 301 | deprecated: false, |
298 | }, | 302 | }, |
@@ -303,7 +307,7 @@ fn very_obsolete() {} | |||
303 | label: "X", | 307 | label: "X", |
304 | navigation_range: 169..170, | 308 | navigation_range: 169..170, |
305 | node_range: 169..170, | 309 | node_range: 169..170, |
306 | kind: VARIANT, | 310 | kind: Variant, |
307 | detail: None, | 311 | detail: None, |
308 | deprecated: false, | 312 | deprecated: false, |
309 | }, | 313 | }, |
@@ -314,7 +318,7 @@ fn very_obsolete() {} | |||
314 | label: "Y", | 318 | label: "Y", |
315 | navigation_range: 172..173, | 319 | navigation_range: 172..173, |
316 | node_range: 172..178, | 320 | node_range: 172..178, |
317 | kind: VARIANT, | 321 | kind: Variant, |
318 | detail: None, | 322 | detail: None, |
319 | deprecated: false, | 323 | deprecated: false, |
320 | }, | 324 | }, |
@@ -323,7 +327,7 @@ fn very_obsolete() {} | |||
323 | label: "T", | 327 | label: "T", |
324 | navigation_range: 186..187, | 328 | navigation_range: 186..187, |
325 | node_range: 181..193, | 329 | node_range: 181..193, |
326 | kind: TYPE_ALIAS, | 330 | kind: TypeAlias, |
327 | detail: Some( | 331 | detail: Some( |
328 | "()", | 332 | "()", |
329 | ), | 333 | ), |
@@ -334,7 +338,7 @@ fn very_obsolete() {} | |||
334 | label: "S", | 338 | label: "S", |
335 | navigation_range: 201..202, | 339 | navigation_range: 201..202, |
336 | node_range: 194..213, | 340 | node_range: 194..213, |
337 | kind: STATIC, | 341 | kind: Static, |
338 | detail: Some( | 342 | detail: Some( |
339 | "i32", | 343 | "i32", |
340 | ), | 344 | ), |
@@ -345,7 +349,7 @@ fn very_obsolete() {} | |||
345 | label: "C", | 349 | label: "C", |
346 | navigation_range: 220..221, | 350 | navigation_range: 220..221, |
347 | node_range: 214..232, | 351 | node_range: 214..232, |
348 | kind: CONST, | 352 | kind: Const, |
349 | detail: Some( | 353 | detail: Some( |
350 | "i32", | 354 | "i32", |
351 | ), | 355 | ), |
@@ -356,7 +360,7 @@ fn very_obsolete() {} | |||
356 | label: "impl E", | 360 | label: "impl E", |
357 | navigation_range: 239..240, | 361 | navigation_range: 239..240, |
358 | node_range: 234..243, | 362 | node_range: 234..243, |
359 | kind: IMPL, | 363 | kind: Impl, |
360 | detail: None, | 364 | detail: None, |
361 | deprecated: false, | 365 | deprecated: false, |
362 | }, | 366 | }, |
@@ -365,7 +369,7 @@ fn very_obsolete() {} | |||
365 | label: "impl fmt::Debug for E", | 369 | label: "impl fmt::Debug for E", |
366 | navigation_range: 265..266, | 370 | navigation_range: 265..266, |
367 | node_range: 245..269, | 371 | node_range: 245..269, |
368 | kind: IMPL, | 372 | kind: Impl, |
369 | detail: None, | 373 | detail: None, |
370 | deprecated: false, | 374 | deprecated: false, |
371 | }, | 375 | }, |
@@ -374,7 +378,7 @@ fn very_obsolete() {} | |||
374 | label: "mc", | 378 | label: "mc", |
375 | navigation_range: 284..286, | 379 | navigation_range: 284..286, |
376 | node_range: 271..303, | 380 | node_range: 271..303, |
377 | kind: MACRO_RULES, | 381 | kind: Macro, |
378 | detail: None, | 382 | detail: None, |
379 | deprecated: false, | 383 | deprecated: false, |
380 | }, | 384 | }, |
@@ -383,7 +387,7 @@ fn very_obsolete() {} | |||
383 | label: "mcexp", | 387 | label: "mcexp", |
384 | navigation_range: 334..339, | 388 | navigation_range: 334..339, |
385 | node_range: 305..356, | 389 | node_range: 305..356, |
386 | kind: MACRO_RULES, | 390 | kind: Macro, |
387 | detail: None, | 391 | detail: None, |
388 | deprecated: false, | 392 | deprecated: false, |
389 | }, | 393 | }, |
@@ -392,7 +396,7 @@ fn very_obsolete() {} | |||
392 | label: "mcexp", | 396 | label: "mcexp", |
393 | navigation_range: 387..392, | 397 | navigation_range: 387..392, |
394 | node_range: 358..409, | 398 | node_range: 358..409, |
395 | kind: MACRO_RULES, | 399 | kind: Macro, |
396 | detail: None, | 400 | detail: None, |
397 | deprecated: false, | 401 | deprecated: false, |
398 | }, | 402 | }, |
@@ -401,7 +405,7 @@ fn very_obsolete() {} | |||
401 | label: "obsolete", | 405 | label: "obsolete", |
402 | navigation_range: 428..436, | 406 | navigation_range: 428..436, |
403 | node_range: 411..441, | 407 | node_range: 411..441, |
404 | kind: FN, | 408 | kind: Function, |
405 | detail: Some( | 409 | detail: Some( |
406 | "fn()", | 410 | "fn()", |
407 | ), | 411 | ), |
@@ -412,7 +416,7 @@ fn very_obsolete() {} | |||
412 | label: "very_obsolete", | 416 | label: "very_obsolete", |
413 | navigation_range: 481..494, | 417 | navigation_range: 481..494, |
414 | node_range: 443..499, | 418 | node_range: 443..499, |
415 | kind: FN, | 419 | kind: Function, |
416 | detail: Some( | 420 | detail: Some( |
417 | "fn()", | 421 | "fn()", |
418 | ), | 422 | ), |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index d75ae447b..431da5d9c 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -9,7 +9,7 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | display::{ToNav, TryToNav}, | 11 | display::{ToNav, TryToNav}, |
12 | FilePosition, NavigationTarget, RangeInfo, | 12 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | // Feature: Go to Definition | 15 | // Feature: Go to Definition |
@@ -86,7 +86,7 @@ fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<Nav | |||
86 | full_range: self_param.syntax().text_range(), | 86 | full_range: self_param.syntax().text_range(), |
87 | focus_range: Some(self_token.text_range()), | 87 | focus_range: Some(self_token.text_range()), |
88 | name: self_token.text().clone(), | 88 | name: self_token.text().clone(), |
89 | kind: self_token.kind(), | 89 | kind: Some(SymbolKind::SelfParam), |
90 | container_name: None, | 90 | container_name: None, |
91 | description: None, | 91 | description: None, |
92 | docs: None, | 92 | docs: None, |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index e82aad6d5..52f993cc9 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -297,7 +297,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String> | |||
297 | AssocItemContainer::Trait(t) => Some(t.name(db)), | 297 | AssocItemContainer::Trait(t) => Some(t.name(db)), |
298 | AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), | 298 | AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), |
299 | }, | 299 | }, |
300 | ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), | 300 | ModuleDef::Variant(e) => Some(e.parent_enum(db).name(db)), |
301 | _ => None, | 301 | _ => None, |
302 | }, | 302 | }, |
303 | _ => None, | 303 | _ => None, |
@@ -324,6 +324,12 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
324 | let mod_path = definition_mod_path(db, &def); | 324 | let mod_path = definition_mod_path(db, &def); |
325 | return match def { | 325 | return match def { |
326 | Definition::Macro(it) => { | 326 | Definition::Macro(it) => { |
327 | // FIXME: Currently proc-macro do not have ast-node, | ||
328 | // such that it does not have source | ||
329 | // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913 | ||
330 | if it.is_proc_macro() { | ||
331 | return None; | ||
332 | } | ||
327 | let label = macro_label(&it.source(db).value); | 333 | let label = macro_label(&it.source(db).value); |
328 | from_def_source_labeled(db, it, Some(label), mod_path) | 334 | from_def_source_labeled(db, it, Some(label), mod_path) |
329 | } | 335 | } |
@@ -349,7 +355,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
349 | ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), | 355 | ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), |
350 | ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path), | 356 | ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path), |
351 | ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path), | 357 | ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path), |
352 | ModuleDef::EnumVariant(it) => from_def_source(db, it, mod_path), | 358 | ModuleDef::Variant(it) => from_def_source(db, it, mod_path), |
353 | ModuleDef::Const(it) => from_def_source(db, it, mod_path), | 359 | ModuleDef::Const(it) => from_def_source(db, it, mod_path), |
354 | ModuleDef::Static(it) => from_def_source(db, it, mod_path), | 360 | ModuleDef::Static(it) => from_def_source(db, it, mod_path), |
355 | ModuleDef::Trait(it) => from_def_source(db, it, mod_path), | 361 | ModuleDef::Trait(it) => from_def_source(db, it, mod_path), |
@@ -2181,14 +2187,9 @@ fn foo_<|>test() {} | |||
2181 | 0, | 2187 | 0, |
2182 | ), | 2188 | ), |
2183 | full_range: 0..24, | 2189 | full_range: 0..24, |
2184 | focus_range: Some( | 2190 | focus_range: 11..19, |
2185 | 11..19, | ||
2186 | ), | ||
2187 | name: "foo_test", | 2191 | name: "foo_test", |
2188 | kind: FN, | 2192 | kind: Function, |
2189 | container_name: None, | ||
2190 | description: None, | ||
2191 | docs: None, | ||
2192 | }, | 2193 | }, |
2193 | kind: Test { | 2194 | kind: Test { |
2194 | test_id: Path( | 2195 | test_id: Path( |
@@ -2224,14 +2225,9 @@ mod tests<|> { | |||
2224 | 0, | 2225 | 0, |
2225 | ), | 2226 | ), |
2226 | full_range: 0..46, | 2227 | full_range: 0..46, |
2227 | focus_range: Some( | 2228 | focus_range: 4..9, |
2228 | 4..9, | ||
2229 | ), | ||
2230 | name: "tests", | 2229 | name: "tests", |
2231 | kind: MODULE, | 2230 | kind: Module, |
2232 | container_name: None, | ||
2233 | description: None, | ||
2234 | docs: None, | ||
2235 | }, | 2231 | }, |
2236 | kind: TestMod { | 2232 | kind: TestMod { |
2237 | path: "tests", | 2233 | path: "tests", |
@@ -2263,16 +2259,10 @@ fn main() { let s<|>t = S{ f1:0 }; } | |||
2263 | 0, | 2259 | 0, |
2264 | ), | 2260 | ), |
2265 | full_range: 0..19, | 2261 | full_range: 0..19, |
2266 | focus_range: Some( | 2262 | focus_range: 7..8, |
2267 | 7..8, | ||
2268 | ), | ||
2269 | name: "S", | 2263 | name: "S", |
2270 | kind: STRUCT, | 2264 | kind: Struct, |
2271 | container_name: None, | 2265 | description: "struct S", |
2272 | description: Some( | ||
2273 | "struct S", | ||
2274 | ), | ||
2275 | docs: None, | ||
2276 | }, | 2266 | }, |
2277 | }, | 2267 | }, |
2278 | ], | 2268 | ], |
@@ -2302,16 +2292,10 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } | |||
2302 | 0, | 2292 | 0, |
2303 | ), | 2293 | ), |
2304 | full_range: 17..37, | 2294 | full_range: 17..37, |
2305 | focus_range: Some( | 2295 | focus_range: 24..25, |
2306 | 24..25, | ||
2307 | ), | ||
2308 | name: "S", | 2296 | name: "S", |
2309 | kind: STRUCT, | 2297 | kind: Struct, |
2310 | container_name: None, | 2298 | description: "struct S", |
2311 | description: Some( | ||
2312 | "struct S", | ||
2313 | ), | ||
2314 | docs: None, | ||
2315 | }, | 2299 | }, |
2316 | }, | 2300 | }, |
2317 | HoverGotoTypeData { | 2301 | HoverGotoTypeData { |
@@ -2321,16 +2305,10 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } | |||
2321 | 0, | 2305 | 0, |
2322 | ), | 2306 | ), |
2323 | full_range: 0..16, | 2307 | full_range: 0..16, |
2324 | focus_range: Some( | 2308 | focus_range: 7..10, |
2325 | 7..10, | ||
2326 | ), | ||
2327 | name: "Arg", | 2309 | name: "Arg", |
2328 | kind: STRUCT, | 2310 | kind: Struct, |
2329 | container_name: None, | 2311 | description: "struct Arg", |
2330 | description: Some( | ||
2331 | "struct Arg", | ||
2332 | ), | ||
2333 | docs: None, | ||
2334 | }, | 2312 | }, |
2335 | }, | 2313 | }, |
2336 | ], | 2314 | ], |
@@ -2360,16 +2338,10 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } | |||
2360 | 0, | 2338 | 0, |
2361 | ), | 2339 | ), |
2362 | full_range: 17..37, | 2340 | full_range: 17..37, |
2363 | focus_range: Some( | 2341 | focus_range: 24..25, |
2364 | 24..25, | ||
2365 | ), | ||
2366 | name: "S", | 2342 | name: "S", |
2367 | kind: STRUCT, | 2343 | kind: Struct, |
2368 | container_name: None, | 2344 | description: "struct S", |
2369 | description: Some( | ||
2370 | "struct S", | ||
2371 | ), | ||
2372 | docs: None, | ||
2373 | }, | 2345 | }, |
2374 | }, | 2346 | }, |
2375 | HoverGotoTypeData { | 2347 | HoverGotoTypeData { |
@@ -2379,16 +2351,10 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } | |||
2379 | 0, | 2351 | 0, |
2380 | ), | 2352 | ), |
2381 | full_range: 0..16, | 2353 | full_range: 0..16, |
2382 | focus_range: Some( | 2354 | focus_range: 7..10, |
2383 | 7..10, | ||
2384 | ), | ||
2385 | name: "Arg", | 2355 | name: "Arg", |
2386 | kind: STRUCT, | 2356 | kind: Struct, |
2387 | container_name: None, | 2357 | description: "struct Arg", |
2388 | description: Some( | ||
2389 | "struct Arg", | ||
2390 | ), | ||
2391 | docs: None, | ||
2392 | }, | 2358 | }, |
2393 | }, | 2359 | }, |
2394 | ], | 2360 | ], |
@@ -2421,16 +2387,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
2421 | 0, | 2387 | 0, |
2422 | ), | 2388 | ), |
2423 | full_range: 0..14, | 2389 | full_range: 0..14, |
2424 | focus_range: Some( | 2390 | focus_range: 7..8, |
2425 | 7..8, | ||
2426 | ), | ||
2427 | name: "A", | 2391 | name: "A", |
2428 | kind: STRUCT, | 2392 | kind: Struct, |
2429 | container_name: None, | 2393 | description: "struct A", |
2430 | description: Some( | ||
2431 | "struct A", | ||
2432 | ), | ||
2433 | docs: None, | ||
2434 | }, | 2394 | }, |
2435 | }, | 2395 | }, |
2436 | HoverGotoTypeData { | 2396 | HoverGotoTypeData { |
@@ -2440,16 +2400,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
2440 | 0, | 2400 | 0, |
2441 | ), | 2401 | ), |
2442 | full_range: 15..29, | 2402 | full_range: 15..29, |
2443 | focus_range: Some( | 2403 | focus_range: 22..23, |
2444 | 22..23, | ||
2445 | ), | ||
2446 | name: "B", | 2404 | name: "B", |
2447 | kind: STRUCT, | 2405 | kind: Struct, |
2448 | container_name: None, | 2406 | description: "struct B", |
2449 | description: Some( | ||
2450 | "struct B", | ||
2451 | ), | ||
2452 | docs: None, | ||
2453 | }, | 2407 | }, |
2454 | }, | 2408 | }, |
2455 | HoverGotoTypeData { | 2409 | HoverGotoTypeData { |
@@ -2459,16 +2413,10 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
2459 | 0, | 2413 | 0, |
2460 | ), | 2414 | ), |
2461 | full_range: 42..60, | 2415 | full_range: 42..60, |
2462 | focus_range: Some( | 2416 | focus_range: 53..54, |
2463 | 53..54, | ||
2464 | ), | ||
2465 | name: "C", | 2417 | name: "C", |
2466 | kind: STRUCT, | 2418 | kind: Struct, |
2467 | container_name: None, | 2419 | description: "pub struct C", |
2468 | description: Some( | ||
2469 | "pub struct C", | ||
2470 | ), | ||
2471 | docs: None, | ||
2472 | }, | 2420 | }, |
2473 | }, | 2421 | }, |
2474 | ], | 2422 | ], |
@@ -2498,16 +2446,10 @@ fn main() { let s<|>t = foo(); } | |||
2498 | 0, | 2446 | 0, |
2499 | ), | 2447 | ), |
2500 | full_range: 0..12, | 2448 | full_range: 0..12, |
2501 | focus_range: Some( | 2449 | focus_range: 6..9, |
2502 | 6..9, | ||
2503 | ), | ||
2504 | name: "Foo", | 2450 | name: "Foo", |
2505 | kind: TRAIT, | 2451 | kind: Trait, |
2506 | container_name: None, | 2452 | description: "trait Foo", |
2507 | description: Some( | ||
2508 | "trait Foo", | ||
2509 | ), | ||
2510 | docs: None, | ||
2511 | }, | 2453 | }, |
2512 | }, | 2454 | }, |
2513 | ], | 2455 | ], |
@@ -2538,16 +2480,10 @@ fn main() { let s<|>t = foo(); } | |||
2538 | 0, | 2480 | 0, |
2539 | ), | 2481 | ), |
2540 | full_range: 0..15, | 2482 | full_range: 0..15, |
2541 | focus_range: Some( | 2483 | focus_range: 6..9, |
2542 | 6..9, | ||
2543 | ), | ||
2544 | name: "Foo", | 2484 | name: "Foo", |
2545 | kind: TRAIT, | 2485 | kind: Trait, |
2546 | container_name: None, | 2486 | description: "trait Foo", |
2547 | description: Some( | ||
2548 | "trait Foo", | ||
2549 | ), | ||
2550 | docs: None, | ||
2551 | }, | 2487 | }, |
2552 | }, | 2488 | }, |
2553 | HoverGotoTypeData { | 2489 | HoverGotoTypeData { |
@@ -2557,16 +2493,10 @@ fn main() { let s<|>t = foo(); } | |||
2557 | 0, | 2493 | 0, |
2558 | ), | 2494 | ), |
2559 | full_range: 16..25, | 2495 | full_range: 16..25, |
2560 | focus_range: Some( | 2496 | focus_range: 23..24, |
2561 | 23..24, | ||
2562 | ), | ||
2563 | name: "S", | 2497 | name: "S", |
2564 | kind: STRUCT, | 2498 | kind: Struct, |
2565 | container_name: None, | 2499 | description: "struct S", |
2566 | description: Some( | ||
2567 | "struct S", | ||
2568 | ), | ||
2569 | docs: None, | ||
2570 | }, | 2500 | }, |
2571 | }, | 2501 | }, |
2572 | ], | 2502 | ], |
@@ -2597,16 +2527,10 @@ fn main() { let s<|>t = foo(); } | |||
2597 | 0, | 2527 | 0, |
2598 | ), | 2528 | ), |
2599 | full_range: 0..12, | 2529 | full_range: 0..12, |
2600 | focus_range: Some( | 2530 | focus_range: 6..9, |
2601 | 6..9, | ||
2602 | ), | ||
2603 | name: "Foo", | 2531 | name: "Foo", |
2604 | kind: TRAIT, | 2532 | kind: Trait, |
2605 | container_name: None, | 2533 | description: "trait Foo", |
2606 | description: Some( | ||
2607 | "trait Foo", | ||
2608 | ), | ||
2609 | docs: None, | ||
2610 | }, | 2534 | }, |
2611 | }, | 2535 | }, |
2612 | HoverGotoTypeData { | 2536 | HoverGotoTypeData { |
@@ -2616,16 +2540,10 @@ fn main() { let s<|>t = foo(); } | |||
2616 | 0, | 2540 | 0, |
2617 | ), | 2541 | ), |
2618 | full_range: 13..25, | 2542 | full_range: 13..25, |
2619 | focus_range: Some( | 2543 | focus_range: 19..22, |
2620 | 19..22, | ||
2621 | ), | ||
2622 | name: "Bar", | 2544 | name: "Bar", |
2623 | kind: TRAIT, | 2545 | kind: Trait, |
2624 | container_name: None, | 2546 | description: "trait Bar", |
2625 | description: Some( | ||
2626 | "trait Bar", | ||
2627 | ), | ||
2628 | docs: None, | ||
2629 | }, | 2547 | }, |
2630 | }, | 2548 | }, |
2631 | ], | 2549 | ], |
@@ -2659,16 +2577,10 @@ fn main() { let s<|>t = foo(); } | |||
2659 | 0, | 2577 | 0, |
2660 | ), | 2578 | ), |
2661 | full_range: 0..15, | 2579 | full_range: 0..15, |
2662 | focus_range: Some( | 2580 | focus_range: 6..9, |
2663 | 6..9, | ||
2664 | ), | ||
2665 | name: "Foo", | 2581 | name: "Foo", |
2666 | kind: TRAIT, | 2582 | kind: Trait, |
2667 | container_name: None, | 2583 | description: "trait Foo", |
2668 | description: Some( | ||
2669 | "trait Foo", | ||
2670 | ), | ||
2671 | docs: None, | ||
2672 | }, | 2584 | }, |
2673 | }, | 2585 | }, |
2674 | HoverGotoTypeData { | 2586 | HoverGotoTypeData { |
@@ -2678,16 +2590,10 @@ fn main() { let s<|>t = foo(); } | |||
2678 | 0, | 2590 | 0, |
2679 | ), | 2591 | ), |
2680 | full_range: 16..31, | 2592 | full_range: 16..31, |
2681 | focus_range: Some( | 2593 | focus_range: 22..25, |
2682 | 22..25, | ||
2683 | ), | ||
2684 | name: "Bar", | 2594 | name: "Bar", |
2685 | kind: TRAIT, | 2595 | kind: Trait, |
2686 | container_name: None, | 2596 | description: "trait Bar", |
2687 | description: Some( | ||
2688 | "trait Bar", | ||
2689 | ), | ||
2690 | docs: None, | ||
2691 | }, | 2597 | }, |
2692 | }, | 2598 | }, |
2693 | HoverGotoTypeData { | 2599 | HoverGotoTypeData { |
@@ -2697,16 +2603,10 @@ fn main() { let s<|>t = foo(); } | |||
2697 | 0, | 2603 | 0, |
2698 | ), | 2604 | ), |
2699 | full_range: 32..44, | 2605 | full_range: 32..44, |
2700 | focus_range: Some( | 2606 | focus_range: 39..41, |
2701 | 39..41, | ||
2702 | ), | ||
2703 | name: "S1", | 2607 | name: "S1", |
2704 | kind: STRUCT, | 2608 | kind: Struct, |
2705 | container_name: None, | 2609 | description: "struct S1", |
2706 | description: Some( | ||
2707 | "struct S1", | ||
2708 | ), | ||
2709 | docs: None, | ||
2710 | }, | 2610 | }, |
2711 | }, | 2611 | }, |
2712 | HoverGotoTypeData { | 2612 | HoverGotoTypeData { |
@@ -2716,16 +2616,10 @@ fn main() { let s<|>t = foo(); } | |||
2716 | 0, | 2616 | 0, |
2717 | ), | 2617 | ), |
2718 | full_range: 45..57, | 2618 | full_range: 45..57, |
2719 | focus_range: Some( | 2619 | focus_range: 52..54, |
2720 | 52..54, | ||
2721 | ), | ||
2722 | name: "S2", | 2620 | name: "S2", |
2723 | kind: STRUCT, | 2621 | kind: Struct, |
2724 | container_name: None, | 2622 | description: "struct S2", |
2725 | description: Some( | ||
2726 | "struct S2", | ||
2727 | ), | ||
2728 | docs: None, | ||
2729 | }, | 2623 | }, |
2730 | }, | 2624 | }, |
2731 | ], | 2625 | ], |
@@ -2753,16 +2647,10 @@ fn foo(ar<|>g: &impl Foo) {} | |||
2753 | 0, | 2647 | 0, |
2754 | ), | 2648 | ), |
2755 | full_range: 0..12, | 2649 | full_range: 0..12, |
2756 | focus_range: Some( | 2650 | focus_range: 6..9, |
2757 | 6..9, | ||
2758 | ), | ||
2759 | name: "Foo", | 2651 | name: "Foo", |
2760 | kind: TRAIT, | 2652 | kind: Trait, |
2761 | container_name: None, | 2653 | description: "trait Foo", |
2762 | description: Some( | ||
2763 | "trait Foo", | ||
2764 | ), | ||
2765 | docs: None, | ||
2766 | }, | 2654 | }, |
2767 | }, | 2655 | }, |
2768 | ], | 2656 | ], |
@@ -2793,16 +2681,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2793 | 0, | 2681 | 0, |
2794 | ), | 2682 | ), |
2795 | full_range: 0..12, | 2683 | full_range: 0..12, |
2796 | focus_range: Some( | 2684 | focus_range: 6..9, |
2797 | 6..9, | ||
2798 | ), | ||
2799 | name: "Foo", | 2685 | name: "Foo", |
2800 | kind: TRAIT, | 2686 | kind: Trait, |
2801 | container_name: None, | 2687 | description: "trait Foo", |
2802 | description: Some( | ||
2803 | "trait Foo", | ||
2804 | ), | ||
2805 | docs: None, | ||
2806 | }, | 2688 | }, |
2807 | }, | 2689 | }, |
2808 | HoverGotoTypeData { | 2690 | HoverGotoTypeData { |
@@ -2812,16 +2694,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2812 | 0, | 2694 | 0, |
2813 | ), | 2695 | ), |
2814 | full_range: 13..28, | 2696 | full_range: 13..28, |
2815 | focus_range: Some( | 2697 | focus_range: 19..22, |
2816 | 19..22, | ||
2817 | ), | ||
2818 | name: "Bar", | 2698 | name: "Bar", |
2819 | kind: TRAIT, | 2699 | kind: Trait, |
2820 | container_name: None, | 2700 | description: "trait Bar", |
2821 | description: Some( | ||
2822 | "trait Bar", | ||
2823 | ), | ||
2824 | docs: None, | ||
2825 | }, | 2701 | }, |
2826 | }, | 2702 | }, |
2827 | HoverGotoTypeData { | 2703 | HoverGotoTypeData { |
@@ -2831,16 +2707,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2831 | 0, | 2707 | 0, |
2832 | ), | 2708 | ), |
2833 | full_range: 29..39, | 2709 | full_range: 29..39, |
2834 | focus_range: Some( | 2710 | focus_range: 36..37, |
2835 | 36..37, | ||
2836 | ), | ||
2837 | name: "S", | 2711 | name: "S", |
2838 | kind: STRUCT, | 2712 | kind: Struct, |
2839 | container_name: None, | 2713 | description: "struct S", |
2840 | description: Some( | ||
2841 | "struct S", | ||
2842 | ), | ||
2843 | docs: None, | ||
2844 | }, | 2714 | }, |
2845 | }, | 2715 | }, |
2846 | ], | 2716 | ], |
@@ -2876,16 +2746,10 @@ mod future { | |||
2876 | 0, | 2746 | 0, |
2877 | ), | 2747 | ), |
2878 | full_range: 101..163, | 2748 | full_range: 101..163, |
2879 | focus_range: Some( | 2749 | focus_range: 140..146, |
2880 | 140..146, | ||
2881 | ), | ||
2882 | name: "Future", | 2750 | name: "Future", |
2883 | kind: TRAIT, | 2751 | kind: Trait, |
2884 | container_name: None, | 2752 | description: "pub trait Future", |
2885 | description: Some( | ||
2886 | "pub trait Future", | ||
2887 | ), | ||
2888 | docs: None, | ||
2889 | }, | 2753 | }, |
2890 | }, | 2754 | }, |
2891 | HoverGotoTypeData { | 2755 | HoverGotoTypeData { |
@@ -2895,16 +2759,10 @@ mod future { | |||
2895 | 0, | 2759 | 0, |
2896 | ), | 2760 | ), |
2897 | full_range: 0..9, | 2761 | full_range: 0..9, |
2898 | focus_range: Some( | 2762 | focus_range: 7..8, |
2899 | 7..8, | ||
2900 | ), | ||
2901 | name: "S", | 2763 | name: "S", |
2902 | kind: STRUCT, | 2764 | kind: Struct, |
2903 | container_name: None, | 2765 | description: "struct S", |
2904 | description: Some( | ||
2905 | "struct S", | ||
2906 | ), | ||
2907 | docs: None, | ||
2908 | }, | 2766 | }, |
2909 | }, | 2767 | }, |
2910 | ], | 2768 | ], |
@@ -2933,16 +2791,10 @@ fn foo(ar<|>g: &impl Foo<S>) {} | |||
2933 | 0, | 2791 | 0, |
2934 | ), | 2792 | ), |
2935 | full_range: 0..15, | 2793 | full_range: 0..15, |
2936 | focus_range: Some( | 2794 | focus_range: 6..9, |
2937 | 6..9, | ||
2938 | ), | ||
2939 | name: "Foo", | 2795 | name: "Foo", |
2940 | kind: TRAIT, | 2796 | kind: Trait, |
2941 | container_name: None, | 2797 | description: "trait Foo", |
2942 | description: Some( | ||
2943 | "trait Foo", | ||
2944 | ), | ||
2945 | docs: None, | ||
2946 | }, | 2798 | }, |
2947 | }, | 2799 | }, |
2948 | HoverGotoTypeData { | 2800 | HoverGotoTypeData { |
@@ -2952,16 +2804,10 @@ fn foo(ar<|>g: &impl Foo<S>) {} | |||
2952 | 0, | 2804 | 0, |
2953 | ), | 2805 | ), |
2954 | full_range: 16..27, | 2806 | full_range: 16..27, |
2955 | focus_range: Some( | 2807 | focus_range: 23..24, |
2956 | 23..24, | ||
2957 | ), | ||
2958 | name: "S", | 2808 | name: "S", |
2959 | kind: STRUCT, | 2809 | kind: Struct, |
2960 | container_name: None, | 2810 | description: "struct S", |
2961 | description: Some( | ||
2962 | "struct S", | ||
2963 | ), | ||
2964 | docs: None, | ||
2965 | }, | 2811 | }, |
2966 | }, | 2812 | }, |
2967 | ], | 2813 | ], |
@@ -2995,16 +2841,10 @@ fn main() { let s<|>t = foo(); } | |||
2995 | 0, | 2841 | 0, |
2996 | ), | 2842 | ), |
2997 | full_range: 42..55, | 2843 | full_range: 42..55, |
2998 | focus_range: Some( | 2844 | focus_range: 49..50, |
2999 | 49..50, | ||
3000 | ), | ||
3001 | name: "B", | 2845 | name: "B", |
3002 | kind: STRUCT, | 2846 | kind: Struct, |
3003 | container_name: None, | 2847 | description: "struct B", |
3004 | description: Some( | ||
3005 | "struct B", | ||
3006 | ), | ||
3007 | docs: None, | ||
3008 | }, | 2848 | }, |
3009 | }, | 2849 | }, |
3010 | HoverGotoTypeData { | 2850 | HoverGotoTypeData { |
@@ -3014,16 +2854,10 @@ fn main() { let s<|>t = foo(); } | |||
3014 | 0, | 2854 | 0, |
3015 | ), | 2855 | ), |
3016 | full_range: 0..12, | 2856 | full_range: 0..12, |
3017 | focus_range: Some( | 2857 | focus_range: 6..9, |
3018 | 6..9, | ||
3019 | ), | ||
3020 | name: "Foo", | 2858 | name: "Foo", |
3021 | kind: TRAIT, | 2859 | kind: Trait, |
3022 | container_name: None, | 2860 | description: "trait Foo", |
3023 | description: Some( | ||
3024 | "trait Foo", | ||
3025 | ), | ||
3026 | docs: None, | ||
3027 | }, | 2861 | }, |
3028 | }, | 2862 | }, |
3029 | ], | 2863 | ], |
@@ -3051,16 +2885,10 @@ fn foo(ar<|>g: &dyn Foo) {} | |||
3051 | 0, | 2885 | 0, |
3052 | ), | 2886 | ), |
3053 | full_range: 0..12, | 2887 | full_range: 0..12, |
3054 | focus_range: Some( | 2888 | focus_range: 6..9, |
3055 | 6..9, | ||
3056 | ), | ||
3057 | name: "Foo", | 2889 | name: "Foo", |
3058 | kind: TRAIT, | 2890 | kind: Trait, |
3059 | container_name: None, | 2891 | description: "trait Foo", |
3060 | description: Some( | ||
3061 | "trait Foo", | ||
3062 | ), | ||
3063 | docs: None, | ||
3064 | }, | 2892 | }, |
3065 | }, | 2893 | }, |
3066 | ], | 2894 | ], |
@@ -3089,16 +2917,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {} | |||
3089 | 0, | 2917 | 0, |
3090 | ), | 2918 | ), |
3091 | full_range: 0..15, | 2919 | full_range: 0..15, |
3092 | focus_range: Some( | 2920 | focus_range: 6..9, |
3093 | 6..9, | ||
3094 | ), | ||
3095 | name: "Foo", | 2921 | name: "Foo", |
3096 | kind: TRAIT, | 2922 | kind: Trait, |
3097 | container_name: None, | 2923 | description: "trait Foo", |
3098 | description: Some( | ||
3099 | "trait Foo", | ||
3100 | ), | ||
3101 | docs: None, | ||
3102 | }, | 2924 | }, |
3103 | }, | 2925 | }, |
3104 | HoverGotoTypeData { | 2926 | HoverGotoTypeData { |
@@ -3108,16 +2930,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {} | |||
3108 | 0, | 2930 | 0, |
3109 | ), | 2931 | ), |
3110 | full_range: 16..27, | 2932 | full_range: 16..27, |
3111 | focus_range: Some( | 2933 | focus_range: 23..24, |
3112 | 23..24, | ||
3113 | ), | ||
3114 | name: "S", | 2934 | name: "S", |
3115 | kind: STRUCT, | 2935 | kind: Struct, |
3116 | container_name: None, | 2936 | description: "struct S", |
3117 | description: Some( | ||
3118 | "struct S", | ||
3119 | ), | ||
3120 | docs: None, | ||
3121 | }, | 2937 | }, |
3122 | }, | 2938 | }, |
3123 | ], | 2939 | ], |
@@ -3149,16 +2965,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3149 | 0, | 2965 | 0, |
3150 | ), | 2966 | ), |
3151 | full_range: 0..21, | 2967 | full_range: 0..21, |
3152 | focus_range: Some( | 2968 | focus_range: 6..15, |
3153 | 6..15, | ||
3154 | ), | ||
3155 | name: "ImplTrait", | 2969 | name: "ImplTrait", |
3156 | kind: TRAIT, | 2970 | kind: Trait, |
3157 | container_name: None, | 2971 | description: "trait ImplTrait", |
3158 | description: Some( | ||
3159 | "trait ImplTrait", | ||
3160 | ), | ||
3161 | docs: None, | ||
3162 | }, | 2972 | }, |
3163 | }, | 2973 | }, |
3164 | HoverGotoTypeData { | 2974 | HoverGotoTypeData { |
@@ -3168,16 +2978,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3168 | 0, | 2978 | 0, |
3169 | ), | 2979 | ), |
3170 | full_range: 43..57, | 2980 | full_range: 43..57, |
3171 | focus_range: Some( | 2981 | focus_range: 50..51, |
3172 | 50..51, | ||
3173 | ), | ||
3174 | name: "B", | 2982 | name: "B", |
3175 | kind: STRUCT, | 2983 | kind: Struct, |
3176 | container_name: None, | 2984 | description: "struct B", |
3177 | description: Some( | ||
3178 | "struct B", | ||
3179 | ), | ||
3180 | docs: None, | ||
3181 | }, | 2985 | }, |
3182 | }, | 2986 | }, |
3183 | HoverGotoTypeData { | 2987 | HoverGotoTypeData { |
@@ -3187,16 +2991,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3187 | 0, | 2991 | 0, |
3188 | ), | 2992 | ), |
3189 | full_range: 22..42, | 2993 | full_range: 22..42, |
3190 | focus_range: Some( | 2994 | focus_range: 28..36, |
3191 | 28..36, | ||
3192 | ), | ||
3193 | name: "DynTrait", | 2995 | name: "DynTrait", |
3194 | kind: TRAIT, | 2996 | kind: Trait, |
3195 | container_name: None, | 2997 | description: "trait DynTrait", |
3196 | description: Some( | ||
3197 | "trait DynTrait", | ||
3198 | ), | ||
3199 | docs: None, | ||
3200 | }, | 2998 | }, |
3201 | }, | 2999 | }, |
3202 | HoverGotoTypeData { | 3000 | HoverGotoTypeData { |
@@ -3206,16 +3004,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
3206 | 0, | 3004 | 0, |
3207 | ), | 3005 | ), |
3208 | full_range: 58..69, | 3006 | full_range: 58..69, |
3209 | focus_range: Some( | 3007 | focus_range: 65..66, |
3210 | 65..66, | ||
3211 | ), | ||
3212 | name: "S", | 3008 | name: "S", |
3213 | kind: STRUCT, | 3009 | kind: Struct, |
3214 | container_name: None, | 3010 | description: "struct S", |
3215 | description: Some( | ||
3216 | "struct S", | ||
3217 | ), | ||
3218 | docs: None, | ||
3219 | }, | 3011 | }, |
3220 | }, | 3012 | }, |
3221 | ], | 3013 | ], |
@@ -3254,16 +3046,10 @@ fn main() { let s<|>t = test().get(); } | |||
3254 | 0, | 3046 | 0, |
3255 | ), | 3047 | ), |
3256 | full_range: 0..62, | 3048 | full_range: 0..62, |
3257 | focus_range: Some( | 3049 | focus_range: 6..9, |
3258 | 6..9, | ||
3259 | ), | ||
3260 | name: "Foo", | 3050 | name: "Foo", |
3261 | kind: TRAIT, | 3051 | kind: Trait, |
3262 | container_name: None, | 3052 | description: "trait Foo", |
3263 | description: Some( | ||
3264 | "trait Foo", | ||
3265 | ), | ||
3266 | docs: None, | ||
3267 | }, | 3053 | }, |
3268 | }, | 3054 | }, |
3269 | ], | 3055 | ], |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index c5c652cda..dbad9a84f 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -57,14 +57,14 @@ use ide_db::{ | |||
57 | symbol_index::{self, FileSymbol}, | 57 | symbol_index::{self, FileSymbol}, |
58 | LineIndexDatabase, | 58 | LineIndexDatabase, |
59 | }; | 59 | }; |
60 | use syntax::{SourceFile, TextRange, TextSize}; | 60 | use syntax::SourceFile; |
61 | 61 | ||
62 | use crate::display::ToNav; | 62 | use crate::display::ToNav; |
63 | 63 | ||
64 | pub use crate::{ | 64 | pub use crate::{ |
65 | call_hierarchy::CallItem, | 65 | call_hierarchy::CallItem, |
66 | diagnostics::{Diagnostic, DiagnosticsConfig, Fix, Severity}, | 66 | diagnostics::{Diagnostic, DiagnosticsConfig, Fix, Severity}, |
67 | display::NavigationTarget, | 67 | display::navigation_target::{NavigationTarget, SymbolKind}, |
68 | expand_macro::ExpandedMacro, | 68 | expand_macro::ExpandedMacro, |
69 | file_structure::StructureNode, | 69 | file_structure::StructureNode, |
70 | folding_ranges::{Fold, FoldKind}, | 70 | folding_ranges::{Fold, FoldKind}, |
@@ -79,22 +79,21 @@ pub use crate::{ | |||
79 | HighlightedRange, | 79 | HighlightedRange, |
80 | }, | 80 | }, |
81 | }; | 81 | }; |
82 | pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist}; | ||
82 | pub use completion::{ | 83 | pub use completion::{ |
83 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability, | 84 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability, |
84 | CompletionScore, ImportEdit, InsertTextFormat, | 85 | CompletionScore, ImportEdit, InsertTextFormat, |
85 | }; | 86 | }; |
86 | pub use ide_db::{ | ||
87 | call_info::CallInfo, | ||
88 | search::{Reference, ReferenceAccess, ReferenceKind}, | ||
89 | }; | ||
90 | |||
91 | pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist}; | ||
92 | pub use hir::{Documentation, Semantics}; | 87 | pub use hir::{Documentation, Semantics}; |
93 | pub use ide_db::base_db::{ | 88 | pub use ide_db::base_db::{ |
94 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, | 89 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, |
95 | SourceRootId, | 90 | SourceRootId, |
96 | }; | 91 | }; |
97 | pub use ide_db::{ | 92 | pub use ide_db::{ |
93 | call_info::CallInfo, | ||
94 | search::{Reference, ReferenceAccess, ReferenceKind}, | ||
95 | }; | ||
96 | pub use ide_db::{ | ||
98 | label::Label, | 97 | label::Label, |
99 | line_index::{LineCol, LineIndex}, | 98 | line_index::{LineCol, LineIndex}, |
100 | search::SearchScope, | 99 | search::SearchScope, |
@@ -103,6 +102,7 @@ pub use ide_db::{ | |||
103 | RootDatabase, | 102 | RootDatabase, |
104 | }; | 103 | }; |
105 | pub use ssr::SsrError; | 104 | pub use ssr::SsrError; |
105 | pub use syntax::{TextRange, TextSize}; | ||
106 | pub use text_edit::{Indel, TextEdit}; | 106 | pub use text_edit::{Indel, TextEdit}; |
107 | 107 | ||
108 | pub type Cancelable<T> = Result<T, Canceled>; | 108 | pub type Cancelable<T> = Result<T, Canceled>; |
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index 6cc3b2991..be344a09b 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs | |||
@@ -78,7 +78,7 @@ mod tests { | |||
78 | ", | 78 | ", |
79 | ); | 79 | ); |
80 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | 80 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); |
81 | nav.assert_match("foo MODULE FileId(0) 0..8"); | 81 | nav.assert_match("foo Module FileId(0) 0..8"); |
82 | } | 82 | } |
83 | 83 | ||
84 | #[test] | 84 | #[test] |
@@ -97,7 +97,7 @@ mod tests { | |||
97 | ", | 97 | ", |
98 | ); | 98 | ); |
99 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | 99 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); |
100 | nav.assert_match("foo MODULE FileId(0) 0..8"); | 100 | nav.assert_match("foo Module FileId(0) 0..8"); |
101 | } | 101 | } |
102 | 102 | ||
103 | #[test] | 103 | #[test] |
@@ -113,7 +113,7 @@ mod tests { | |||
113 | ", | 113 | ", |
114 | ); | 114 | ); |
115 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | 115 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); |
116 | nav.assert_match("baz MODULE FileId(0) 32..44"); | 116 | nav.assert_match("baz Module FileId(0) 32..44"); |
117 | } | 117 | } |
118 | 118 | ||
119 | #[test] | 119 | #[test] |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 98190a86b..18ea19305 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -24,7 +24,7 @@ use syntax::{ | |||
24 | match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset, | 24 | match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; | 27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind}; |
28 | 28 | ||
29 | #[derive(Debug, Clone)] | 29 | #[derive(Debug, Clone)] |
30 | pub struct ReferenceSearchResult { | 30 | pub struct ReferenceSearchResult { |
@@ -278,7 +278,7 @@ fn try_find_self_references( | |||
278 | full_range: self_param.syntax().text_range(), | 278 | full_range: self_param.syntax().text_range(), |
279 | focus_range: Some(param_self_token.text_range()), | 279 | focus_range: Some(param_self_token.text_range()), |
280 | name: param_self_token.text().clone(), | 280 | name: param_self_token.text().clone(), |
281 | kind: param_self_token.kind(), | 281 | kind: Some(SymbolKind::SelfParam), |
282 | container_name: None, | 282 | container_name: None, |
283 | description: None, | 283 | description: None, |
284 | docs: None, | 284 | docs: None, |
@@ -343,7 +343,7 @@ fn main() { | |||
343 | } | 343 | } |
344 | "#, | 344 | "#, |
345 | expect![[r#" | 345 | expect![[r#" |
346 | Foo STRUCT FileId(0) 0..26 7..10 Other | 346 | Foo Struct FileId(0) 0..26 7..10 Other |
347 | 347 | ||
348 | FileId(0) 101..104 StructLiteral | 348 | FileId(0) 101..104 StructLiteral |
349 | "#]], | 349 | "#]], |
@@ -361,7 +361,7 @@ struct Foo<|> {} | |||
361 | } | 361 | } |
362 | "#, | 362 | "#, |
363 | expect![[r#" | 363 | expect![[r#" |
364 | Foo STRUCT FileId(0) 0..13 7..10 Other | 364 | Foo Struct FileId(0) 0..13 7..10 Other |
365 | 365 | ||
366 | FileId(0) 41..44 Other | 366 | FileId(0) 41..44 Other |
367 | FileId(0) 54..57 StructLiteral | 367 | FileId(0) 54..57 StructLiteral |
@@ -380,7 +380,7 @@ struct Foo<T> <|>{} | |||
380 | } | 380 | } |
381 | "#, | 381 | "#, |
382 | expect![[r#" | 382 | expect![[r#" |
383 | Foo STRUCT FileId(0) 0..16 7..10 Other | 383 | Foo Struct FileId(0) 0..16 7..10 Other |
384 | 384 | ||
385 | FileId(0) 64..67 StructLiteral | 385 | FileId(0) 64..67 StructLiteral |
386 | "#]], | 386 | "#]], |
@@ -399,7 +399,7 @@ fn main() { | |||
399 | } | 399 | } |
400 | "#, | 400 | "#, |
401 | expect![[r#" | 401 | expect![[r#" |
402 | Foo STRUCT FileId(0) 0..16 7..10 Other | 402 | Foo Struct FileId(0) 0..16 7..10 Other |
403 | 403 | ||
404 | FileId(0) 54..57 StructLiteral | 404 | FileId(0) 54..57 StructLiteral |
405 | "#]], | 405 | "#]], |
@@ -420,7 +420,7 @@ fn main() { | |||
420 | } | 420 | } |
421 | "#, | 421 | "#, |
422 | expect![[r#" | 422 | expect![[r#" |
423 | Foo ENUM FileId(0) 0..26 5..8 Other | 423 | Foo Enum FileId(0) 0..26 5..8 Other |
424 | 424 | ||
425 | FileId(0) 63..66 EnumLiteral | 425 | FileId(0) 63..66 EnumLiteral |
426 | "#]], | 426 | "#]], |
@@ -441,7 +441,7 @@ fn main() { | |||
441 | } | 441 | } |
442 | "#, | 442 | "#, |
443 | expect![[r#" | 443 | expect![[r#" |
444 | Foo ENUM FileId(0) 0..26 5..8 Other | 444 | Foo Enum FileId(0) 0..26 5..8 Other |
445 | 445 | ||
446 | FileId(0) 50..53 Other | 446 | FileId(0) 50..53 Other |
447 | FileId(0) 63..66 EnumLiteral | 447 | FileId(0) 63..66 EnumLiteral |
@@ -463,7 +463,7 @@ fn main() { | |||
463 | } | 463 | } |
464 | "#, | 464 | "#, |
465 | expect![[r#" | 465 | expect![[r#" |
466 | Foo ENUM FileId(0) 0..32 5..8 Other | 466 | Foo Enum FileId(0) 0..32 5..8 Other |
467 | 467 | ||
468 | FileId(0) 73..76 EnumLiteral | 468 | FileId(0) 73..76 EnumLiteral |
469 | "#]], | 469 | "#]], |
@@ -484,7 +484,7 @@ fn main() { | |||
484 | } | 484 | } |
485 | "#, | 485 | "#, |
486 | expect![[r#" | 486 | expect![[r#" |
487 | Foo ENUM FileId(0) 0..33 5..8 Other | 487 | Foo Enum FileId(0) 0..33 5..8 Other |
488 | 488 | ||
489 | FileId(0) 70..73 EnumLiteral | 489 | FileId(0) 70..73 EnumLiteral |
490 | "#]], | 490 | "#]], |
@@ -507,7 +507,7 @@ fn main() { | |||
507 | i = 5; | 507 | i = 5; |
508 | }"#, | 508 | }"#, |
509 | expect![[r#" | 509 | expect![[r#" |
510 | i IDENT_PAT FileId(0) 24..25 Other Write | 510 | i Local FileId(0) 24..25 Other Write |
511 | 511 | ||
512 | FileId(0) 50..51 Other Write | 512 | FileId(0) 50..51 Other Write |
513 | FileId(0) 54..55 Other Read | 513 | FileId(0) 54..55 Other Read |
@@ -531,7 +531,7 @@ fn bar() { | |||
531 | } | 531 | } |
532 | "#, | 532 | "#, |
533 | expect![[r#" | 533 | expect![[r#" |
534 | spam IDENT_PAT FileId(0) 19..23 Other | 534 | spam Local FileId(0) 19..23 Other |
535 | 535 | ||
536 | FileId(0) 34..38 Other Read | 536 | FileId(0) 34..38 Other Read |
537 | FileId(0) 41..45 Other Read | 537 | FileId(0) 41..45 Other Read |
@@ -546,7 +546,7 @@ fn bar() { | |||
546 | fn foo(i : u32) -> u32 { i<|> } | 546 | fn foo(i : u32) -> u32 { i<|> } |
547 | "#, | 547 | "#, |
548 | expect![[r#" | 548 | expect![[r#" |
549 | i IDENT_PAT FileId(0) 7..8 Other | 549 | i ValueParam FileId(0) 7..8 Other |
550 | 550 | ||
551 | FileId(0) 25..26 Other Read | 551 | FileId(0) 25..26 Other Read |
552 | "#]], | 552 | "#]], |
@@ -560,7 +560,7 @@ fn foo(i : u32) -> u32 { i<|> } | |||
560 | fn foo(i<|> : u32) -> u32 { i } | 560 | fn foo(i<|> : u32) -> u32 { i } |
561 | "#, | 561 | "#, |
562 | expect![[r#" | 562 | expect![[r#" |
563 | i IDENT_PAT FileId(0) 7..8 Other | 563 | i ValueParam FileId(0) 7..8 Other |
564 | 564 | ||
565 | FileId(0) 25..26 Other Read | 565 | FileId(0) 25..26 Other Read |
566 | "#]], | 566 | "#]], |
@@ -581,7 +581,7 @@ fn main(s: Foo) { | |||
581 | } | 581 | } |
582 | "#, | 582 | "#, |
583 | expect![[r#" | 583 | expect![[r#" |
584 | spam RECORD_FIELD FileId(0) 17..30 21..25 Other | 584 | spam Field FileId(0) 17..30 21..25 Other |
585 | 585 | ||
586 | FileId(0) 67..71 Other Read | 586 | FileId(0) 67..71 Other Read |
587 | "#]], | 587 | "#]], |
@@ -598,7 +598,7 @@ impl Foo { | |||
598 | } | 598 | } |
599 | "#, | 599 | "#, |
600 | expect![[r#" | 600 | expect![[r#" |
601 | f FN FileId(0) 27..43 30..31 Other | 601 | f Function FileId(0) 27..43 30..31 Other |
602 | 602 | ||
603 | "#]], | 603 | "#]], |
604 | ); | 604 | ); |
@@ -615,7 +615,7 @@ enum Foo { | |||
615 | } | 615 | } |
616 | "#, | 616 | "#, |
617 | expect![[r#" | 617 | expect![[r#" |
618 | B VARIANT FileId(0) 22..23 22..23 Other | 618 | B Variant FileId(0) 22..23 22..23 Other |
619 | 619 | ||
620 | "#]], | 620 | "#]], |
621 | ); | 621 | ); |
@@ -632,7 +632,7 @@ enum Foo { | |||
632 | } | 632 | } |
633 | "#, | 633 | "#, |
634 | expect![[r#" | 634 | expect![[r#" |
635 | field RECORD_FIELD FileId(0) 26..35 26..31 Other | 635 | field Field FileId(0) 26..35 26..31 Other |
636 | 636 | ||
637 | "#]], | 637 | "#]], |
638 | ); | 638 | ); |
@@ -673,7 +673,7 @@ fn f() { | |||
673 | } | 673 | } |
674 | "#, | 674 | "#, |
675 | expect![[r#" | 675 | expect![[r#" |
676 | Foo STRUCT FileId(1) 17..51 28..31 Other | 676 | Foo Struct FileId(1) 17..51 28..31 Other |
677 | 677 | ||
678 | FileId(0) 53..56 StructLiteral | 678 | FileId(0) 53..56 StructLiteral |
679 | FileId(2) 79..82 StructLiteral | 679 | FileId(2) 79..82 StructLiteral |
@@ -703,7 +703,7 @@ pub struct Foo { | |||
703 | } | 703 | } |
704 | "#, | 704 | "#, |
705 | expect![[r#" | 705 | expect![[r#" |
706 | foo SOURCE_FILE FileId(1) 0..35 Other | 706 | foo Module FileId(1) 0..35 Other |
707 | 707 | ||
708 | FileId(0) 14..17 Other | 708 | FileId(0) 14..17 Other |
709 | "#]], | 709 | "#]], |
@@ -731,7 +731,7 @@ pub(super) struct Foo<|> { | |||
731 | } | 731 | } |
732 | "#, | 732 | "#, |
733 | expect![[r#" | 733 | expect![[r#" |
734 | Foo STRUCT FileId(2) 0..41 18..21 Other | 734 | Foo Struct FileId(2) 0..41 18..21 Other |
735 | 735 | ||
736 | FileId(1) 20..23 Other | 736 | FileId(1) 20..23 Other |
737 | FileId(1) 47..50 StructLiteral | 737 | FileId(1) 47..50 StructLiteral |
@@ -759,7 +759,7 @@ pub(super) struct Foo<|> { | |||
759 | code, | 759 | code, |
760 | None, | 760 | None, |
761 | expect![[r#" | 761 | expect![[r#" |
762 | quux FN FileId(0) 19..35 26..30 Other | 762 | quux Function FileId(0) 19..35 26..30 Other |
763 | 763 | ||
764 | FileId(1) 16..20 StructLiteral | 764 | FileId(1) 16..20 StructLiteral |
765 | FileId(2) 16..20 StructLiteral | 765 | FileId(2) 16..20 StructLiteral |
@@ -770,7 +770,7 @@ pub(super) struct Foo<|> { | |||
770 | code, | 770 | code, |
771 | Some(SearchScope::single_file(FileId(2))), | 771 | Some(SearchScope::single_file(FileId(2))), |
772 | expect![[r#" | 772 | expect![[r#" |
773 | quux FN FileId(0) 19..35 26..30 Other | 773 | quux Function FileId(0) 19..35 26..30 Other |
774 | 774 | ||
775 | FileId(2) 16..20 StructLiteral | 775 | FileId(2) 16..20 StructLiteral |
776 | "#]], | 776 | "#]], |
@@ -790,7 +790,7 @@ fn foo() { | |||
790 | } | 790 | } |
791 | "#, | 791 | "#, |
792 | expect![[r#" | 792 | expect![[r#" |
793 | m1 MACRO_RULES FileId(0) 0..46 29..31 Other | 793 | m1 Macro FileId(0) 0..46 29..31 Other |
794 | 794 | ||
795 | FileId(0) 63..65 StructLiteral | 795 | FileId(0) 63..65 StructLiteral |
796 | FileId(0) 73..75 StructLiteral | 796 | FileId(0) 73..75 StructLiteral |
@@ -808,7 +808,7 @@ fn foo() { | |||
808 | } | 808 | } |
809 | "#, | 809 | "#, |
810 | expect![[r#" | 810 | expect![[r#" |
811 | i IDENT_PAT FileId(0) 23..24 Other Write | 811 | i Local FileId(0) 23..24 Other Write |
812 | 812 | ||
813 | FileId(0) 34..35 Other Write | 813 | FileId(0) 34..35 Other Write |
814 | FileId(0) 38..39 Other Read | 814 | FileId(0) 38..39 Other Read |
@@ -830,7 +830,7 @@ fn foo() { | |||
830 | } | 830 | } |
831 | "#, | 831 | "#, |
832 | expect![[r#" | 832 | expect![[r#" |
833 | f RECORD_FIELD FileId(0) 15..21 15..16 Other | 833 | f Field FileId(0) 15..21 15..16 Other |
834 | 834 | ||
835 | FileId(0) 55..56 RecordFieldExprOrPat Read | 835 | FileId(0) 55..56 RecordFieldExprOrPat Read |
836 | FileId(0) 68..69 Other Write | 836 | FileId(0) 68..69 Other Write |
@@ -848,7 +848,7 @@ fn foo() { | |||
848 | } | 848 | } |
849 | "#, | 849 | "#, |
850 | expect![[r#" | 850 | expect![[r#" |
851 | i IDENT_PAT FileId(0) 19..20 Other | 851 | i Local FileId(0) 19..20 Other |
852 | 852 | ||
853 | FileId(0) 26..27 Other Write | 853 | FileId(0) 26..27 Other Write |
854 | "#]], | 854 | "#]], |
@@ -872,7 +872,7 @@ fn main() { | |||
872 | } | 872 | } |
873 | "#, | 873 | "#, |
874 | expect![[r#" | 874 | expect![[r#" |
875 | new FN FileId(0) 54..81 61..64 Other | 875 | new Function FileId(0) 54..81 61..64 Other |
876 | 876 | ||
877 | FileId(0) 126..129 StructLiteral | 877 | FileId(0) 126..129 StructLiteral |
878 | "#]], | 878 | "#]], |
@@ -894,7 +894,7 @@ use crate::f; | |||
894 | fn g() { f(); } | 894 | fn g() { f(); } |
895 | "#, | 895 | "#, |
896 | expect![[r#" | 896 | expect![[r#" |
897 | f FN FileId(0) 22..31 25..26 Other | 897 | f Function FileId(0) 22..31 25..26 Other |
898 | 898 | ||
899 | FileId(1) 11..12 Other | 899 | FileId(1) 11..12 Other |
900 | FileId(1) 24..25 StructLiteral | 900 | FileId(1) 24..25 StructLiteral |
@@ -917,7 +917,7 @@ fn f(s: S) { | |||
917 | } | 917 | } |
918 | "#, | 918 | "#, |
919 | expect![[r#" | 919 | expect![[r#" |
920 | field RECORD_FIELD FileId(0) 15..24 15..20 Other | 920 | field Field FileId(0) 15..24 15..20 Other |
921 | 921 | ||
922 | FileId(0) 68..73 FieldShorthandForField Read | 922 | FileId(0) 68..73 FieldShorthandForField Read |
923 | "#]], | 923 | "#]], |
@@ -941,7 +941,7 @@ fn f(e: En) { | |||
941 | } | 941 | } |
942 | "#, | 942 | "#, |
943 | expect![[r#" | 943 | expect![[r#" |
944 | field RECORD_FIELD FileId(0) 32..41 32..37 Other | 944 | field Field FileId(0) 32..41 32..37 Other |
945 | 945 | ||
946 | FileId(0) 102..107 FieldShorthandForField Read | 946 | FileId(0) 102..107 FieldShorthandForField Read |
947 | "#]], | 947 | "#]], |
@@ -965,7 +965,7 @@ fn f() -> m::En { | |||
965 | } | 965 | } |
966 | "#, | 966 | "#, |
967 | expect![[r#" | 967 | expect![[r#" |
968 | field RECORD_FIELD FileId(0) 56..65 56..61 Other | 968 | field Field FileId(0) 56..65 56..61 Other |
969 | 969 | ||
970 | FileId(0) 125..130 RecordFieldExprOrPat Read | 970 | FileId(0) 125..130 RecordFieldExprOrPat Read |
971 | "#]], | 971 | "#]], |
@@ -990,7 +990,7 @@ impl Foo { | |||
990 | } | 990 | } |
991 | "#, | 991 | "#, |
992 | expect![[r#" | 992 | expect![[r#" |
993 | self SELF_KW FileId(0) 47..51 47..51 SelfKw Read | 993 | self SelfParam FileId(0) 47..51 47..51 SelfKw Read |
994 | 994 | ||
995 | FileId(0) 71..75 SelfKw Read | 995 | FileId(0) 71..75 SelfKw Read |
996 | FileId(0) 152..156 SelfKw Read | 996 | FileId(0) 152..156 SelfKw Read |
@@ -1038,7 +1038,7 @@ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> { | |||
1038 | } | 1038 | } |
1039 | "#, | 1039 | "#, |
1040 | expect![[r#" | 1040 | expect![[r#" |
1041 | 'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime | 1041 | 'a LifetimeParam FileId(0) 55..57 55..57 Lifetime |
1042 | 1042 | ||
1043 | FileId(0) 63..65 Lifetime | 1043 | FileId(0) 63..65 Lifetime |
1044 | FileId(0) 71..73 Lifetime | 1044 | FileId(0) 71..73 Lifetime |
@@ -1056,7 +1056,7 @@ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> { | |||
1056 | type Foo<'a, T> where T: 'a<|> = &'a T; | 1056 | type Foo<'a, T> where T: 'a<|> = &'a T; |
1057 | "#, | 1057 | "#, |
1058 | expect![[r#" | 1058 | expect![[r#" |
1059 | 'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime | 1059 | 'a LifetimeParam FileId(0) 9..11 9..11 Lifetime |
1060 | 1060 | ||
1061 | FileId(0) 25..27 Lifetime | 1061 | FileId(0) 25..27 Lifetime |
1062 | FileId(0) 31..33 Lifetime | 1062 | FileId(0) 31..33 Lifetime |
@@ -1078,7 +1078,7 @@ impl<'a> Foo<'a> for &'a () { | |||
1078 | } | 1078 | } |
1079 | "#, | 1079 | "#, |
1080 | expect![[r#" | 1080 | expect![[r#" |
1081 | 'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime | 1081 | 'a LifetimeParam FileId(0) 47..49 47..49 Lifetime |
1082 | 1082 | ||
1083 | FileId(0) 55..57 Lifetime | 1083 | FileId(0) 55..57 Lifetime |
1084 | FileId(0) 64..66 Lifetime | 1084 | FileId(0) 64..66 Lifetime |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 56e923841..cd721b7eb 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -1488,4 +1488,39 @@ impl<'yeeee> Foo<'yeeee> for &'yeeee () { | |||
1488 | "#, | 1488 | "#, |
1489 | ) | 1489 | ) |
1490 | } | 1490 | } |
1491 | |||
1492 | #[test] | ||
1493 | fn test_rename_bind_pat() { | ||
1494 | check( | ||
1495 | "new_name", | ||
1496 | r#" | ||
1497 | fn main() { | ||
1498 | enum CustomOption<T> { | ||
1499 | None, | ||
1500 | Some(T), | ||
1501 | } | ||
1502 | |||
1503 | let test_variable = CustomOption::Some(22); | ||
1504 | |||
1505 | match test_variable { | ||
1506 | CustomOption::Some(foo<|>) if foo == 11 => {} | ||
1507 | _ => (), | ||
1508 | } | ||
1509 | }"#, | ||
1510 | r#" | ||
1511 | fn main() { | ||
1512 | enum CustomOption<T> { | ||
1513 | None, | ||
1514 | Some(T), | ||
1515 | } | ||
1516 | |||
1517 | let test_variable = CustomOption::Some(22); | ||
1518 | |||
1519 | match test_variable { | ||
1520 | CustomOption::Some(new_name) if new_name == 11 => {} | ||
1521 | _ => (), | ||
1522 | } | ||
1523 | }"#, | ||
1524 | ); | ||
1525 | } | ||
1491 | } | 1526 | } |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 96462a7b0..2f2b99130 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -2,7 +2,7 @@ use std::fmt; | |||
2 | 2 | ||
3 | use assists::utils::test_related_attribute; | 3 | use assists::utils::test_related_attribute; |
4 | use cfg::CfgExpr; | 4 | use cfg::CfgExpr; |
5 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; | 5 | use hir::{AsAssocItem, HasAttrs, InFile, Semantics}; |
6 | use ide_db::RootDatabase; | 6 | use ide_db::RootDatabase; |
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use syntax::{ | 8 | use syntax::{ |
@@ -10,7 +10,10 @@ use syntax::{ | |||
10 | match_ast, SyntaxNode, | 10 | match_ast, SyntaxNode, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | use crate::{display::ToNav, FileId, NavigationTarget}; | 13 | use crate::{ |
14 | display::{ToNav, TryToNav}, | ||
15 | FileId, NavigationTarget, SymbolKind, | ||
16 | }; | ||
14 | 17 | ||
15 | #[derive(Debug, Clone)] | 18 | #[derive(Debug, Clone)] |
16 | pub struct Runnable { | 19 | pub struct Runnable { |
@@ -101,124 +104,113 @@ pub(crate) fn runnable( | |||
101 | item: SyntaxNode, | 104 | item: SyntaxNode, |
102 | file_id: FileId, | 105 | file_id: FileId, |
103 | ) -> Option<Runnable> { | 106 | ) -> Option<Runnable> { |
104 | match_ast! { | 107 | let runnable_item = match_ast! { |
105 | match item { | 108 | match (item.clone()) { |
106 | ast::Struct(it) => runnable_struct(sema, it, file_id), | ||
107 | ast::Fn(it) => runnable_fn(sema, it, file_id), | 109 | ast::Fn(it) => runnable_fn(sema, it, file_id), |
108 | ast::Module(it) => runnable_mod(sema, it, file_id), | 110 | ast::Module(it) => runnable_mod(sema, it), |
109 | _ => None, | 111 | _ => None, |
110 | } | 112 | } |
111 | } | 113 | }; |
114 | runnable_item.or_else(|| runnable_doctest(sema, item)) | ||
112 | } | 115 | } |
113 | 116 | ||
114 | fn runnable_fn( | 117 | fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> { |
115 | sema: &Semantics<RootDatabase>, | 118 | let def = sema.to_def(&func)?; |
116 | fn_def: ast::Fn, | 119 | let name_string = func.name()?.text().to_string(); |
117 | file_id: FileId, | ||
118 | ) -> Option<Runnable> { | ||
119 | let name_string = fn_def.name()?.text().to_string(); | ||
120 | 120 | ||
121 | let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &fn_def)); | ||
122 | let kind = if name_string == "main" { | 121 | let kind = if name_string == "main" { |
123 | RunnableKind::Bin | 122 | RunnableKind::Bin |
124 | } else { | 123 | } else { |
125 | let test_id = match sema.to_def(&fn_def).map(|def| def.module(sema.db)) { | 124 | let canonical_path = sema.to_def(&func).and_then(|def| { |
126 | Some(module) => { | 125 | let def: hir::ModuleDef = def.into(); |
127 | let def = sema.to_def(&fn_def)?; | 126 | def.canonical_path(sema.db) |
128 | let impl_trait_name = def.as_assoc_item(sema.db).and_then(|assoc_item| { | 127 | }); |
129 | match assoc_item.container(sema.db) { | 128 | let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string)); |
130 | hir::AssocItemContainer::Trait(trait_item) => { | 129 | |
131 | Some(trait_item.name(sema.db).to_string()) | 130 | if test_related_attribute(&func).is_some() { |
132 | } | 131 | let attr = TestAttr::from_fn(&func); |
133 | hir::AssocItemContainer::Impl(impl_def) => impl_def | ||
134 | .target_ty(sema.db) | ||
135 | .as_adt() | ||
136 | .map(|adt| adt.name(sema.db).to_string()), | ||
137 | } | ||
138 | }); | ||
139 | |||
140 | let path_iter = module | ||
141 | .path_to_root(sema.db) | ||
142 | .into_iter() | ||
143 | .rev() | ||
144 | .filter_map(|it| it.name(sema.db)) | ||
145 | .map(|name| name.to_string()); | ||
146 | |||
147 | let path = if let Some(impl_trait_name) = impl_trait_name { | ||
148 | path_iter | ||
149 | .chain(std::iter::once(impl_trait_name)) | ||
150 | .chain(std::iter::once(name_string)) | ||
151 | .join("::") | ||
152 | } else { | ||
153 | path_iter.chain(std::iter::once(name_string)).join("::") | ||
154 | }; | ||
155 | |||
156 | TestId::Path(path) | ||
157 | } | ||
158 | None => TestId::Name(name_string), | ||
159 | }; | ||
160 | |||
161 | if test_related_attribute(&fn_def).is_some() { | ||
162 | let attr = TestAttr::from_fn(&fn_def); | ||
163 | RunnableKind::Test { test_id, attr } | 132 | RunnableKind::Test { test_id, attr } |
164 | } else if fn_def.has_atom_attr("bench") { | 133 | } else if func.has_atom_attr("bench") { |
165 | RunnableKind::Bench { test_id } | 134 | RunnableKind::Bench { test_id } |
166 | } else if has_runnable_doc_test(&attrs) { | ||
167 | RunnableKind::DocTest { test_id } | ||
168 | } else { | 135 | } else { |
169 | return None; | 136 | return None; |
170 | } | 137 | } |
171 | }; | 138 | }; |
172 | 139 | ||
173 | let cfg = attrs.cfg(); | 140 | let nav = NavigationTarget::from_named( |
174 | 141 | sema.db, | |
175 | let nav = if let RunnableKind::DocTest { .. } = kind { | 142 | InFile::new(file_id.into(), &func), |
176 | NavigationTarget::from_doc_commented( | 143 | SymbolKind::Function, |
177 | sema.db, | 144 | ); |
178 | InFile::new(file_id.into(), &fn_def), | 145 | let cfg = def.attrs(sema.db).cfg(); |
179 | InFile::new(file_id.into(), &fn_def), | ||
180 | ) | ||
181 | } else { | ||
182 | NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)) | ||
183 | }; | ||
184 | Some(Runnable { nav, kind, cfg }) | 146 | Some(Runnable { nav, kind, cfg }) |
185 | } | 147 | } |
186 | 148 | ||
187 | fn runnable_struct( | 149 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
188 | sema: &Semantics<RootDatabase>, | 150 | match_ast! { |
189 | struct_def: ast::Struct, | 151 | match item { |
190 | file_id: FileId, | 152 | ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
191 | ) -> Option<Runnable> { | 153 | ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
192 | let name_string = struct_def.name()?.text().to_string(); | 154 | ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
155 | ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
156 | ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
157 | ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
158 | ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
159 | ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
160 | _ => None, | ||
161 | } | ||
162 | } | ||
163 | } | ||
193 | 164 | ||
194 | let attrs = | 165 | fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> { |
195 | Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def)); | 166 | let attrs = match def { |
167 | hir::ModuleDef::Module(it) => it.attrs(sema.db), | ||
168 | hir::ModuleDef::Function(it) => it.attrs(sema.db), | ||
169 | hir::ModuleDef::Adt(it) => it.attrs(sema.db), | ||
170 | hir::ModuleDef::Variant(it) => it.attrs(sema.db), | ||
171 | hir::ModuleDef::Const(it) => it.attrs(sema.db), | ||
172 | hir::ModuleDef::Static(it) => it.attrs(sema.db), | ||
173 | hir::ModuleDef::Trait(it) => it.attrs(sema.db), | ||
174 | hir::ModuleDef::TypeAlias(it) => it.attrs(sema.db), | ||
175 | hir::ModuleDef::BuiltinType(_) => return None, | ||
176 | }; | ||
196 | if !has_runnable_doc_test(&attrs) { | 177 | if !has_runnable_doc_test(&attrs) { |
197 | return None; | 178 | return None; |
198 | } | 179 | } |
199 | let cfg = attrs.cfg(); | 180 | let def_name = def.name(sema.db).map(|it| it.to_string()); |
200 | 181 | let test_id = def | |
201 | let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) { | 182 | .canonical_path(sema.db) |
202 | Some(module) => { | 183 | // This probably belongs to canonical path? |
203 | let path_iter = module | 184 | .map(|path| { |
204 | .path_to_root(sema.db) | 185 | let assoc_def = match def { |
205 | .into_iter() | 186 | hir::ModuleDef::Function(it) => it.as_assoc_item(sema.db), |
206 | .rev() | 187 | hir::ModuleDef::Const(it) => it.as_assoc_item(sema.db), |
207 | .filter_map(|it| it.name(sema.db)) | 188 | hir::ModuleDef::TypeAlias(it) => it.as_assoc_item(sema.db), |
208 | .map(|name| name.to_string()); | 189 | _ => None, |
209 | let path = path_iter.chain(std::iter::once(name_string)).join("::"); | 190 | }; |
210 | 191 | // FIXME: this also looks very wrong | |
211 | TestId::Path(path) | 192 | if let Some(assoc_def) = assoc_def { |
212 | } | 193 | if let hir::AssocItemContainer::Impl(imp) = assoc_def.container(sema.db) { |
213 | None => TestId::Name(name_string), | 194 | if let Some(adt) = imp.target_ty(sema.db).as_adt() { |
214 | }; | 195 | let name = adt.name(sema.db).to_string(); |
215 | 196 | let idx = path.rfind(':').unwrap_or(0); | |
216 | let nav = NavigationTarget::from_doc_commented( | 197 | let (prefix, suffix) = path.split_at(idx); |
217 | sema.db, | 198 | return format!("{}{}::{}", prefix, name, suffix); |
218 | InFile::new(file_id.into(), &struct_def), | 199 | } |
219 | InFile::new(file_id.into(), &struct_def), | 200 | } |
220 | ); | 201 | } |
221 | Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg }) | 202 | path |
203 | }) | ||
204 | .map(TestId::Path) | ||
205 | .or_else(|| def_name.clone().map(TestId::Name))?; | ||
206 | |||
207 | let mut nav = def.try_to_nav(sema.db)?; | ||
208 | nav.focus_range = None; | ||
209 | nav.description = None; | ||
210 | nav.docs = None; | ||
211 | nav.kind = None; | ||
212 | let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() }; | ||
213 | Some(res) | ||
222 | } | 214 | } |
223 | 215 | ||
224 | #[derive(Debug, Copy, Clone)] | 216 | #[derive(Debug, Copy, Clone)] |
@@ -262,11 +254,7 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool { | |||
262 | }) | 254 | }) |
263 | } | 255 | } |
264 | 256 | ||
265 | fn runnable_mod( | 257 | fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> { |
266 | sema: &Semantics<RootDatabase>, | ||
267 | module: ast::Module, | ||
268 | file_id: FileId, | ||
269 | ) -> Option<Runnable> { | ||
270 | if !has_test_function_or_multiple_test_submodules(&module) { | 258 | if !has_test_function_or_multiple_test_submodules(&module) { |
271 | return None; | 259 | return None; |
272 | } | 260 | } |
@@ -279,7 +267,8 @@ fn runnable_mod( | |||
279 | .filter_map(|it| it.name(sema.db)) | 267 | .filter_map(|it| it.name(sema.db)) |
280 | .join("::"); | 268 | .join("::"); |
281 | 269 | ||
282 | let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &module)); | 270 | let def = sema.to_def(&module)?; |
271 | let attrs = def.attrs(sema.db); | ||
283 | let cfg = attrs.cfg(); | 272 | let cfg = attrs.cfg(); |
284 | let nav = module_def.to_nav(sema.db); | 273 | let nav = module_def.to_nav(sema.db); |
285 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | 274 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) |
@@ -319,7 +308,7 @@ mod tests { | |||
319 | 308 | ||
320 | use crate::fixture; | 309 | use crate::fixture; |
321 | 310 | ||
322 | use super::{RunnableAction, BENCH, BIN, DOCTEST, TEST}; | 311 | use super::*; |
323 | 312 | ||
324 | fn check( | 313 | fn check( |
325 | ra_fixture: &str, | 314 | ra_fixture: &str, |
@@ -363,14 +352,9 @@ fn bench() {} | |||
363 | 0, | 352 | 0, |
364 | ), | 353 | ), |
365 | full_range: 1..13, | 354 | full_range: 1..13, |
366 | focus_range: Some( | 355 | focus_range: 4..8, |
367 | 4..8, | ||
368 | ), | ||
369 | name: "main", | 356 | name: "main", |
370 | kind: FN, | 357 | kind: Function, |
371 | container_name: None, | ||
372 | description: None, | ||
373 | docs: None, | ||
374 | }, | 358 | }, |
375 | kind: Bin, | 359 | kind: Bin, |
376 | cfg: None, | 360 | cfg: None, |
@@ -381,14 +365,9 @@ fn bench() {} | |||
381 | 0, | 365 | 0, |
382 | ), | 366 | ), |
383 | full_range: 15..39, | 367 | full_range: 15..39, |
384 | focus_range: Some( | 368 | focus_range: 26..34, |
385 | 26..34, | ||
386 | ), | ||
387 | name: "test_foo", | 369 | name: "test_foo", |
388 | kind: FN, | 370 | kind: Function, |
389 | container_name: None, | ||
390 | description: None, | ||
391 | docs: None, | ||
392 | }, | 371 | }, |
393 | kind: Test { | 372 | kind: Test { |
394 | test_id: Path( | 373 | test_id: Path( |
@@ -406,14 +385,9 @@ fn bench() {} | |||
406 | 0, | 385 | 0, |
407 | ), | 386 | ), |
408 | full_range: 41..75, | 387 | full_range: 41..75, |
409 | focus_range: Some( | 388 | focus_range: 62..70, |
410 | 62..70, | ||
411 | ), | ||
412 | name: "test_foo", | 389 | name: "test_foo", |
413 | kind: FN, | 390 | kind: Function, |
414 | container_name: None, | ||
415 | description: None, | ||
416 | docs: None, | ||
417 | }, | 391 | }, |
418 | kind: Test { | 392 | kind: Test { |
419 | test_id: Path( | 393 | test_id: Path( |
@@ -431,14 +405,9 @@ fn bench() {} | |||
431 | 0, | 405 | 0, |
432 | ), | 406 | ), |
433 | full_range: 77..99, | 407 | full_range: 77..99, |
434 | focus_range: Some( | 408 | focus_range: 89..94, |
435 | 89..94, | ||
436 | ), | ||
437 | name: "bench", | 409 | name: "bench", |
438 | kind: FN, | 410 | kind: Function, |
439 | container_name: None, | ||
440 | description: None, | ||
441 | docs: None, | ||
442 | }, | 411 | }, |
443 | kind: Bench { | 412 | kind: Bench { |
444 | test_id: Path( | 413 | test_id: Path( |
@@ -528,14 +497,9 @@ struct StructWithRunnable(String); | |||
528 | 0, | 497 | 0, |
529 | ), | 498 | ), |
530 | full_range: 1..13, | 499 | full_range: 1..13, |
531 | focus_range: Some( | 500 | focus_range: 4..8, |
532 | 4..8, | ||
533 | ), | ||
534 | name: "main", | 501 | name: "main", |
535 | kind: FN, | 502 | kind: Function, |
536 | container_name: None, | ||
537 | description: None, | ||
538 | docs: None, | ||
539 | }, | 503 | }, |
540 | kind: Bin, | 504 | kind: Bin, |
541 | cfg: None, | 505 | cfg: None, |
@@ -546,12 +510,7 @@ struct StructWithRunnable(String); | |||
546 | 0, | 510 | 0, |
547 | ), | 511 | ), |
548 | full_range: 15..74, | 512 | full_range: 15..74, |
549 | focus_range: None, | ||
550 | name: "should_have_runnable", | 513 | name: "should_have_runnable", |
551 | kind: FN, | ||
552 | container_name: None, | ||
553 | description: None, | ||
554 | docs: None, | ||
555 | }, | 514 | }, |
556 | kind: DocTest { | 515 | kind: DocTest { |
557 | test_id: Path( | 516 | test_id: Path( |
@@ -566,12 +525,7 @@ struct StructWithRunnable(String); | |||
566 | 0, | 525 | 0, |
567 | ), | 526 | ), |
568 | full_range: 76..148, | 527 | full_range: 76..148, |
569 | focus_range: None, | ||
570 | name: "should_have_runnable_1", | 528 | name: "should_have_runnable_1", |
571 | kind: FN, | ||
572 | container_name: None, | ||
573 | description: None, | ||
574 | docs: None, | ||
575 | }, | 529 | }, |
576 | kind: DocTest { | 530 | kind: DocTest { |
577 | test_id: Path( | 531 | test_id: Path( |
@@ -586,12 +540,7 @@ struct StructWithRunnable(String); | |||
586 | 0, | 540 | 0, |
587 | ), | 541 | ), |
588 | full_range: 150..254, | 542 | full_range: 150..254, |
589 | focus_range: None, | ||
590 | name: "should_have_runnable_2", | 543 | name: "should_have_runnable_2", |
591 | kind: FN, | ||
592 | container_name: None, | ||
593 | description: None, | ||
594 | docs: None, | ||
595 | }, | 544 | }, |
596 | kind: DocTest { | 545 | kind: DocTest { |
597 | test_id: Path( | 546 | test_id: Path( |
@@ -606,12 +555,7 @@ struct StructWithRunnable(String); | |||
606 | 0, | 555 | 0, |
607 | ), | 556 | ), |
608 | full_range: 756..821, | 557 | full_range: 756..821, |
609 | focus_range: None, | ||
610 | name: "StructWithRunnable", | 558 | name: "StructWithRunnable", |
611 | kind: STRUCT, | ||
612 | container_name: None, | ||
613 | description: None, | ||
614 | docs: None, | ||
615 | }, | 559 | }, |
616 | kind: DocTest { | 560 | kind: DocTest { |
617 | test_id: Path( | 561 | test_id: Path( |
@@ -650,14 +594,9 @@ impl Data { | |||
650 | 0, | 594 | 0, |
651 | ), | 595 | ), |
652 | full_range: 1..13, | 596 | full_range: 1..13, |
653 | focus_range: Some( | 597 | focus_range: 4..8, |
654 | 4..8, | ||
655 | ), | ||
656 | name: "main", | 598 | name: "main", |
657 | kind: FN, | 599 | kind: Function, |
658 | container_name: None, | ||
659 | description: None, | ||
660 | docs: None, | ||
661 | }, | 600 | }, |
662 | kind: Bin, | 601 | kind: Bin, |
663 | cfg: None, | 602 | cfg: None, |
@@ -668,12 +607,7 @@ impl Data { | |||
668 | 0, | 607 | 0, |
669 | ), | 608 | ), |
670 | full_range: 44..98, | 609 | full_range: 44..98, |
671 | focus_range: None, | ||
672 | name: "foo", | 610 | name: "foo", |
673 | kind: FN, | ||
674 | container_name: None, | ||
675 | description: None, | ||
676 | docs: None, | ||
677 | }, | 611 | }, |
678 | kind: DocTest { | 612 | kind: DocTest { |
679 | test_id: Path( | 613 | test_id: Path( |
@@ -707,14 +641,9 @@ mod test_mod { | |||
707 | 0, | 641 | 0, |
708 | ), | 642 | ), |
709 | full_range: 1..51, | 643 | full_range: 1..51, |
710 | focus_range: Some( | 644 | focus_range: 5..13, |
711 | 5..13, | ||
712 | ), | ||
713 | name: "test_mod", | 645 | name: "test_mod", |
714 | kind: MODULE, | 646 | kind: Module, |
715 | container_name: None, | ||
716 | description: None, | ||
717 | docs: None, | ||
718 | }, | 647 | }, |
719 | kind: TestMod { | 648 | kind: TestMod { |
720 | path: "test_mod", | 649 | path: "test_mod", |
@@ -727,14 +656,9 @@ mod test_mod { | |||
727 | 0, | 656 | 0, |
728 | ), | 657 | ), |
729 | full_range: 20..49, | 658 | full_range: 20..49, |
730 | focus_range: Some( | 659 | focus_range: 35..44, |
731 | 35..44, | ||
732 | ), | ||
733 | name: "test_foo1", | 660 | name: "test_foo1", |
734 | kind: FN, | 661 | kind: Function, |
735 | container_name: None, | ||
736 | description: None, | ||
737 | docs: None, | ||
738 | }, | 662 | }, |
739 | kind: Test { | 663 | kind: Test { |
740 | test_id: Path( | 664 | test_id: Path( |
@@ -787,14 +711,9 @@ mod root_tests { | |||
787 | 0, | 711 | 0, |
788 | ), | 712 | ), |
789 | full_range: 22..323, | 713 | full_range: 22..323, |
790 | focus_range: Some( | 714 | focus_range: 26..40, |
791 | 26..40, | ||
792 | ), | ||
793 | name: "nested_tests_0", | 715 | name: "nested_tests_0", |
794 | kind: MODULE, | 716 | kind: Module, |
795 | container_name: None, | ||
796 | description: None, | ||
797 | docs: None, | ||
798 | }, | 717 | }, |
799 | kind: TestMod { | 718 | kind: TestMod { |
800 | path: "root_tests::nested_tests_0", | 719 | path: "root_tests::nested_tests_0", |
@@ -807,14 +726,9 @@ mod root_tests { | |||
807 | 0, | 726 | 0, |
808 | ), | 727 | ), |
809 | full_range: 51..192, | 728 | full_range: 51..192, |
810 | focus_range: Some( | 729 | focus_range: 55..69, |
811 | 55..69, | ||
812 | ), | ||
813 | name: "nested_tests_1", | 730 | name: "nested_tests_1", |
814 | kind: MODULE, | 731 | kind: Module, |
815 | container_name: None, | ||
816 | description: None, | ||
817 | docs: None, | ||
818 | }, | 732 | }, |
819 | kind: TestMod { | 733 | kind: TestMod { |
820 | path: "root_tests::nested_tests_0::nested_tests_1", | 734 | path: "root_tests::nested_tests_0::nested_tests_1", |
@@ -827,14 +741,9 @@ mod root_tests { | |||
827 | 0, | 741 | 0, |
828 | ), | 742 | ), |
829 | full_range: 84..126, | 743 | full_range: 84..126, |
830 | focus_range: Some( | 744 | focus_range: 107..121, |
831 | 107..121, | ||
832 | ), | ||
833 | name: "nested_test_11", | 745 | name: "nested_test_11", |
834 | kind: FN, | 746 | kind: Function, |
835 | container_name: None, | ||
836 | description: None, | ||
837 | docs: None, | ||
838 | }, | 747 | }, |
839 | kind: Test { | 748 | kind: Test { |
840 | test_id: Path( | 749 | test_id: Path( |
@@ -852,14 +761,9 @@ mod root_tests { | |||
852 | 0, | 761 | 0, |
853 | ), | 762 | ), |
854 | full_range: 140..182, | 763 | full_range: 140..182, |
855 | focus_range: Some( | 764 | focus_range: 163..177, |
856 | 163..177, | ||
857 | ), | ||
858 | name: "nested_test_12", | 765 | name: "nested_test_12", |
859 | kind: FN, | 766 | kind: Function, |
860 | container_name: None, | ||
861 | description: None, | ||
862 | docs: None, | ||
863 | }, | 767 | }, |
864 | kind: Test { | 768 | kind: Test { |
865 | test_id: Path( | 769 | test_id: Path( |
@@ -877,14 +781,9 @@ mod root_tests { | |||
877 | 0, | 781 | 0, |
878 | ), | 782 | ), |
879 | full_range: 202..286, | 783 | full_range: 202..286, |
880 | focus_range: Some( | 784 | focus_range: 206..220, |
881 | 206..220, | ||
882 | ), | ||
883 | name: "nested_tests_2", | 785 | name: "nested_tests_2", |
884 | kind: MODULE, | 786 | kind: Module, |
885 | container_name: None, | ||
886 | description: None, | ||
887 | docs: None, | ||
888 | }, | 787 | }, |
889 | kind: TestMod { | 788 | kind: TestMod { |
890 | path: "root_tests::nested_tests_0::nested_tests_2", | 789 | path: "root_tests::nested_tests_0::nested_tests_2", |
@@ -897,14 +796,9 @@ mod root_tests { | |||
897 | 0, | 796 | 0, |
898 | ), | 797 | ), |
899 | full_range: 235..276, | 798 | full_range: 235..276, |
900 | focus_range: Some( | 799 | focus_range: 258..271, |
901 | 258..271, | ||
902 | ), | ||
903 | name: "nested_test_2", | 800 | name: "nested_test_2", |
904 | kind: FN, | 801 | kind: Function, |
905 | container_name: None, | ||
906 | description: None, | ||
907 | docs: None, | ||
908 | }, | 802 | }, |
909 | kind: Test { | 803 | kind: Test { |
910 | test_id: Path( | 804 | test_id: Path( |
@@ -940,14 +834,9 @@ fn test_foo1() {} | |||
940 | 0, | 834 | 0, |
941 | ), | 835 | ), |
942 | full_range: 1..50, | 836 | full_range: 1..50, |
943 | focus_range: Some( | 837 | focus_range: 36..45, |
944 | 36..45, | ||
945 | ), | ||
946 | name: "test_foo1", | 838 | name: "test_foo1", |
947 | kind: FN, | 839 | kind: Function, |
948 | container_name: None, | ||
949 | description: None, | ||
950 | docs: None, | ||
951 | }, | 840 | }, |
952 | kind: Test { | 841 | kind: Test { |
953 | test_id: Path( | 842 | test_id: Path( |
@@ -990,14 +879,9 @@ fn test_foo1() {} | |||
990 | 0, | 879 | 0, |
991 | ), | 880 | ), |
992 | full_range: 1..72, | 881 | full_range: 1..72, |
993 | focus_range: Some( | 882 | focus_range: 58..67, |
994 | 58..67, | ||
995 | ), | ||
996 | name: "test_foo1", | 883 | name: "test_foo1", |
997 | kind: FN, | 884 | kind: Function, |
998 | container_name: None, | ||
999 | description: None, | ||
1000 | docs: None, | ||
1001 | }, | 885 | }, |
1002 | kind: Test { | 886 | kind: Test { |
1003 | test_id: Path( | 887 | test_id: Path( |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 488969f1a..00c717c7c 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | syntax_highlighting::{ | 23 | syntax_highlighting::{ |
24 | format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, | 24 | format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, |
25 | }, | 25 | }, |
26 | FileId, HighlightModifier, HighlightTag, | 26 | FileId, HighlightModifier, HighlightTag, SymbolKind, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | pub(crate) use html::highlight_as_html; | 29 | pub(crate) use html::highlight_as_html; |
@@ -103,7 +103,7 @@ pub(crate) fn highlight( | |||
103 | if let Some(range) = macro_call_range(&mc) { | 103 | if let Some(range) = macro_call_range(&mc) { |
104 | stack.add(HighlightedRange { | 104 | stack.add(HighlightedRange { |
105 | range, | 105 | range, |
106 | highlight: HighlightTag::Macro.into(), | 106 | highlight: HighlightTag::Symbol(SymbolKind::Macro).into(), |
107 | binding_hash: None, | 107 | binding_hash: None, |
108 | }); | 108 | }); |
109 | } | 109 | } |
@@ -470,13 +470,13 @@ fn highlight_element( | |||
470 | }; | 470 | }; |
471 | 471 | ||
472 | match name_kind { | 472 | match name_kind { |
473 | Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(), | 473 | Some(NameClass::ExternCrate(_)) => HighlightTag::Symbol(SymbolKind::Module).into(), |
474 | Some(NameClass::Definition(def)) => { | 474 | Some(NameClass::Definition(def)) => { |
475 | highlight_def(db, def) | HighlightModifier::Definition | 475 | highlight_def(db, def) | HighlightModifier::Definition |
476 | } | 476 | } |
477 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), | 477 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), |
478 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { | 478 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { |
479 | let mut h = HighlightTag::Field.into(); | 479 | let mut h = HighlightTag::Symbol(SymbolKind::Field).into(); |
480 | if let Definition::Field(field) = field_ref { | 480 | if let Definition::Field(field) = field_ref { |
481 | if let VariantDef::Union(_) = field.parent_def(db) { | 481 | if let VariantDef::Union(_) = field.parent_def(db) { |
482 | h |= HighlightModifier::Unsafe; | 482 | h |= HighlightModifier::Unsafe; |
@@ -493,14 +493,16 @@ fn highlight_element( | |||
493 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { | 493 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { |
494 | // even though we track whether we are in an attribute or not we still need this special case | 494 | // even though we track whether we are in an attribute or not we still need this special case |
495 | // as otherwise we would emit unresolved references for name refs inside attributes | 495 | // as otherwise we would emit unresolved references for name refs inside attributes |
496 | Highlight::from(HighlightTag::Function) | 496 | Highlight::from(HighlightTag::Symbol(SymbolKind::Function)) |
497 | } | 497 | } |
498 | NAME_REF => { | 498 | NAME_REF => { |
499 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 499 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
500 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | 500 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { |
501 | match NameRefClass::classify(sema, &name_ref) { | 501 | match NameRefClass::classify(sema, &name_ref) { |
502 | Some(name_kind) => match name_kind { | 502 | Some(name_kind) => match name_kind { |
503 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), | 503 | NameRefClass::ExternCrate(_) => { |
504 | HighlightTag::Symbol(SymbolKind::Module).into() | ||
505 | } | ||
504 | NameRefClass::Definition(def) => { | 506 | NameRefClass::Definition(def) => { |
505 | if let Definition::Local(local) = &def { | 507 | if let Definition::Local(local) = &def { |
506 | if let Some(name) = local.name(db) { | 508 | if let Some(name) = local.name(db) { |
@@ -530,7 +532,9 @@ fn highlight_element( | |||
530 | 532 | ||
531 | h | 533 | h |
532 | } | 534 | } |
533 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | 535 | NameRefClass::FieldShorthand { .. } => { |
536 | HighlightTag::Symbol(SymbolKind::Field).into() | ||
537 | } | ||
534 | }, | 538 | }, |
535 | None if syntactic_name_ref_highlighting => { | 539 | None if syntactic_name_ref_highlighting => { |
536 | highlight_name_ref_by_syntax(name_ref, sema) | 540 | highlight_name_ref_by_syntax(name_ref, sema) |
@@ -556,7 +560,7 @@ fn highlight_element( | |||
556 | CHAR => HighlightTag::CharLiteral.into(), | 560 | CHAR => HighlightTag::CharLiteral.into(), |
557 | QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow, | 561 | QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow, |
558 | LIFETIME => { | 562 | LIFETIME => { |
559 | let h = Highlight::new(HighlightTag::Lifetime); | 563 | let h = Highlight::new(HighlightTag::Symbol(SymbolKind::LifetimeParam)); |
560 | match element.parent().map(|it| it.kind()) { | 564 | match element.parent().map(|it| it.kind()) { |
561 | Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, | 565 | Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, |
562 | _ => h, | 566 | _ => h, |
@@ -580,7 +584,7 @@ fn highlight_element( | |||
580 | HighlightTag::Operator.into() | 584 | HighlightTag::Operator.into() |
581 | } | 585 | } |
582 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | 586 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { |
583 | HighlightTag::Macro.into() | 587 | HighlightTag::Symbol(SymbolKind::Macro).into() |
584 | } | 588 | } |
585 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | 589 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { |
586 | HighlightTag::BuiltinType.into() | 590 | HighlightTag::BuiltinType.into() |
@@ -659,7 +663,7 @@ fn highlight_element( | |||
659 | .and_then(SyntaxNode::parent) | 663 | .and_then(SyntaxNode::parent) |
660 | .and_then(ast::Path::cast) | 664 | .and_then(ast::Path::cast) |
661 | .and_then(|p| sema.resolve_path(&p)); | 665 | .and_then(|p| sema.resolve_path(&p)); |
662 | let mut h = HighlightTag::SelfKeyword.into(); | 666 | let mut h = HighlightTag::Symbol(SymbolKind::SelfParam).into(); |
663 | if self_param_is_mut | 667 | if self_param_is_mut |
664 | || matches!(self_path, | 668 | || matches!(self_path, |
665 | Some(hir::PathResolution::Local(local)) | 669 | Some(hir::PathResolution::Local(local)) |
@@ -732,7 +736,8 @@ fn highlight_method_call( | |||
732 | method_call: &ast::MethodCallExpr, | 736 | method_call: &ast::MethodCallExpr, |
733 | ) -> Option<Highlight> { | 737 | ) -> Option<Highlight> { |
734 | let func = sema.resolve_method_call(&method_call)?; | 738 | let func = sema.resolve_method_call(&method_call)?; |
735 | let mut h = HighlightTag::Method.into(); | 739 | let mut h = HighlightTag::Symbol(SymbolKind::Function).into(); |
740 | h |= HighlightModifier::Associated; | ||
736 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | 741 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { |
737 | h |= HighlightModifier::Unsafe; | 742 | h |= HighlightModifier::Unsafe; |
738 | } | 743 | } |
@@ -756,35 +761,45 @@ fn highlight_method_call( | |||
756 | 761 | ||
757 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | 762 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { |
758 | match def { | 763 | match def { |
759 | Definition::Macro(_) => HighlightTag::Macro, | 764 | Definition::Macro(_) => HighlightTag::Symbol(SymbolKind::Macro), |
760 | Definition::Field(_) => HighlightTag::Field, | 765 | Definition::Field(_) => HighlightTag::Symbol(SymbolKind::Field), |
761 | Definition::ModuleDef(def) => match def { | 766 | Definition::ModuleDef(def) => match def { |
762 | hir::ModuleDef::Module(_) => HighlightTag::Module, | 767 | hir::ModuleDef::Module(_) => HighlightTag::Symbol(SymbolKind::Module), |
763 | hir::ModuleDef::Function(func) => { | 768 | hir::ModuleDef::Function(func) => { |
764 | let mut h = if func.as_assoc_item(db).is_some() { | 769 | let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Function)); |
770 | if func.as_assoc_item(db).is_some() { | ||
771 | h |= HighlightModifier::Associated; | ||
765 | if func.self_param(db).is_none() { | 772 | if func.self_param(db).is_none() { |
766 | Highlight::from(HighlightTag::Method) | HighlightModifier::Static | 773 | h |= HighlightModifier::Static |
767 | } else { | ||
768 | HighlightTag::Method.into() | ||
769 | } | 774 | } |
770 | } else { | 775 | } |
771 | HighlightTag::Function.into() | ||
772 | }; | ||
773 | if func.is_unsafe(db) { | 776 | if func.is_unsafe(db) { |
774 | h |= HighlightModifier::Unsafe; | 777 | h |= HighlightModifier::Unsafe; |
775 | } | 778 | } |
776 | return h; | 779 | return h; |
777 | } | 780 | } |
778 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, | 781 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct), |
779 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, | 782 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum), |
780 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, | 783 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union), |
781 | hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant, | 784 | hir::ModuleDef::Variant(_) => HighlightTag::Symbol(SymbolKind::Variant), |
782 | hir::ModuleDef::Const(_) => HighlightTag::Constant, | 785 | hir::ModuleDef::Const(konst) => { |
783 | hir::ModuleDef::Trait(_) => HighlightTag::Trait, | 786 | let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const)); |
784 | hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, | 787 | if konst.as_assoc_item(db).is_some() { |
788 | h |= HighlightModifier::Associated | ||
789 | } | ||
790 | return h; | ||
791 | } | ||
792 | hir::ModuleDef::Trait(_) => HighlightTag::Symbol(SymbolKind::Trait), | ||
793 | hir::ModuleDef::TypeAlias(type_) => { | ||
794 | let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::TypeAlias)); | ||
795 | if type_.as_assoc_item(db).is_some() { | ||
796 | h |= HighlightModifier::Associated | ||
797 | } | ||
798 | return h; | ||
799 | } | ||
785 | hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, | 800 | hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, |
786 | hir::ModuleDef::Static(s) => { | 801 | hir::ModuleDef::Static(s) => { |
787 | let mut h = Highlight::new(HighlightTag::Static); | 802 | let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Static)); |
788 | if s.is_mut(db) { | 803 | if s.is_mut(db) { |
789 | h |= HighlightModifier::Mutable; | 804 | h |= HighlightModifier::Mutable; |
790 | h |= HighlightModifier::Unsafe; | 805 | h |= HighlightModifier::Unsafe; |
@@ -792,11 +807,14 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
792 | return h; | 807 | return h; |
793 | } | 808 | } |
794 | }, | 809 | }, |
795 | Definition::SelfType(_) => HighlightTag::SelfType, | 810 | Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl), |
796 | Definition::TypeParam(_) => HighlightTag::TypeParam, | 811 | Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam), |
797 | Definition::Local(local) => { | 812 | Definition::Local(local) => { |
798 | let tag = | 813 | let tag = if local.is_param(db) { |
799 | if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local }; | 814 | HighlightTag::Symbol(SymbolKind::ValueParam) |
815 | } else { | ||
816 | HighlightTag::Symbol(SymbolKind::Local) | ||
817 | }; | ||
800 | let mut h = Highlight::new(tag); | 818 | let mut h = Highlight::new(tag); |
801 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { | 819 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { |
802 | h |= HighlightModifier::Mutable; | 820 | h |= HighlightModifier::Mutable; |
@@ -806,7 +824,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
806 | } | 824 | } |
807 | return h; | 825 | return h; |
808 | } | 826 | } |
809 | Definition::LifetimeParam(_) => HighlightTag::Lifetime, | 827 | Definition::LifetimeParam(_) => HighlightTag::Symbol(SymbolKind::LifetimeParam), |
810 | } | 828 | } |
811 | .into() | 829 | .into() |
812 | } | 830 | } |
@@ -820,19 +838,19 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
820 | }; | 838 | }; |
821 | 839 | ||
822 | let tag = match parent.kind() { | 840 | let tag = match parent.kind() { |
823 | STRUCT => HighlightTag::Struct, | 841 | STRUCT => HighlightTag::Symbol(SymbolKind::Struct), |
824 | ENUM => HighlightTag::Enum, | 842 | ENUM => HighlightTag::Symbol(SymbolKind::Enum), |
825 | UNION => HighlightTag::Union, | 843 | VARIANT => HighlightTag::Symbol(SymbolKind::Variant), |
826 | TRAIT => HighlightTag::Trait, | 844 | UNION => HighlightTag::Symbol(SymbolKind::Union), |
827 | TYPE_ALIAS => HighlightTag::TypeAlias, | 845 | TRAIT => HighlightTag::Symbol(SymbolKind::Trait), |
828 | TYPE_PARAM => HighlightTag::TypeParam, | 846 | TYPE_ALIAS => HighlightTag::Symbol(SymbolKind::TypeAlias), |
829 | RECORD_FIELD => HighlightTag::Field, | 847 | TYPE_PARAM => HighlightTag::Symbol(SymbolKind::TypeParam), |
830 | MODULE => HighlightTag::Module, | 848 | RECORD_FIELD => HighlightTag::Symbol(SymbolKind::Field), |
831 | FN => HighlightTag::Function, | 849 | MODULE => HighlightTag::Symbol(SymbolKind::Module), |
832 | CONST => HighlightTag::Constant, | 850 | FN => HighlightTag::Symbol(SymbolKind::Function), |
833 | STATIC => HighlightTag::Static, | 851 | CONST => HighlightTag::Symbol(SymbolKind::Const), |
834 | VARIANT => HighlightTag::EnumVariant, | 852 | STATIC => HighlightTag::Symbol(SymbolKind::Static), |
835 | IDENT_PAT => HighlightTag::Local, | 853 | IDENT_PAT => HighlightTag::Symbol(SymbolKind::Local), |
836 | _ => default, | 854 | _ => default, |
837 | }; | 855 | }; |
838 | 856 | ||
@@ -851,10 +869,10 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
851 | METHOD_CALL_EXPR => { | 869 | METHOD_CALL_EXPR => { |
852 | return ast::MethodCallExpr::cast(parent) | 870 | return ast::MethodCallExpr::cast(parent) |
853 | .and_then(|method_call| highlight_method_call(sema, &method_call)) | 871 | .and_then(|method_call| highlight_method_call(sema, &method_call)) |
854 | .unwrap_or_else(|| HighlightTag::Function.into()); | 872 | .unwrap_or_else(|| HighlightTag::Symbol(SymbolKind::Function).into()); |
855 | } | 873 | } |
856 | FIELD_EXPR => { | 874 | FIELD_EXPR => { |
857 | let h = HighlightTag::Field; | 875 | let h = HighlightTag::Symbol(SymbolKind::Field); |
858 | let is_union = ast::FieldExpr::cast(parent) | 876 | let is_union = ast::FieldExpr::cast(parent) |
859 | .and_then(|field_expr| { | 877 | .and_then(|field_expr| { |
860 | let field = sema.resolve_field(&field_expr)?; | 878 | let field = sema.resolve_field(&field_expr)?; |
@@ -881,9 +899,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
881 | _ => { | 899 | _ => { |
882 | // within path, decide whether it is module or adt by checking for uppercase name | 900 | // within path, decide whether it is module or adt by checking for uppercase name |
883 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { | 901 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { |
884 | HighlightTag::Struct | 902 | HighlightTag::Symbol(SymbolKind::Struct) |
885 | } else { | 903 | } else { |
886 | HighlightTag::Module | 904 | HighlightTag::Symbol(SymbolKind::Module) |
887 | } | 905 | } |
888 | .into(); | 906 | .into(); |
889 | } | 907 | } |
@@ -894,11 +912,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
894 | }; | 912 | }; |
895 | 913 | ||
896 | match parent.kind() { | 914 | match parent.kind() { |
897 | CALL_EXPR => HighlightTag::Function.into(), | 915 | CALL_EXPR => HighlightTag::Symbol(SymbolKind::Function).into(), |
898 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { | 916 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { |
899 | HighlightTag::Struct.into() | 917 | HighlightTag::Symbol(SymbolKind::Struct) |
900 | } else { | 918 | } else { |
901 | HighlightTag::Constant | 919 | HighlightTag::Symbol(SymbolKind::Const) |
902 | } | 920 | } |
903 | .into(), | 921 | .into(), |
904 | } | 922 | } |
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs index 42f27df5d..26416022b 100644 --- a/crates/ide/src/syntax_highlighting/format.rs +++ b/crates/ide/src/syntax_highlighting/format.rs | |||
@@ -4,7 +4,9 @@ use syntax::{ | |||
4 | AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, | 4 | AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use crate::{syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange}; | 7 | use crate::{ |
8 | syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange, SymbolKind, | ||
9 | }; | ||
8 | 10 | ||
9 | #[derive(Default)] | 11 | #[derive(Default)] |
10 | pub(super) struct FormatStringHighlighter { | 12 | pub(super) struct FormatStringHighlighter { |
@@ -71,6 +73,6 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HighlightTag> { | |||
71 | | FormatSpecifier::Asterisk | 73 | | FormatSpecifier::Asterisk |
72 | | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier, | 74 | | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier, |
73 | FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral, | 75 | FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral, |
74 | FormatSpecifier::Identifier => HighlightTag::Local, | 76 | FormatSpecifier::Identifier => HighlightTag::Symbol(SymbolKind::Local), |
75 | }) | 77 | }) |
76 | } | 78 | } |
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs index e97d1be1a..9eb184c74 100644 --- a/crates/ide/src/syntax_highlighting/injection.rs +++ b/crates/ide/src/syntax_highlighting/injection.rs | |||
@@ -179,6 +179,5 @@ pub(super) fn highlight_doc_comment( | |||
179 | stack.add(comment); | 179 | stack.add(comment); |
180 | } | 180 | } |
181 | stack.pop_and_inject(None); | 181 | stack.pop_and_inject(None); |
182 | stack | 182 | stack.pop_and_inject(Some(Highlight::from(HighlightTag::Dummy) | HighlightModifier::Injected)); |
183 | .pop_and_inject(Some(Highlight::from(HighlightTag::Generic) | HighlightModifier::Injected)); | ||
184 | } | 183 | } |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index ffd9588b8..974f54fa0 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | use std::{fmt, ops}; | 4 | use std::{fmt, ops}; |
5 | 5 | ||
6 | use crate::SymbolKind; | ||
7 | |||
6 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 8 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
7 | pub struct Highlight { | 9 | pub struct Highlight { |
8 | pub tag: HighlightTag, | 10 | pub tag: HighlightTag, |
@@ -14,40 +16,25 @@ pub struct HighlightModifiers(u32); | |||
14 | 16 | ||
15 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 17 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
16 | pub enum HighlightTag { | 18 | pub enum HighlightTag { |
17 | Attribute, | 19 | Symbol(SymbolKind), |
20 | |||
18 | BoolLiteral, | 21 | BoolLiteral, |
19 | BuiltinType, | 22 | BuiltinType, |
20 | ByteLiteral, | 23 | ByteLiteral, |
21 | CharLiteral, | 24 | CharLiteral, |
25 | NumericLiteral, | ||
26 | StringLiteral, | ||
27 | Attribute, | ||
22 | Comment, | 28 | Comment, |
23 | Constant, | ||
24 | Enum, | ||
25 | EnumVariant, | ||
26 | EscapeSequence, | 29 | EscapeSequence, |
27 | Field, | 30 | FormatSpecifier, |
28 | Function, | ||
29 | Generic, | ||
30 | Keyword, | 31 | Keyword, |
31 | Lifetime, | ||
32 | Macro, | ||
33 | Method, | ||
34 | Module, | ||
35 | NumericLiteral, | ||
36 | Punctuation, | 32 | Punctuation, |
37 | SelfKeyword, | ||
38 | SelfType, | ||
39 | Static, | ||
40 | StringLiteral, | ||
41 | Struct, | ||
42 | Trait, | ||
43 | TypeAlias, | ||
44 | TypeParam, | ||
45 | Union, | ||
46 | ValueParam, | ||
47 | Local, | ||
48 | UnresolvedReference, | ||
49 | FormatSpecifier, | ||
50 | Operator, | 33 | Operator, |
34 | UnresolvedReference, | ||
35 | |||
36 | // For things which don't have proper Tag, but want to use modifiers. | ||
37 | Dummy, | ||
51 | } | 38 | } |
52 | 39 | ||
53 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 40 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
@@ -64,48 +51,53 @@ pub enum HighlightModifier { | |||
64 | Injected, | 51 | Injected, |
65 | Mutable, | 52 | Mutable, |
66 | Consuming, | 53 | Consuming, |
67 | Unsafe, | ||
68 | Callable, | 54 | Callable, |
69 | /// Used for associated functions | 55 | /// Used for associated functions |
70 | Static, | 56 | Static, |
57 | /// Used for items in impls&traits. | ||
58 | Associated, | ||
59 | |||
60 | /// Keep this last! | ||
61 | Unsafe, | ||
71 | } | 62 | } |
72 | 63 | ||
73 | impl HighlightTag { | 64 | impl HighlightTag { |
74 | fn as_str(self) -> &'static str { | 65 | fn as_str(self) -> &'static str { |
75 | match self { | 66 | match self { |
67 | HighlightTag::Symbol(symbol) => match symbol { | ||
68 | SymbolKind::Const => "constant", | ||
69 | SymbolKind::Static => "static", | ||
70 | SymbolKind::Enum => "enum", | ||
71 | SymbolKind::Variant => "enum_variant", | ||
72 | SymbolKind::Struct => "struct", | ||
73 | SymbolKind::Union => "union", | ||
74 | SymbolKind::Field => "field", | ||
75 | SymbolKind::Module => "module", | ||
76 | SymbolKind::Trait => "trait", | ||
77 | SymbolKind::Function => "function", | ||
78 | SymbolKind::TypeAlias => "type_alias", | ||
79 | SymbolKind::TypeParam => "type_param", | ||
80 | SymbolKind::LifetimeParam => "lifetime", | ||
81 | SymbolKind::Macro => "macro", | ||
82 | SymbolKind::Local => "variable", | ||
83 | SymbolKind::ValueParam => "value_param", | ||
84 | SymbolKind::SelfParam => "self_keyword", | ||
85 | SymbolKind::Impl => "self_type", | ||
86 | }, | ||
76 | HighlightTag::Attribute => "attribute", | 87 | HighlightTag::Attribute => "attribute", |
77 | HighlightTag::BoolLiteral => "bool_literal", | 88 | HighlightTag::BoolLiteral => "bool_literal", |
78 | HighlightTag::BuiltinType => "builtin_type", | 89 | HighlightTag::BuiltinType => "builtin_type", |
79 | HighlightTag::ByteLiteral => "byte_literal", | 90 | HighlightTag::ByteLiteral => "byte_literal", |
80 | HighlightTag::CharLiteral => "char_literal", | 91 | HighlightTag::CharLiteral => "char_literal", |
81 | HighlightTag::Comment => "comment", | 92 | HighlightTag::Comment => "comment", |
82 | HighlightTag::Constant => "constant", | ||
83 | HighlightTag::Enum => "enum", | ||
84 | HighlightTag::EnumVariant => "enum_variant", | ||
85 | HighlightTag::EscapeSequence => "escape_sequence", | 93 | HighlightTag::EscapeSequence => "escape_sequence", |
86 | HighlightTag::Field => "field", | ||
87 | HighlightTag::FormatSpecifier => "format_specifier", | 94 | HighlightTag::FormatSpecifier => "format_specifier", |
88 | HighlightTag::Function => "function", | 95 | HighlightTag::Dummy => "dummy", |
89 | HighlightTag::Generic => "generic", | ||
90 | HighlightTag::Keyword => "keyword", | 96 | HighlightTag::Keyword => "keyword", |
91 | HighlightTag::Lifetime => "lifetime", | ||
92 | HighlightTag::Punctuation => "punctuation", | 97 | HighlightTag::Punctuation => "punctuation", |
93 | HighlightTag::Macro => "macro", | ||
94 | HighlightTag::Method => "method", | ||
95 | HighlightTag::Module => "module", | ||
96 | HighlightTag::NumericLiteral => "numeric_literal", | 98 | HighlightTag::NumericLiteral => "numeric_literal", |
97 | HighlightTag::Operator => "operator", | 99 | HighlightTag::Operator => "operator", |
98 | HighlightTag::SelfKeyword => "self_keyword", | ||
99 | HighlightTag::SelfType => "self_type", | ||
100 | HighlightTag::Static => "static", | ||
101 | HighlightTag::StringLiteral => "string_literal", | 100 | HighlightTag::StringLiteral => "string_literal", |
102 | HighlightTag::Struct => "struct", | ||
103 | HighlightTag::Trait => "trait", | ||
104 | HighlightTag::TypeAlias => "type_alias", | ||
105 | HighlightTag::TypeParam => "type_param", | ||
106 | HighlightTag::Union => "union", | ||
107 | HighlightTag::ValueParam => "value_param", | ||
108 | HighlightTag::Local => "variable", | ||
109 | HighlightTag::UnresolvedReference => "unresolved_reference", | 101 | HighlightTag::UnresolvedReference => "unresolved_reference", |
110 | } | 102 | } |
111 | } | 103 | } |
@@ -118,7 +110,7 @@ impl fmt::Display for HighlightTag { | |||
118 | } | 110 | } |
119 | 111 | ||
120 | impl HighlightModifier { | 112 | impl HighlightModifier { |
121 | const ALL: &'static [HighlightModifier] = &[ | 113 | const ALL: &'static [HighlightModifier; HighlightModifier::Unsafe as u8 as usize + 1] = &[ |
122 | HighlightModifier::Attribute, | 114 | HighlightModifier::Attribute, |
123 | HighlightModifier::ControlFlow, | 115 | HighlightModifier::ControlFlow, |
124 | HighlightModifier::Definition, | 116 | HighlightModifier::Definition, |
@@ -126,9 +118,10 @@ impl HighlightModifier { | |||
126 | HighlightModifier::Injected, | 118 | HighlightModifier::Injected, |
127 | HighlightModifier::Mutable, | 119 | HighlightModifier::Mutable, |
128 | HighlightModifier::Consuming, | 120 | HighlightModifier::Consuming, |
129 | HighlightModifier::Unsafe, | ||
130 | HighlightModifier::Callable, | 121 | HighlightModifier::Callable, |
131 | HighlightModifier::Static, | 122 | HighlightModifier::Static, |
123 | HighlightModifier::Associated, | ||
124 | HighlightModifier::Unsafe, | ||
132 | ]; | 125 | ]; |
133 | 126 | ||
134 | fn as_str(self) -> &'static str { | 127 | fn as_str(self) -> &'static str { |
@@ -143,6 +136,7 @@ impl HighlightModifier { | |||
143 | HighlightModifier::Unsafe => "unsafe", | 136 | HighlightModifier::Unsafe => "unsafe", |
144 | HighlightModifier::Callable => "callable", | 137 | HighlightModifier::Callable => "callable", |
145 | HighlightModifier::Static => "static", | 138 | HighlightModifier::Static => "static", |
139 | HighlightModifier::Associated => "associated", | ||
146 | } | 140 | } |
147 | } | 141 | } |
148 | 142 | ||
@@ -209,6 +203,10 @@ impl ops::BitOr<HighlightModifier> for Highlight { | |||
209 | } | 203 | } |
210 | 204 | ||
211 | impl HighlightModifiers { | 205 | impl HighlightModifiers { |
206 | pub fn contains(self, m: HighlightModifier) -> bool { | ||
207 | self.0 & m.mask() == m.mask() | ||
208 | } | ||
209 | |||
212 | pub fn iter(self) -> impl Iterator<Item = HighlightModifier> { | 210 | pub fn iter(self) -> impl Iterator<Item = HighlightModifier> { |
213 | HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask()) | 211 | HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask()) |
214 | } | 212 | } |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html index 6fb606a47..db6f32d33 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html | |||
@@ -40,17 +40,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
40 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 40 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
41 | 41 | ||
42 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span> | 42 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span> |
43 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 43 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
44 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 44 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
45 | <span class="punctuation">}</span> | 45 | <span class="punctuation">}</span> |
46 | 46 | ||
47 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span> | 47 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span> |
48 | <span class="keyword">fn</span> <span class="method declaration static">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 48 | <span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
49 | <span class="keyword">fn</span> <span class="method declaration">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 49 | <span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
50 | <span class="punctuation">}</span> | 50 | <span class="punctuation">}</span> |
51 | 51 | ||
52 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span> | 52 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span> |
53 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 53 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
54 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 54 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
55 | <span class="punctuation">}</span> | 55 | <span class="punctuation">}</span> |
56 | </code></pre> \ No newline at end of file | 56 | </code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 920956b51..4e511baa9 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -36,24 +36,24 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 36 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
37 | </style> | 37 | </style> |
38 | <pre><code><span class="comment documentation">/// ```</span> | 38 | <pre><code><span class="comment documentation">/// ```</span> |
39 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="punctuation injected">_</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected"> | 39 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="punctuation injected">_</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected"> |
40 | </span><span class="comment documentation">/// ```</span> | 40 | </span><span class="comment documentation">/// ```</span> |
41 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> | 41 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> |
42 | <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span> | 42 | <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span> |
43 | <span class="punctuation">}</span> | 43 | <span class="punctuation">}</span> |
44 | 44 | ||
45 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 45 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
46 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span> | 46 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span> |
47 | 47 | ||
48 | <span class="comment documentation">/// Constructs a new `Foo`.</span> | 48 | <span class="comment documentation">/// Constructs a new `Foo`.</span> |
49 | <span class="comment documentation">///</span> | 49 | <span class="comment documentation">///</span> |
50 | <span class="comment documentation">/// # Examples</span> | 50 | <span class="comment documentation">/// # Examples</span> |
51 | <span class="comment documentation">///</span> | 51 | <span class="comment documentation">///</span> |
52 | <span class="comment documentation">/// ```</span> | 52 | <span class="comment documentation">/// ```</span> |
53 | <span class="comment documentation">/// #</span><span class="generic injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span> | 53 | <span class="comment documentation">/// #</span><span class="dummy injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span> |
54 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="keyword injected">mut</span><span class="generic injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> | 54 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="keyword injected">mut</span><span class="dummy injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> |
55 | </span> <span class="comment documentation">/// ```</span> | 55 | </span> <span class="comment documentation">/// ```</span> |
56 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="method declaration static">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 56 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
57 | <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span> | 57 | <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span> |
58 | <span class="punctuation">}</span> | 58 | <span class="punctuation">}</span> |
59 | 59 | ||
@@ -62,32 +62,32 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
62 | <span class="comment documentation">/// # Examples</span> | 62 | <span class="comment documentation">/// # Examples</span> |
63 | <span class="comment documentation">///</span> | 63 | <span class="comment documentation">///</span> |
64 | <span class="comment documentation">/// ```</span> | 64 | <span class="comment documentation">/// ```</span> |
65 | <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="generic injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span> | 65 | <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="dummy injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span> |
66 | <span class="comment documentation">///</span> | 66 | <span class="comment documentation">///</span> |
67 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foo</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 67 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> |
68 | <span class="comment documentation">///</span> | 68 | <span class="comment documentation">///</span> |
69 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> | 69 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> |
70 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="generic injected">foo</span><span class="operator injected">.</span><span class="generic injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 70 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="dummy injected">foo</span><span class="operator injected">.</span><span class="dummy injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> |
71 | <span class="comment documentation">///</span> | 71 | <span class="comment documentation">///</span> |
72 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">bar</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="generic injected"> </span><span class="operator injected">||</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span> | 72 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">bar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="dummy injected"> </span><span class="operator injected">||</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span> |
73 | <span class="comment documentation">///</span> | 73 | <span class="comment documentation">///</span> |
74 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line | 74 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line |
75 | </span><span class="comment documentation">/// </span><span class="comment injected"> comment */</span> | 75 | </span><span class="comment documentation">/// </span><span class="comment injected"> comment */</span> |
76 | <span class="comment documentation">///</span> | 76 | <span class="comment documentation">///</span> |
77 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"Foo | 77 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"Foo |
78 | </span><span class="comment documentation">/// </span><span class="string_literal injected"> bar | 78 | </span><span class="comment documentation">/// </span><span class="string_literal injected"> bar |
79 | </span><span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="punctuation injected">;</span> | 79 | </span><span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="punctuation injected">;</span> |
80 | <span class="comment documentation">///</span> | 80 | <span class="comment documentation">///</span> |
81 | <span class="comment documentation">/// ```</span> | 81 | <span class="comment documentation">/// ```</span> |
82 | <span class="comment documentation">///</span> | 82 | <span class="comment documentation">///</span> |
83 | <span class="comment documentation">/// ```rust,no_run</span> | 83 | <span class="comment documentation">/// ```rust,no_run</span> |
84 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foobar</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> | 84 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foobar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> |
85 | </span> <span class="comment documentation">/// ```</span> | 85 | </span> <span class="comment documentation">/// ```</span> |
86 | <span class="comment documentation">///</span> | 86 | <span class="comment documentation">///</span> |
87 | <span class="comment documentation">/// ```sh</span> | 87 | <span class="comment documentation">/// ```sh</span> |
88 | <span class="comment documentation">/// echo 1</span> | 88 | <span class="comment documentation">/// echo 1</span> |
89 | <span class="comment documentation">/// ```</span> | 89 | <span class="comment documentation">/// ```</span> |
90 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="punctuation">{</span> | 90 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="punctuation">{</span> |
91 | <span class="bool_literal">true</span> | 91 | <span class="bool_literal">true</span> |
92 | <span class="punctuation">}</span> | 92 | <span class="punctuation">}</span> |
93 | <span class="punctuation">}</span> | 93 | <span class="punctuation">}</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 31daf2bd0..7f18ad297 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html | |||
@@ -40,7 +40,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
40 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 40 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
41 | <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span> | 41 | <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span> |
42 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span> | 42 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span> |
43 | <span class="keyword">fn</span> <span class="method declaration static">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 43 | <span class="keyword">fn</span> <span class="function declaration static associated">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
44 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span> | 44 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span> |
45 | <span class="punctuation">}</span> | 45 | <span class="punctuation">}</span> |
46 | <span class="punctuation">}</span><span class="string_literal">"#</span> | 46 | <span class="punctuation">}</span><span class="string_literal">"#</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 67ec73f15..d26f48516 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html | |||
@@ -45,7 +45,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
45 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> | 45 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> |
46 | 46 | ||
47 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> | 47 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> |
48 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="method declaration unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 48 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
49 | <span class="punctuation">}</span> | 49 | <span class="punctuation">}</span> |
50 | 50 | ||
51 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span> | 51 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span> |
@@ -60,11 +60,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
60 | <span class="punctuation">}</span> | 60 | <span class="punctuation">}</span> |
61 | 61 | ||
62 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span> | 62 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span> |
63 | <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span> | 63 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span> |
64 | <span class="punctuation">}</span> | 64 | <span class="punctuation">}</span> |
65 | 65 | ||
66 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span> | 66 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span> |
67 | <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 67 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
68 | <span class="punctuation">}</span> | 68 | <span class="punctuation">}</span> |
69 | 69 | ||
70 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 70 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
@@ -78,7 +78,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
78 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 78 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> |
79 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 79 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> |
80 | <span class="punctuation">}</span> | 80 | <span class="punctuation">}</span> |
81 | <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="method unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 81 | <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="function associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
82 | 82 | ||
83 | <span class="comment">// unsafe deref</span> | 83 | <span class="comment">// unsafe deref</span> |
84 | <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span> | 84 | <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span> |
@@ -94,6 +94,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
94 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span> | 94 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span> |
95 | 95 | ||
96 | <span class="comment">// unsafe auto ref of packed field</span> | 96 | <span class="comment">// unsafe auto ref of packed field</span> |
97 | <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="method unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 97 | <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="function associated unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
98 | <span class="punctuation">}</span> | 98 | <span class="punctuation">}</span> |
99 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 99 | <span class="punctuation">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 3530a5fdb..588e86a34 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -65,25 +65,25 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
65 | <span class="punctuation">}</span> | 65 | <span class="punctuation">}</span> |
66 | 66 | ||
67 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span> | 67 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span> |
68 | <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="punctuation">;</span> | 68 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="punctuation">;</span> |
69 | <span class="punctuation">}</span> | 69 | <span class="punctuation">}</span> |
70 | 70 | ||
71 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 71 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
72 | <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 72 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> |
73 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 73 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
74 | <span class="punctuation">}</span> | 74 | <span class="punctuation">}</span> |
75 | <span class="punctuation">}</span> | 75 | <span class="punctuation">}</span> |
76 | 76 | ||
77 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 77 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
78 | <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 78 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> |
79 | <span class="value_param">f</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> | 79 | <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> |
80 | <span class="punctuation">}</span> | 80 | <span class="punctuation">}</span> |
81 | 81 | ||
82 | <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 82 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
83 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 83 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> |
84 | <span class="punctuation">}</span> | 84 | <span class="punctuation">}</span> |
85 | 85 | ||
86 | <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 86 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> |
87 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 87 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
88 | <span class="punctuation">}</span> | 88 | <span class="punctuation">}</span> |
89 | <span class="punctuation">}</span> | 89 | <span class="punctuation">}</span> |
@@ -94,15 +94,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
94 | <span class="punctuation">}</span> | 94 | <span class="punctuation">}</span> |
95 | 95 | ||
96 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> | 96 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> |
97 | <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> | 97 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> |
98 | <span class="value_param">f</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> | 98 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> |
99 | <span class="punctuation">}</span> | 99 | <span class="punctuation">}</span> |
100 | 100 | ||
101 | <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 101 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
102 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 102 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> |
103 | <span class="punctuation">}</span> | 103 | <span class="punctuation">}</span> |
104 | 104 | ||
105 | <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> | 105 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> |
106 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 106 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
107 | <span class="punctuation">}</span> | 107 | <span class="punctuation">}</span> |
108 | <span class="punctuation">}</span> | 108 | <span class="punctuation">}</span> |
@@ -178,17 +178,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
178 | 178 | ||
179 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 179 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> |
180 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 180 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> |
181 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 181 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
182 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 182 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
183 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> | 183 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> |
184 | 184 | ||
185 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 185 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> |
186 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 186 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
187 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 187 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
188 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span> | 188 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span> |
189 | 189 | ||
190 | <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span> | 190 | <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span> |
191 | <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="method">baz</span><span class="punctuation">;</span> | 191 | <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="punctuation">;</span> |
192 | 192 | ||
193 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> | 193 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> |
194 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> | 194 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> |
@@ -203,7 +203,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
203 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span> | 203 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span> |
204 | 204 | ||
205 | <span class="keyword">impl</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">T</span><span class="punctuation">></span> <span class="punctuation">{</span> | 205 | <span class="keyword">impl</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">T</span><span class="punctuation">></span> <span class="punctuation">{</span> |
206 | <span class="keyword">fn</span> <span class="method declaration">and</span><span class="punctuation"><</span><span class="type_param declaration">U</span><span class="punctuation">></span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">U</span><span class="punctuation">></span><span class="punctuation">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">></span> <span class="punctuation">{</span> | 206 | <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="punctuation"><</span><span class="type_param declaration">U</span><span class="punctuation">></span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">U</span><span class="punctuation">></span><span class="punctuation">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">></span> <span class="punctuation">{</span> |
207 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span> | 207 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span> |
208 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 208 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> |
209 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="punctuation">,</span> | 209 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="punctuation">,</span> |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index bd2afc887..9d7dce1d4 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -66,7 +66,7 @@ impl Definition { | |||
66 | hir::Adt::Union(it) => it.name(db), | 66 | hir::Adt::Union(it) => it.name(db), |
67 | hir::Adt::Enum(it) => it.name(db), | 67 | hir::Adt::Enum(it) => it.name(db), |
68 | }, | 68 | }, |
69 | hir::ModuleDef::EnumVariant(it) => it.name(db), | 69 | hir::ModuleDef::Variant(it) => it.name(db), |
70 | hir::ModuleDef::Const(it) => it.name(db)?, | 70 | hir::ModuleDef::Const(it) => it.name(db)?, |
71 | hir::ModuleDef::Static(it) => it.name(db)?, | 71 | hir::ModuleDef::Static(it) => it.name(db)?, |
72 | hir::ModuleDef::Trait(it) => it.name(db), | 72 | hir::ModuleDef::Trait(it) => it.name(db), |
@@ -207,7 +207,7 @@ impl NameClass { | |||
207 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 207 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
208 | }, | 208 | }, |
209 | ast::Variant(it) => { | 209 | ast::Variant(it) => { |
210 | let def: hir::EnumVariant = sema.to_def(&it)?; | 210 | let def: hir::Variant = sema.to_def(&it)?; |
211 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 211 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
212 | }, | 212 | }, |
213 | ast::Fn(it) => { | 213 | ast::Fn(it) => { |
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index 9be36d59b..d6b498be3 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs | |||
@@ -9,7 +9,7 @@ use syntax::{ | |||
9 | ast::{ | 9 | ast::{ |
10 | self, | 10 | self, |
11 | edit::{AstNodeEdit, IndentLevel}, | 11 | edit::{AstNodeEdit, IndentLevel}, |
12 | make, AstNode, PathSegmentKind, VisibilityOwner, | 12 | make, AstNode, AttrsOwner, PathSegmentKind, VisibilityOwner, |
13 | }, | 13 | }, |
14 | AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, | 14 | AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, |
15 | }; | 15 | }; |
@@ -180,6 +180,15 @@ fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) - | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | fn eq_attrs( | ||
184 | attrs0: impl Iterator<Item = ast::Attr>, | ||
185 | attrs1: impl Iterator<Item = ast::Attr>, | ||
186 | ) -> bool { | ||
187 | let attrs0 = attrs0.map(|attr| attr.to_string()); | ||
188 | let attrs1 = attrs1.map(|attr| attr.to_string()); | ||
189 | attrs0.eq(attrs1) | ||
190 | } | ||
191 | |||
183 | pub fn try_merge_imports( | 192 | pub fn try_merge_imports( |
184 | lhs: &ast::Use, | 193 | lhs: &ast::Use, |
185 | rhs: &ast::Use, | 194 | rhs: &ast::Use, |
@@ -189,6 +198,10 @@ pub fn try_merge_imports( | |||
189 | if !eq_visibility(lhs.visibility(), rhs.visibility()) { | 198 | if !eq_visibility(lhs.visibility(), rhs.visibility()) { |
190 | return None; | 199 | return None; |
191 | } | 200 | } |
201 | if !eq_attrs(lhs.attrs(), rhs.attrs()) { | ||
202 | return None; | ||
203 | } | ||
204 | |||
192 | let lhs_tree = lhs.use_tree()?; | 205 | let lhs_tree = lhs.use_tree()?; |
193 | let rhs_tree = rhs.use_tree()?; | 206 | let rhs_tree = rhs.use_tree()?; |
194 | let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?; | 207 | let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?; |
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 9e194354e..a603fe87f 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs | |||
@@ -448,6 +448,20 @@ use std::io;", | |||
448 | } | 448 | } |
449 | 449 | ||
450 | #[test] | 450 | #[test] |
451 | fn merge_groups_skip_attributed() { | ||
452 | check_full( | ||
453 | "std::io", | ||
454 | r#" | ||
455 | #[cfg(feature = "gated")] use std::fmt::{Result, Display}; | ||
456 | "#, | ||
457 | r#" | ||
458 | #[cfg(feature = "gated")] use std::fmt::{Result, Display}; | ||
459 | use std::io; | ||
460 | "#, | ||
461 | ) | ||
462 | } | ||
463 | |||
464 | #[test] | ||
451 | #[ignore] // FIXME: Support this | 465 | #[ignore] // FIXME: Support this |
452 | fn split_out_merge() { | 466 | fn split_out_merge() { |
453 | check_last( | 467 | check_last( |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 525c8a41f..ff10f71c3 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -141,7 +141,7 @@ impl Definition { | |||
141 | hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(), | 141 | hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(), |
142 | hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(), | 142 | hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(), |
143 | hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(), | 143 | hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(), |
144 | hir::GenericDef::EnumVariant(it) => it.source(db).value.syntax().text_range(), | 144 | hir::GenericDef::Variant(it) => it.source(db).value.syntax().text_range(), |
145 | hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(), | 145 | hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(), |
146 | }; | 146 | }; |
147 | let mut res = FxHashMap::default(); | 147 | let mut res = FxHashMap::default(); |
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index ca455fa03..0aa6a0765 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs | |||
@@ -39,7 +39,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
39 | use syntax::{ | 39 | use syntax::{ |
40 | ast::{self, NameOwner}, | 40 | ast::{self, NameOwner}, |
41 | match_ast, AstNode, Parse, SmolStr, SourceFile, | 41 | match_ast, AstNode, Parse, SmolStr, SourceFile, |
42 | SyntaxKind::{self, *}, | 42 | SyntaxKind::*, |
43 | SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, | 43 | SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, |
44 | }; | 44 | }; |
45 | 45 | ||
@@ -323,7 +323,7 @@ impl Query { | |||
323 | let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); | 323 | let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); |
324 | 324 | ||
325 | for symbol in &symbol_index.symbols[start..end] { | 325 | for symbol in &symbol_index.symbols[start..end] { |
326 | if self.only_types && !is_type(symbol.kind) { | 326 | if self.only_types && !symbol.kind.is_type() { |
327 | continue; | 327 | continue; |
328 | } | 328 | } |
329 | if self.exact && symbol.name != self.query { | 329 | if self.exact && symbol.name != self.query { |
@@ -341,23 +341,44 @@ impl Query { | |||
341 | } | 341 | } |
342 | } | 342 | } |
343 | 343 | ||
344 | fn is_type(kind: SyntaxKind) -> bool { | ||
345 | matches!(kind, STRUCT | ENUM | TRAIT | TYPE_ALIAS) | ||
346 | } | ||
347 | |||
348 | /// The actual data that is stored in the index. It should be as compact as | 344 | /// The actual data that is stored in the index. It should be as compact as |
349 | /// possible. | 345 | /// possible. |
350 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 346 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
351 | pub struct FileSymbol { | 347 | pub struct FileSymbol { |
352 | pub file_id: FileId, | 348 | pub file_id: FileId, |
353 | pub name: SmolStr, | 349 | pub name: SmolStr, |
354 | pub kind: SyntaxKind, | 350 | pub kind: FileSymbolKind, |
355 | pub range: TextRange, | 351 | pub range: TextRange, |
356 | pub ptr: SyntaxNodePtr, | 352 | pub ptr: SyntaxNodePtr, |
357 | pub name_range: Option<TextRange>, | 353 | pub name_range: Option<TextRange>, |
358 | pub container_name: Option<SmolStr>, | 354 | pub container_name: Option<SmolStr>, |
359 | } | 355 | } |
360 | 356 | ||
357 | #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] | ||
358 | pub enum FileSymbolKind { | ||
359 | Function, | ||
360 | Struct, | ||
361 | Enum, | ||
362 | Trait, | ||
363 | Module, | ||
364 | TypeAlias, | ||
365 | Const, | ||
366 | Static, | ||
367 | Macro, | ||
368 | } | ||
369 | |||
370 | impl FileSymbolKind { | ||
371 | fn is_type(self: FileSymbolKind) -> bool { | ||
372 | matches!( | ||
373 | self, | ||
374 | FileSymbolKind::Struct | ||
375 | | FileSymbolKind::Enum | ||
376 | | FileSymbolKind::Trait | ||
377 | | FileSymbolKind::TypeAlias | ||
378 | ) | ||
379 | } | ||
380 | } | ||
381 | |||
361 | fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> { | 382 | fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> { |
362 | let mut symbols = Vec::new(); | 383 | let mut symbols = Vec::new(); |
363 | let mut stack = Vec::new(); | 384 | let mut stack = Vec::new(); |
@@ -412,7 +433,18 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { | |||
412 | fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { | 433 | fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { |
413 | to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { | 434 | to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { |
414 | name, | 435 | name, |
415 | kind: node.kind(), | 436 | kind: match node.kind() { |
437 | FN => FileSymbolKind::Function, | ||
438 | STRUCT => FileSymbolKind::Struct, | ||
439 | ENUM => FileSymbolKind::Enum, | ||
440 | TRAIT => FileSymbolKind::Trait, | ||
441 | MODULE => FileSymbolKind::Module, | ||
442 | TYPE_ALIAS => FileSymbolKind::TypeAlias, | ||
443 | CONST => FileSymbolKind::Const, | ||
444 | STATIC => FileSymbolKind::Static, | ||
445 | MACRO_RULES => FileSymbolKind::Macro, | ||
446 | kind => unreachable!("{:?}", kind), | ||
447 | }, | ||
416 | range: node.text_range(), | 448 | range: node.text_range(), |
417 | ptr, | 449 | ptr, |
418 | file_id, | 450 | file_id, |
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs index 616119ba9..57592dc92 100644 --- a/crates/mbe/src/mbe_expander/transcriber.rs +++ b/crates/mbe/src/mbe_expander/transcriber.rs | |||
@@ -97,7 +97,7 @@ fn expand_subtree( | |||
97 | err = err.or(e); | 97 | err = err.or(e); |
98 | arena.push(tt.into()); | 98 | arena.push(tt.into()); |
99 | } | 99 | } |
100 | Op::Var { name, kind: _ } => { | 100 | Op::Var { name, .. } => { |
101 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, name); | 101 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, name); |
102 | err = err.or(e); | 102 | err = err.or(e); |
103 | push_fragment(arena, fragment); | 103 | push_fragment(arena, fragment); |
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 6b46a1673..c3fdd4040 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs | |||
@@ -101,7 +101,9 @@ fn next_op<'a>( | |||
101 | Op::Repeat { subtree, separator, kind } | 101 | Op::Repeat { subtree, separator, kind } |
102 | } | 102 | } |
103 | tt::TokenTree::Leaf(leaf) => match leaf { | 103 | tt::TokenTree::Leaf(leaf) => match leaf { |
104 | tt::Leaf::Punct(..) => return Err(ExpandError::UnexpectedToken), | 104 | tt::Leaf::Punct(_) => { |
105 | return Err(ExpandError::UnexpectedToken); | ||
106 | } | ||
105 | tt::Leaf::Ident(ident) => { | 107 | tt::Leaf::Ident(ident) => { |
106 | let name = &ident.text; | 108 | let name = &ident.text; |
107 | let kind = eat_fragment_kind(src, mode)?; | 109 | let kind = eat_fragment_kind(src, mode)?; |
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index 265c0d63d..2bec7fd49 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs | |||
@@ -313,7 +313,7 @@ trait TokenConvertor { | |||
313 | return; | 313 | return; |
314 | } | 314 | } |
315 | 315 | ||
316 | result.push(if k.is_punct() { | 316 | result.push(if k.is_punct() && k != UNDERSCORE { |
317 | assert_eq!(range.len(), TextSize::of('.')); | 317 | assert_eq!(range.len(), TextSize::of('.')); |
318 | let delim = match k { | 318 | let delim = match k { |
319 | T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])), | 319 | T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])), |
@@ -378,6 +378,7 @@ trait TokenConvertor { | |||
378 | let leaf: tt::Leaf = match k { | 378 | let leaf: tt::Leaf = match k { |
379 | T![true] | T![false] => make_leaf!(Ident), | 379 | T![true] | T![false] => make_leaf!(Ident), |
380 | IDENT => make_leaf!(Ident), | 380 | IDENT => make_leaf!(Ident), |
381 | UNDERSCORE => make_leaf!(Ident), | ||
381 | k if k.is_keyword() => make_leaf!(Ident), | 382 | k if k.is_keyword() => make_leaf!(Ident), |
382 | k if k.is_literal() => make_leaf!(Literal), | 383 | k if k.is_literal() => make_leaf!(Literal), |
383 | LIFETIME_IDENT => { | 384 | LIFETIME_IDENT => { |
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index dff6e98c2..f10e7a9b6 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs | |||
@@ -992,6 +992,18 @@ fn test_tt_composite2() { | |||
992 | } | 992 | } |
993 | 993 | ||
994 | #[test] | 994 | #[test] |
995 | fn test_underscore() { | ||
996 | parse_macro( | ||
997 | r#" | ||
998 | macro_rules! foo { | ||
999 | ($_:tt) => { 0 } | ||
1000 | } | ||
1001 | "#, | ||
1002 | ) | ||
1003 | .assert_expand_items(r#"foo! { => }"#, r#"0"#); | ||
1004 | } | ||
1005 | |||
1006 | #[test] | ||
995 | fn test_lifetime() { | 1007 | fn test_lifetime() { |
996 | parse_macro( | 1008 | parse_macro( |
997 | r#" | 1009 | r#" |
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index 23039eba4..1a078f6b4 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs | |||
@@ -133,6 +133,10 @@ pub(crate) mod fragments { | |||
133 | 133 | ||
134 | m.complete(p, MACRO_STMTS); | 134 | m.complete(p, MACRO_STMTS); |
135 | } | 135 | } |
136 | |||
137 | pub(crate) fn attr(p: &mut Parser) { | ||
138 | attributes::outer_attrs(p) | ||
139 | } | ||
136 | } | 140 | } |
137 | 141 | ||
138 | pub(crate) fn reparser( | 142 | pub(crate) fn reparser( |
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 41e62116f..ab8e4c70e 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs | |||
@@ -99,6 +99,8 @@ pub enum FragmentKind { | |||
99 | // FIXME: use separate fragment kinds for macro inputs and outputs? | 99 | // FIXME: use separate fragment kinds for macro inputs and outputs? |
100 | Items, | 100 | Items, |
101 | Statements, | 101 | Statements, |
102 | |||
103 | Attr, | ||
102 | } | 104 | } |
103 | 105 | ||
104 | pub fn parse_fragment( | 106 | pub fn parse_fragment( |
@@ -118,6 +120,7 @@ pub fn parse_fragment( | |||
118 | FragmentKind::Statement => grammar::fragments::stmt, | 120 | FragmentKind::Statement => grammar::fragments::stmt, |
119 | FragmentKind::Items => grammar::fragments::macro_items, | 121 | FragmentKind::Items => grammar::fragments::macro_items, |
120 | FragmentKind::Statements => grammar::fragments::macro_stmts, | 122 | FragmentKind::Statements => grammar::fragments::macro_stmts, |
123 | FragmentKind::Attr => grammar::fragments::attr, | ||
121 | }; | 124 | }; |
122 | parse_from_tokens(token_source, tree_sink, parser) | 125 | parse_from_tokens(token_source, tree_sink, parser) |
123 | } | 126 | } |
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index 894c5c952..bb3b6f2ef 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs | |||
@@ -16,6 +16,7 @@ use paths::{AbsPath, AbsPathBuf}; | |||
16 | use rustc_hash::FxHashMap; | 16 | use rustc_hash::FxHashMap; |
17 | 17 | ||
18 | use crate::cfg_flag::CfgFlag; | 18 | use crate::cfg_flag::CfgFlag; |
19 | use crate::utf8_stdout; | ||
19 | 20 | ||
20 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo | 21 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo |
21 | /// workspace. It pretty closely mirrors `cargo metadata` output. | 22 | /// workspace. It pretty closely mirrors `cargo metadata` output. |
@@ -166,8 +167,34 @@ impl CargoWorkspace { | |||
166 | if let Some(parent) = cargo_toml.parent() { | 167 | if let Some(parent) = cargo_toml.parent() { |
167 | meta.current_dir(parent.to_path_buf()); | 168 | meta.current_dir(parent.to_path_buf()); |
168 | } | 169 | } |
169 | if let Some(target) = config.target.as_ref() { | 170 | let target = if let Some(target) = config.target.as_ref() { |
170 | meta.other_options(vec![String::from("--filter-platform"), target.clone()]); | 171 | Some(target.clone()) |
172 | } else { | ||
173 | // cargo metadata defaults to giving information for _all_ targets. | ||
174 | // In the absence of a preference from the user, we use the host platform. | ||
175 | let mut rustc = Command::new(toolchain::rustc()); | ||
176 | rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV"); | ||
177 | log::debug!("Discovering host platform by {:?}", rustc); | ||
178 | match utf8_stdout(rustc) { | ||
179 | Ok(stdout) => { | ||
180 | let field = "host: "; | ||
181 | let target = stdout.lines().find_map(|l| l.strip_prefix(field)); | ||
182 | if let Some(target) = target { | ||
183 | Some(target.to_string()) | ||
184 | } else { | ||
185 | // If we fail to resolve the host platform, it's not the end of the world. | ||
186 | log::info!("rustc -vV did not report host platform, got:\n{}", stdout); | ||
187 | None | ||
188 | } | ||
189 | } | ||
190 | Err(e) => { | ||
191 | log::warn!("Failed to discover host platform: {}", e); | ||
192 | None | ||
193 | } | ||
194 | } | ||
195 | }; | ||
196 | if let Some(target) = target { | ||
197 | meta.other_options(vec![String::from("--filter-platform"), target]); | ||
171 | } | 198 | } |
172 | let mut meta = meta.exec().with_context(|| { | 199 | let mut meta = meta.exec().with_context(|| { |
173 | format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) | 200 | format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 039976e4b..0b4d3f4eb 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -21,7 +21,7 @@ env_logger = { version = "0.8.1", default-features = false } | |||
21 | itertools = "0.9.0" | 21 | itertools = "0.9.0" |
22 | jod-thread = "0.1.0" | 22 | jod-thread = "0.1.0" |
23 | log = "0.4.8" | 23 | log = "0.4.8" |
24 | lsp-types = { version = "0.85.0", features = ["proposed"] } | 24 | lsp-types = { version = "0.86.0", features = ["proposed"] } |
25 | parking_lot = "0.11.0" | 25 | parking_lot = "0.11.0" |
26 | pico-args = "0.3.1" | 26 | pico-args = "0.3.1" |
27 | oorandom = "11.1.2" | 27 | oorandom = "11.1.2" |
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 5e4c22bc5..de5eb93b5 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -64,7 +64,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
64 | prepare_provider: Some(true), | 64 | prepare_provider: Some(true), |
65 | work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, | 65 | work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, |
66 | })), | 66 | })), |
67 | on_type_rename_provider: None, | 67 | linked_editing_range_provider: None, |
68 | document_link_provider: None, | 68 | document_link_provider: None, |
69 | color_provider: None, | 69 | color_provider: None, |
70 | execute_command_provider: None, | 70 | execute_command_provider: None, |
@@ -83,6 +83,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
83 | } | 83 | } |
84 | .into(), | 84 | .into(), |
85 | ), | 85 | ), |
86 | moniker_provider: None, | ||
86 | experimental: Some(json!({ | 87 | experimental: Some(json!({ |
87 | "joinLines": true, | 88 | "joinLines": true, |
88 | "ssr": true, | 89 | "ssr": true, |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index af226c109..66f8bee99 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -9,7 +9,7 @@ use std::{ | |||
9 | 9 | ||
10 | use ide::{ | 10 | use ide::{ |
11 | CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, | 11 | CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, |
12 | NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, | 12 | NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, SymbolKind, TextEdit, |
13 | }; | 13 | }; |
14 | use itertools::Itertools; | 14 | use itertools::Itertools; |
15 | use lsp_server::ErrorCode; | 15 | use lsp_server::ErrorCode; |
@@ -27,7 +27,7 @@ use project_model::TargetKind; | |||
27 | use serde::{Deserialize, Serialize}; | 27 | use serde::{Deserialize, Serialize}; |
28 | use serde_json::to_value; | 28 | use serde_json::to_value; |
29 | use stdx::{format_to, split_once}; | 29 | use stdx::{format_to, split_once}; |
30 | use syntax::{algo, ast, AstNode, SyntaxKind, TextRange, TextSize}; | 30 | use syntax::{algo, ast, AstNode, TextRange, TextSize}; |
31 | 31 | ||
32 | use crate::{ | 32 | use crate::{ |
33 | cargo_target_spec::CargoTargetSpec, | 33 | cargo_target_spec::CargoTargetSpec, |
@@ -385,7 +385,10 @@ pub(crate) fn handle_workspace_symbol( | |||
385 | #[allow(deprecated)] | 385 | #[allow(deprecated)] |
386 | let info = SymbolInformation { | 386 | let info = SymbolInformation { |
387 | name: nav.name.to_string(), | 387 | name: nav.name.to_string(), |
388 | kind: to_proto::symbol_kind(nav.kind), | 388 | kind: nav |
389 | .kind | ||
390 | .map(to_proto::symbol_kind) | ||
391 | .unwrap_or(lsp_types::SymbolKind::Variable), | ||
389 | tags: None, | 392 | tags: None, |
390 | location: to_proto::location_from_nav(snap, nav)?, | 393 | location: to_proto::location_from_nav(snap, nav)?, |
391 | container_name, | 394 | container_name, |
@@ -1037,10 +1040,10 @@ pub(crate) fn handle_code_lens( | |||
1037 | .filter(|it| { | 1040 | .filter(|it| { |
1038 | matches!( | 1041 | matches!( |
1039 | it.kind, | 1042 | it.kind, |
1040 | SyntaxKind::TRAIT | 1043 | SymbolKind::Trait |
1041 | | SyntaxKind::STRUCT | 1044 | | SymbolKind::Struct |
1042 | | SyntaxKind::ENUM | 1045 | | SymbolKind::Enum |
1043 | | SyntaxKind::UNION | 1046 | | SymbolKind::Union |
1044 | ) | 1047 | ) |
1045 | }) | 1048 | }) |
1046 | .map(|it| { | 1049 | .map(|it| { |
@@ -1263,7 +1266,7 @@ pub(crate) fn handle_call_hierarchy_prepare( | |||
1263 | let RangeInfo { range: _, info: navs } = nav_info; | 1266 | let RangeInfo { range: _, info: navs } = nav_info; |
1264 | let res = navs | 1267 | let res = navs |
1265 | .into_iter() | 1268 | .into_iter() |
1266 | .filter(|it| it.kind == SyntaxKind::FN) | 1269 | .filter(|it| it.kind == Some(SymbolKind::Function)) |
1267 | .map(|it| to_proto::call_hierarchy_item(&snap, it)) | 1270 | .map(|it| to_proto::call_hierarchy_item(&snap, it)) |
1268 | .collect::<Result<Vec<_>>>()?; | 1271 | .collect::<Result<Vec<_>>>()?; |
1269 | 1272 | ||
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 715f8927a..e0561b5a7 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -5,14 +5,13 @@ use std::{ | |||
5 | }; | 5 | }; |
6 | 6 | ||
7 | use ide::{ | 7 | use ide::{ |
8 | Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, | 8 | Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId, |
9 | FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange, | 9 | FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, |
10 | Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, | 10 | HighlightedRange, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, |
11 | ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit, | 11 | NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, |
12 | SourceFileEdit, SymbolKind, TextEdit, TextRange, TextSize, | ||
12 | }; | 13 | }; |
13 | use ide_db::base_db::{FileId, FileRange}; | ||
14 | use itertools::Itertools; | 14 | use itertools::Itertools; |
15 | use syntax::{SyntaxKind, TextRange, TextSize}; | ||
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
18 | cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, | 17 | cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, |
@@ -30,21 +29,25 @@ pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Rang | |||
30 | lsp_types::Range::new(start, end) | 29 | lsp_types::Range::new(start, end) |
31 | } | 30 | } |
32 | 31 | ||
33 | pub(crate) fn symbol_kind(syntax_kind: SyntaxKind) -> lsp_types::SymbolKind { | 32 | pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { |
34 | match syntax_kind { | 33 | match symbol_kind { |
35 | SyntaxKind::FN => lsp_types::SymbolKind::Function, | 34 | SymbolKind::Function => lsp_types::SymbolKind::Function, |
36 | SyntaxKind::STRUCT => lsp_types::SymbolKind::Struct, | 35 | SymbolKind::Struct => lsp_types::SymbolKind::Struct, |
37 | SyntaxKind::ENUM => lsp_types::SymbolKind::Enum, | 36 | SymbolKind::Enum => lsp_types::SymbolKind::Enum, |
38 | SyntaxKind::VARIANT => lsp_types::SymbolKind::EnumMember, | 37 | SymbolKind::Variant => lsp_types::SymbolKind::EnumMember, |
39 | SyntaxKind::TRAIT => lsp_types::SymbolKind::Interface, | 38 | SymbolKind::Trait => lsp_types::SymbolKind::Interface, |
40 | SyntaxKind::MACRO_CALL => lsp_types::SymbolKind::Function, | 39 | SymbolKind::Macro => lsp_types::SymbolKind::Function, |
41 | SyntaxKind::MODULE => lsp_types::SymbolKind::Module, | 40 | SymbolKind::Module => lsp_types::SymbolKind::Module, |
42 | SyntaxKind::TYPE_ALIAS => lsp_types::SymbolKind::TypeParameter, | 41 | SymbolKind::TypeAlias | SymbolKind::TypeParam => lsp_types::SymbolKind::TypeParameter, |
43 | SyntaxKind::RECORD_FIELD => lsp_types::SymbolKind::Field, | 42 | SymbolKind::Field => lsp_types::SymbolKind::Field, |
44 | SyntaxKind::STATIC => lsp_types::SymbolKind::Constant, | 43 | SymbolKind::Static => lsp_types::SymbolKind::Constant, |
45 | SyntaxKind::CONST => lsp_types::SymbolKind::Constant, | 44 | SymbolKind::Const => lsp_types::SymbolKind::Constant, |
46 | SyntaxKind::IMPL => lsp_types::SymbolKind::Object, | 45 | SymbolKind::Impl => lsp_types::SymbolKind::Object, |
47 | _ => lsp_types::SymbolKind::Variable, | 46 | SymbolKind::Local |
47 | | SymbolKind::SelfParam | ||
48 | | SymbolKind::LifetimeParam | ||
49 | | SymbolKind::ValueParam => lsp_types::SymbolKind::Variable, | ||
50 | SymbolKind::Union => lsp_types::SymbolKind::Struct, | ||
48 | } | 51 | } |
49 | } | 52 | } |
50 | 53 | ||
@@ -369,34 +372,41 @@ fn semantic_token_type_and_modifiers( | |||
369 | ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { | 372 | ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { |
370 | let mut mods = semantic_tokens::ModifierSet::default(); | 373 | let mut mods = semantic_tokens::ModifierSet::default(); |
371 | let type_ = match highlight.tag { | 374 | let type_ = match highlight.tag { |
372 | HighlightTag::Struct => lsp_types::SemanticTokenType::STRUCT, | 375 | HighlightTag::Symbol(symbol) => match symbol { |
373 | HighlightTag::Enum => lsp_types::SemanticTokenType::ENUM, | 376 | SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE, |
374 | HighlightTag::Union => semantic_tokens::UNION, | 377 | SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE, |
375 | HighlightTag::TypeAlias => semantic_tokens::TYPE_ALIAS, | 378 | SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY, |
376 | HighlightTag::Trait => lsp_types::SemanticTokenType::INTERFACE, | 379 | SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, |
380 | SymbolKind::LifetimeParam => semantic_tokens::LIFETIME, | ||
381 | SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER, | ||
382 | SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD, | ||
383 | SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE, | ||
384 | SymbolKind::Function => { | ||
385 | if highlight.modifiers.contains(HighlightModifier::Associated) { | ||
386 | lsp_types::SemanticTokenType::METHOD | ||
387 | } else { | ||
388 | lsp_types::SemanticTokenType::FUNCTION | ||
389 | } | ||
390 | } | ||
391 | SymbolKind::Const => { | ||
392 | mods |= semantic_tokens::CONSTANT; | ||
393 | mods |= lsp_types::SemanticTokenModifier::STATIC; | ||
394 | lsp_types::SemanticTokenType::VARIABLE | ||
395 | } | ||
396 | SymbolKind::Static => { | ||
397 | mods |= lsp_types::SemanticTokenModifier::STATIC; | ||
398 | lsp_types::SemanticTokenType::VARIABLE | ||
399 | } | ||
400 | SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT, | ||
401 | SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM, | ||
402 | SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER, | ||
403 | SymbolKind::Union => semantic_tokens::UNION, | ||
404 | SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS, | ||
405 | SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE, | ||
406 | SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO, | ||
407 | }, | ||
377 | HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE, | 408 | HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE, |
378 | HighlightTag::SelfKeyword => semantic_tokens::SELF_KEYWORD, | 409 | HighlightTag::Dummy => semantic_tokens::GENERIC, |
379 | HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE, | ||
380 | HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY, | ||
381 | HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION, | ||
382 | HighlightTag::Generic => semantic_tokens::GENERIC, | ||
383 | HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE, | ||
384 | HighlightTag::Method => lsp_types::SemanticTokenType::METHOD, | ||
385 | HighlightTag::Constant => { | ||
386 | mods |= semantic_tokens::CONSTANT; | ||
387 | mods |= lsp_types::SemanticTokenModifier::STATIC; | ||
388 | lsp_types::SemanticTokenType::VARIABLE | ||
389 | } | ||
390 | HighlightTag::Static => { | ||
391 | mods |= lsp_types::SemanticTokenModifier::STATIC; | ||
392 | lsp_types::SemanticTokenType::VARIABLE | ||
393 | } | ||
394 | HighlightTag::EnumVariant => lsp_types::SemanticTokenType::ENUM_MEMBER, | ||
395 | HighlightTag::Macro => lsp_types::SemanticTokenType::MACRO, | ||
396 | HighlightTag::ValueParam => lsp_types::SemanticTokenType::PARAMETER, | ||
397 | HighlightTag::Local => lsp_types::SemanticTokenType::VARIABLE, | ||
398 | HighlightTag::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, | ||
399 | HighlightTag::Lifetime => semantic_tokens::LIFETIME, | ||
400 | HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => { | 410 | HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => { |
401 | lsp_types::SemanticTokenType::NUMBER | 411 | lsp_types::SemanticTokenType::NUMBER |
402 | } | 412 | } |
@@ -426,6 +436,7 @@ fn semantic_token_type_and_modifiers( | |||
426 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, | 436 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, |
427 | HighlightModifier::Callable => semantic_tokens::CALLABLE, | 437 | HighlightModifier::Callable => semantic_tokens::CALLABLE, |
428 | HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC, | 438 | HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC, |
439 | HighlightModifier::Associated => continue, | ||
429 | }; | 440 | }; |
430 | mods |= modifier; | 441 | mods |= modifier; |
431 | } | 442 | } |
@@ -633,7 +644,7 @@ pub(crate) fn resource_op( | |||
633 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { | 644 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { |
634 | uri, | 645 | uri, |
635 | options: None, | 646 | options: None, |
636 | annotation: None, | 647 | annotation_id: None, |
637 | }) | 648 | }) |
638 | } | 649 | } |
639 | FileSystemEdit::MoveFile { src, dst } => { | 650 | FileSystemEdit::MoveFile { src, dst } => { |
@@ -643,7 +654,7 @@ pub(crate) fn resource_op( | |||
643 | old_uri, | 654 | old_uri, |
644 | new_uri, | 655 | new_uri, |
645 | options: None, | 656 | options: None, |
646 | annotation: None, | 657 | annotation_id: None, |
647 | }) | 658 | }) |
648 | } | 659 | } |
649 | } | 660 | } |
@@ -708,6 +719,7 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { | |||
708 | .collect(), | 719 | .collect(), |
709 | ) | 720 | ) |
710 | }), | 721 | }), |
722 | change_annotations: None, | ||
711 | } | 723 | } |
712 | } | 724 | } |
713 | } | 725 | } |
@@ -718,7 +730,7 @@ pub(crate) fn call_hierarchy_item( | |||
718 | ) -> Result<lsp_types::CallHierarchyItem> { | 730 | ) -> Result<lsp_types::CallHierarchyItem> { |
719 | let name = target.name.to_string(); | 731 | let name = target.name.to_string(); |
720 | let detail = target.description.clone(); | 732 | let detail = target.description.clone(); |
721 | let kind = symbol_kind(target.kind); | 733 | let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::Function); |
722 | let (uri, range, selection_range) = location_info(snap, target)?; | 734 | let (uri, range, selection_range) = location_info(snap, target)?; |
723 | Ok(lsp_types::CallHierarchyItem { | 735 | Ok(lsp_types::CallHierarchyItem { |
724 | name, | 736 | name, |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 16b079c42..ba7e5d2fb 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -20,6 +20,9 @@ pub fn name_ref(text: &str) -> ast::NameRef { | |||
20 | pub fn ty(text: &str) -> ast::Type { | 20 | pub fn ty(text: &str) -> ast::Type { |
21 | ast_from_text(&format!("impl {} for D {{}};", text)) | 21 | ast_from_text(&format!("impl {} for D {{}};", text)) |
22 | } | 22 | } |
23 | pub fn ty_unit() -> ast::Type { | ||
24 | ty("()") | ||
25 | } | ||
23 | 26 | ||
24 | pub fn assoc_item_list() -> ast::AssocItemList { | 27 | pub fn assoc_item_list() -> ast::AssocItemList { |
25 | ast_from_text("impl C for D {};") | 28 | ast_from_text("impl C for D {};") |
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index e753b11bb..4d272f367 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs | |||
@@ -205,6 +205,13 @@ impl ast::Type { | |||
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
208 | impl ast::Attr { | ||
209 | /// Returns `text`, parsed as an attribute, but only if it has no errors. | ||
210 | pub fn parse(text: &str) -> Result<Self, ()> { | ||
211 | parsing::parse_text_fragment(text, parser::FragmentKind::Attr) | ||
212 | } | ||
213 | } | ||
214 | |||
208 | /// Matches a `SyntaxNode` against an `ast` type. | 215 | /// Matches a `SyntaxNode` against an `ast` type. |
209 | /// | 216 | /// |
210 | /// # Example: | 217 | /// # Example: |