1
- use hir:: { Function , ModuleDef , Visibility } ;
1
+ use hir:: { Function , ModuleDef } ;
2
2
use ide_db:: { RootDatabase , assists:: AssistId , path_transform:: PathTransform } ;
3
3
use itertools:: Itertools ;
4
+ use stdx:: to_camel_case;
4
5
use syntax:: {
6
+ AstNode , SyntaxElement , SyntaxKind , SyntaxNode , T ,
5
7
ast:: {
6
- self , edit:: { AstNodeEdit , IndentLevel } , make, HasAttrs , HasGenericParams , HasName , HasVisibility
7
- } , match_ast, ted, AstNode , SyntaxElement , SyntaxKind , SyntaxNode , T
8
+ self , HasAttrs , HasGenericParams , HasName , HasVisibility ,
9
+ edit:: { AstNodeEdit , IndentLevel } ,
10
+ make,
11
+ } ,
12
+ match_ast, ted,
8
13
} ;
9
14
10
15
use crate :: { AssistContext , Assists } ;
@@ -50,10 +55,16 @@ pub(crate) fn extract_struct_from_function_signature(
50
55
fn_ast
51
56
. param_list ( ) ?
52
57
. params ( )
53
- . map ( |param| Some ( make:: record_field ( None , make:: name ( "todo" ) , param. ty ( ) ?) ) )
54
- . collect :: < Option < Vec < _ > > > ( ) ?
55
- . into_iter ( ) ,
58
+ . map ( |param| {
59
+ Some ( make:: record_field (
60
+ fn_ast. visibility ( ) ,
61
+ param. pat ( ) . and_then ( pat_to_name) ?,
62
+ param. ty ( ) ?,
63
+ ) )
64
+ } )
65
+ . collect :: < Option < Vec < _ > > > ( ) ?,
56
66
) ;
67
+ let name = make:: name ( & format ! ( "{}Struct" , to_camel_case( fn_name. text_non_mutable( ) ) ) ) ;
57
68
acc. add (
58
69
AssistId :: refactor_rewrite ( "extract_struct_from_function_signature" ) ,
59
70
"Extract struct from signature of a function" ,
@@ -84,8 +95,7 @@ pub(crate) fn extract_struct_from_function_signature(
84
95
field_list. clone_for_update ( )
85
96
} ;
86
97
87
- let def =
88
- create_struct_def ( fn_name. clone ( ) , & fn_ast, & field_list, generics) ;
98
+ let def = create_struct_def ( name. clone ( ) , & fn_ast, & field_list, generics) ;
89
99
90
100
let indent = fn_ast. indent_level ( ) ;
91
101
let def = def. indent ( indent) ;
@@ -100,13 +110,20 @@ pub(crate) fn extract_struct_from_function_signature(
100
110
} ,
101
111
)
102
112
}
113
+
114
+ fn pat_to_name ( pat : ast:: Pat ) -> Option < ast:: Name > {
115
+ match pat {
116
+ ast:: Pat :: IdentPat ( ident_pat) => ident_pat. name ( ) ,
117
+ _ => None ,
118
+ }
119
+ }
103
120
fn create_struct_def (
104
121
name : ast:: Name ,
105
122
fn_ast : & ast:: Fn ,
106
123
field_list : & ast:: RecordFieldList ,
107
124
generics : Option < ast:: GenericParamList > ,
108
125
) -> ast:: Struct {
109
- let enum_vis = fn_ast. visibility ( ) ;
126
+ let fn_vis = fn_ast. visibility ( ) ;
110
127
111
128
let insert_vis = |node : & ' _ SyntaxNode , vis : & ' _ SyntaxNode | {
112
129
let vis = vis. clone_for_update ( ) ;
@@ -115,7 +132,7 @@ fn create_struct_def(
115
132
116
133
// for fields without any existing visibility, use visibility of enum
117
134
let field_list: ast:: FieldList = {
118
- if let Some ( vis) = & enum_vis {
135
+ if let Some ( vis) = & fn_vis {
119
136
field_list
120
137
. fields ( )
121
138
. filter ( |field| field. visibility ( ) . is_none ( ) )
@@ -127,7 +144,7 @@ fn create_struct_def(
127
144
} ;
128
145
let field_list = field_list. indent ( IndentLevel :: single ( ) ) ;
129
146
130
- let strukt = make:: struct_ ( enum_vis , name, generics, field_list) . clone_for_update ( ) ;
147
+ let strukt = make:: struct_ ( fn_vis , name, generics, field_list) . clone_for_update ( ) ;
131
148
132
149
// take comments from variant
133
150
ted:: insert_all (
0 commit comments