From fedd0245d105c3a5c483970316b555cbe5f7b34b Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Mon, 18 Apr 2022 21:34:36 +0800 Subject: [PATCH] derive completions take existing derives into count --- crates/ide_completion/src/context.rs | 21 ++++++++++---------- crates/ide_completion/src/tests/attribute.rs | 21 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 12747b3ce4..5f6b8f7db5 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -523,7 +523,8 @@ impl<'a> CompletionContext<'a> { // successful expansions (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => { let new_offset = fake_mapped_token.text_range().start(); - derive_ctx = Some((actual_expansion, fake_expansion, new_offset)); + derive_ctx = + Some((actual_expansion, fake_expansion, new_offset, orig_attr)); break 'expansion; } // exactly one expansion failed, inconsistent state so stop expanding completely @@ -718,7 +719,7 @@ impl<'a> CompletionContext<'a> { original_file: &SyntaxNode, file_with_fake_ident: SyntaxNode, offset: TextSize, - derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize)>, + derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>, ) { let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); let syntax_element = NodeOrToken::Token(fake_ident_token); @@ -742,16 +743,14 @@ impl<'a> CompletionContext<'a> { (self.expected_type, self.expected_name) = self.expected_type_and_name(); // Overwrite the path kind for derives - if let Some((original_file, file_with_fake_ident, offset)) = derive_ctx { - let attr = self + if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx { + self.existing_derives = self .sema - .token_ancestors_with_macros(self.token.clone()) - .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) - .find_map(ast::Attr::cast); - if let Some(attr) = &attr { - self.existing_derives = - self.sema.resolve_derive_macro(attr).into_iter().flatten().flatten().collect(); - } + .resolve_derive_macro(&origin_attr) + .into_iter() + .flatten() + .flatten() + .collect(); if let Some(ast::NameLike::NameRef(name_ref)) = find_node_at_offset(&file_with_fake_ident, offset) diff --git a/crates/ide_completion/src/tests/attribute.rs b/crates/ide_completion/src/tests/attribute.rs index 4ee95e8928..b851bf6a84 100644 --- a/crates/ide_completion/src/tests/attribute.rs +++ b/crates/ide_completion/src/tests/attribute.rs @@ -747,6 +747,27 @@ mod derive { ); } + #[test] + fn derive_with_existing_derives() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive(PartialEq, Eq, Or$0)] struct Test; +"#, + expect![[r#" + md core + de Default macro Default + de Clone, Copy + de PartialOrd, Ord + de Clone macro Clone + de PartialOrd + kw self:: + kw super:: + kw crate:: + "#]], + ); + } + #[test] fn derive_flyimport() { check_derive(