derive completions take existing derives into count

This commit is contained in:
XFFXFF 2022-04-18 21:34:36 +08:00
parent d1f6b4e2a0
commit fedd0245d1
2 changed files with 31 additions and 11 deletions

View File

@ -523,7 +523,8 @@ fn expand_and_fill(
// successful expansions // successful expansions
(Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => { (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
let new_offset = fake_mapped_token.text_range().start(); 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; break 'expansion;
} }
// exactly one expansion failed, inconsistent state so stop expanding completely // exactly one expansion failed, inconsistent state so stop expanding completely
@ -718,7 +719,7 @@ fn fill(
original_file: &SyntaxNode, original_file: &SyntaxNode,
file_with_fake_ident: SyntaxNode, file_with_fake_ident: SyntaxNode,
offset: TextSize, 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 fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
let syntax_element = NodeOrToken::Token(fake_ident_token); let syntax_element = NodeOrToken::Token(fake_ident_token);
@ -742,16 +743,14 @@ fn fill(
(self.expected_type, self.expected_name) = self.expected_type_and_name(); (self.expected_type, self.expected_name) = self.expected_type_and_name();
// Overwrite the path kind for derives // Overwrite the path kind for derives
if let Some((original_file, file_with_fake_ident, offset)) = derive_ctx { if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx {
let attr = self self.existing_derives = self
.sema .sema
.token_ancestors_with_macros(self.token.clone()) .resolve_derive_macro(&origin_attr)
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) .into_iter()
.find_map(ast::Attr::cast); .flatten()
if let Some(attr) = &attr { .flatten()
self.existing_derives = .collect();
self.sema.resolve_derive_macro(attr).into_iter().flatten().flatten().collect();
}
if let Some(ast::NameLike::NameRef(name_ref)) = if let Some(ast::NameLike::NameRef(name_ref)) =
find_node_at_offset(&file_with_fake_ident, offset) find_node_at_offset(&file_with_fake_ident, offset)

View File

@ -747,6 +747,27 @@ fn derive_with_input_after() {
); );
} }
#[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] #[test]
fn derive_flyimport() { fn derive_flyimport() {
check_derive( check_derive(