@@ -51,6 +51,8 @@ pub(crate) fn extract_struct_from_function_signature(
51
51
// TODO: special handiling for self?
52
52
// TODO: special handling for destrutered types (or maybe just don't suppurt code action on
53
53
// destructed types yet
54
+ let params = fn_ast. param_list ( ) ?;
55
+
54
56
let field_list = make:: record_field_list (
55
57
fn_ast
56
58
. param_list ( ) ?
@@ -70,14 +72,21 @@ pub(crate) fn extract_struct_from_function_signature(
70
72
"Extract struct from signature of a function" ,
71
73
target,
72
74
|builder| {
75
+ let fn_ast = builder. make_mut ( fn_ast) ;
76
+ tracing:: info!( "extract_struct_from_function_signature: starting edit" ) ;
73
77
builder. edit_file ( ctx. vfs_file_id ( ) ) ;
78
+ tracing:: info!( "extract_struct_from_function_signature: editing main file" ) ;
74
79
75
80
let generic_params = fn_ast
76
81
. generic_param_list ( )
77
- . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
82
+ . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
83
+ tracing:: info!( "extract_struct_from_function_signature: collecting generics" ) ;
78
84
let generics = generic_params. as_ref ( ) . map ( |generics| generics. clone_for_update ( ) ) ;
79
85
80
86
// resolve GenericArg in field_list to actual type
87
+ // we are getting a query error from salsa, I think it is because the field list is
88
+ // constructed in new generation, so maybe do the resolving while its still param list
89
+ // and then convert it into record list after
81
90
let field_list = if let Some ( ( target_scope, source_scope) ) =
82
91
ctx. sema . scope ( fn_ast. syntax ( ) ) . zip ( ctx. sema . scope ( field_list. syntax ( ) ) )
83
92
{
@@ -94,8 +103,9 @@ pub(crate) fn extract_struct_from_function_signature(
94
103
} else {
95
104
field_list. clone_for_update ( )
96
105
} ;
97
-
98
- let def = create_struct_def ( name. clone ( ) , & fn_ast, & field_list, generics) ;
106
+ tracing:: info!( "extract_struct_from_function_signature: collecting fields" ) ;
107
+ let def = create_struct_def ( name. clone ( ) , & fn_ast, & params, & field_list, generics) ;
108
+ tracing:: info!( "extract_struct_from_function_signature: creating struct" ) ;
99
109
100
110
let indent = fn_ast. indent_level ( ) ;
101
111
let def = def. indent ( indent) ;
@@ -107,6 +117,7 @@ pub(crate) fn extract_struct_from_function_signature(
107
117
make:: tokens:: whitespace( & format!( "\n \n {indent}" ) ) . into( ) ,
108
118
] ,
109
119
) ;
120
+ tracing:: info!( "extract_struct_from_function_signature: inserting struct {def}" ) ;
110
121
} ,
111
122
)
112
123
}
@@ -120,6 +131,7 @@ fn pat_to_name(pat: ast::Pat) -> Option<ast::Name> {
120
131
fn create_struct_def (
121
132
name : ast:: Name ,
122
133
fn_ast : & ast:: Fn ,
134
+ param_ast : & ast:: ParamList ,
123
135
field_list : & ast:: RecordFieldList ,
124
136
generics : Option < ast:: GenericParamList > ,
125
137
) -> ast:: Struct {
@@ -146,17 +158,19 @@ fn create_struct_def(
146
158
147
159
let strukt = make:: struct_ ( fn_vis, name, generics, field_list) . clone_for_update ( ) ;
148
160
149
- // take comments from variant
161
+ // take comments from only inside signature
150
162
ted:: insert_all (
151
163
ted:: Position :: first_child_of ( strukt. syntax ( ) ) ,
152
- take_all_comments ( fn_ast . syntax ( ) ) ,
164
+ take_all_comments ( param_ast . syntax ( ) ) ,
153
165
) ;
154
166
155
- // copy attributes from enum
167
+ // TODO: this may not be correct as we shouldn't put all the attributes at the top
168
+ // copy attributes from each parameter
156
169
ted:: insert_all (
157
170
ted:: Position :: first_child_of ( strukt. syntax ( ) ) ,
158
- fn_ast
159
- . attrs ( )
171
+ param_ast
172
+ . params ( )
173
+ . flat_map ( |p| p. attrs ( ) )
160
174
. flat_map ( |it| {
161
175
vec ! [ it. syntax( ) . clone_for_update( ) . into( ) , make:: tokens:: single_newline( ) . into( ) ]
162
176
} )
0 commit comments