@@ -61,6 +61,7 @@ pub(crate) fn extract_struct_from_function_signature(
61
61
Some ( make:: record_field (
62
62
fn_ast. visibility ( ) ,
63
63
param. pat ( ) . and_then ( pat_to_name) ?,
64
+ // TODO: how are we going to handle references without explicit lifetimes
64
65
param. ty ( ) ?,
65
66
) )
66
67
} )
@@ -72,23 +73,27 @@ pub(crate) fn extract_struct_from_function_signature(
72
73
"Extract struct from signature of a function" ,
73
74
target,
74
75
|builder| {
76
+ // TODO: update calls to the function
75
77
let fn_ast = builder. make_mut ( fn_ast) ;
78
+ let params = builder. make_mut ( params) ;
76
79
tracing:: info!( "extract_struct_from_function_signature: starting edit" ) ;
77
80
builder. edit_file ( ctx. vfs_file_id ( ) ) ;
78
81
tracing:: info!( "extract_struct_from_function_signature: editing main file" ) ;
79
82
80
83
let generic_params = fn_ast
81
84
. generic_param_list ( )
82
- . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
85
+ . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
83
86
tracing:: info!( "extract_struct_from_function_signature: collecting generics" ) ;
84
87
let generics = generic_params. as_ref ( ) . map ( |generics| generics. clone_for_update ( ) ) ;
85
88
86
89
// 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
90
+ // we would get a query error from salsa, if we would use the field_list
91
+ // I think it is because the field list is
92
+ // constructed in new generation.
93
+ // So I do the resolving while its still param list
94
+ // and then apply it into record list after
90
95
let field_list = if let Some ( ( target_scope, source_scope) ) =
91
- ctx. sema . scope ( fn_ast. syntax ( ) ) . zip ( ctx. sema . scope ( field_list . syntax ( ) ) )
96
+ ctx. sema . scope ( fn_ast. syntax ( ) ) . zip ( ctx. sema . scope ( params . syntax ( ) ) )
92
97
{
93
98
let field_list = field_list. reset_indent ( ) ;
94
99
let field_list =
@@ -118,10 +123,44 @@ pub(crate) fn extract_struct_from_function_signature(
118
123
] ,
119
124
) ;
120
125
tracing:: info!( "extract_struct_from_function_signature: inserting struct {def}" ) ;
126
+ update_function ( name, & fn_ast, generic_params. map ( |g| g. clone_for_update ( ) ) ) ;
121
127
} ,
122
128
)
123
129
}
124
130
131
+ fn update_function (
132
+ name : ast:: Name ,
133
+ fn_ast : & ast:: Fn ,
134
+ generics : Option < ast:: GenericParamList > ,
135
+ ) -> Option < ( ) > {
136
+ let generic_args = generics
137
+ . filter ( |generics| generics. generic_params ( ) . count ( ) > 0 )
138
+ . map ( |generics| generics. to_generic_args ( ) ) ;
139
+ // FIXME: replace with a `ast::make` constructor
140
+ let ty = match generic_args {
141
+ Some ( generic_args) => make:: ty ( & format ! ( "{name}{generic_args}" ) ) ,
142
+ None => make:: ty ( & name. text ( ) ) ,
143
+ } ;
144
+
145
+ let param = make:: param (
146
+ // TODO: do we want to destructure the struct
147
+ ast:: Pat :: IdentPat ( make:: ident_pat (
148
+ false ,
149
+ fn_ast. param_list ( ) ?. params ( ) . any ( |p| {
150
+ p. pat ( )
151
+ . is_some_and ( |p| matches ! ( p, ast:: Pat :: IdentPat ( p) if p. mut_token( ) . is_some( ) ) )
152
+ } ) ,
153
+ name,
154
+ ) ) ,
155
+ ty,
156
+ ) ;
157
+ // TODO: will eventually need to handle self to
158
+ let param_list = make:: param_list ( None , std:: iter:: once ( param) ) . clone_for_update ( ) ;
159
+ ted:: replace ( fn_ast. param_list ( ) ?. syntax ( ) , param_list. syntax ( ) ) ;
160
+ // TODO: update uses of parameters in function, if we do not destructure
161
+ Some ( ( ) )
162
+ }
163
+
125
164
fn pat_to_name ( pat : ast:: Pat ) -> Option < ast:: Name > {
126
165
match pat {
127
166
ast:: Pat :: IdentPat ( ident_pat) => ident_pat. name ( ) ,
0 commit comments