@@ -5,7 +5,6 @@ use itertools::Itertools;
5
5
use syntax:: {
6
6
ast:: { self , make, AstNode , NameOwner } ,
7
7
SyntaxKind :: { IDENT , WHITESPACE } ,
8
- TextSize ,
9
8
} ;
10
9
11
10
use crate :: {
@@ -43,32 +42,23 @@ pub(crate) fn replace_derive_with_manual_impl(
43
42
ctx : & AssistContext ,
44
43
) -> Option < ( ) > {
45
44
let attr = ctx. find_node_at_offset :: < ast:: Attr > ( ) ?;
46
-
47
- let has_derive = attr
48
- . syntax ( )
49
- . descendants_with_tokens ( )
50
- . filter ( |t| t. kind ( ) == IDENT )
51
- . find_map ( syntax:: NodeOrToken :: into_token)
52
- . filter ( |t| t. text ( ) == "derive" )
53
- . is_some ( ) ;
54
- if !has_derive {
45
+ let ( name, args) = attr. as_simple_call ( ) ?;
46
+ if name != "derive" {
55
47
return None ;
56
48
}
57
49
58
- let trait_token = ctx . token_at_offset ( ) . find ( |t| t. kind ( ) == IDENT && t . text ( ) != "derive" ) ?;
59
- let trait_path = make :: path_unqualified ( make :: path_segment ( make :: name_ref ( trait_token. text ( ) ) ) ) ;
50
+ let trait_token = args . syntax ( ) . token_at_offset ( ctx . offset ( ) ) . find ( |t| t. kind ( ) == IDENT ) ?;
51
+ let trait_name = trait_token. text ( ) ;
60
52
61
53
let adt = attr. syntax ( ) . parent ( ) . and_then ( ast:: Adt :: cast) ?;
62
- let annotated_name = adt. name ( ) ?;
63
- let insert_pos = adt. syntax ( ) . text_range ( ) . end ( ) ;
64
54
65
- let current_module = ctx. sema . scope ( annotated_name . syntax ( ) ) . module ( ) ?;
55
+ let current_module = ctx. sema . scope ( adt . syntax ( ) ) . module ( ) ?;
66
56
let current_crate = current_module. krate ( ) ;
67
57
68
58
let found_traits = items_locator:: items_with_name (
69
59
& ctx. sema ,
70
60
current_crate,
71
- NameToImport :: Exact ( trait_token . text ( ) . to_string ( ) ) ,
61
+ NameToImport :: Exact ( trait_name . to_string ( ) ) ,
72
62
items_locator:: AssocItemSearch :: Exclude ,
73
63
Some ( items_locator:: DEFAULT_QUERY_SEARCH_LIMIT ) ,
74
64
)
@@ -86,10 +76,11 @@ pub(crate) fn replace_derive_with_manual_impl(
86
76
87
77
let mut no_traits_found = true ;
88
78
for ( trait_path, trait_) in found_traits. inspect ( |_| no_traits_found = false ) {
89
- add_assist ( acc, ctx, & attr, & trait_path, Some ( trait_) , & adt, & annotated_name , insert_pos ) ?;
79
+ add_assist ( acc, ctx, & attr, & args , & trait_path, Some ( trait_) , & adt) ?;
90
80
}
91
81
if no_traits_found {
92
- add_assist ( acc, ctx, & attr, & trait_path, None , & adt, & annotated_name, insert_pos) ?;
82
+ let trait_path = make:: path_unqualified ( make:: path_segment ( make:: name_ref ( trait_name) ) ) ;
83
+ add_assist ( acc, ctx, & attr, & args, & trait_path, None , & adt) ?;
93
84
}
94
85
Some ( ( ) )
95
86
}
@@ -98,24 +89,24 @@ fn add_assist(
98
89
acc : & mut Assists ,
99
90
ctx : & AssistContext ,
100
91
attr : & ast:: Attr ,
92
+ input : & ast:: TokenTree ,
101
93
trait_path : & ast:: Path ,
102
94
trait_ : Option < hir:: Trait > ,
103
95
adt : & ast:: Adt ,
104
- annotated_name : & ast:: Name ,
105
- insert_pos : TextSize ,
106
96
) -> Option < ( ) > {
107
97
let target = attr. syntax ( ) . text_range ( ) ;
108
- let input = attr . token_tree ( ) ?;
109
- let label = format ! ( "Convert to manual `impl {} for {}`" , trait_path, annotated_name) ;
98
+ let annotated_name = adt . name ( ) ?;
99
+ let label = format ! ( "Convert to manual `impl {} for {}`" , trait_path, annotated_name) ;
110
100
let trait_name = trait_path. segment ( ) . and_then ( |seg| seg. name_ref ( ) ) ?;
111
101
112
102
acc. add (
113
103
AssistId ( "replace_derive_with_manual_impl" , AssistKind :: Refactor ) ,
114
104
label,
115
105
target,
116
106
|builder| {
107
+ let insert_pos = adt. syntax ( ) . text_range ( ) . end ( ) ;
117
108
let impl_def_with_items =
118
- impl_def_from_trait ( & ctx. sema , annotated_name, trait_, trait_path) ;
109
+ impl_def_from_trait ( & ctx. sema , & annotated_name, trait_, trait_path) ;
119
110
update_attribute ( builder, & input, & trait_name, & attr) ;
120
111
let trait_path = format ! ( "{}" , trait_path) ;
121
112
match ( ctx. config . snippet_cap , impl_def_with_items) {
0 commit comments