diff options
Diffstat (limited to 'crates/ide_db')
-rw-r--r-- | crates/ide_db/src/helpers/insert_use.rs | 15 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/insert_use/tests.rs | 14 | ||||
-rw-r--r-- | crates/ide_db/src/symbol_index.rs | 48 |
3 files changed, 68 insertions, 9 deletions
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/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, |