@@ -56,26 +56,23 @@ impl ModuleKind {
56
56
}
57
57
58
58
pub ( crate ) fn parse ( mut input : ItemFn ) -> syn:: Result < StarModule > {
59
- let ( module_docstring, attrs) = parse_module_attributes ( & input) ?;
60
- let visibility = input. vis ;
61
- let sig_span = input. sig . span ( ) ;
62
- let name = input. sig . ident ;
59
+ let module_docstring = parse_module_docstring ( & input) ?;
63
60
64
61
if input. sig . inputs . len ( ) != 1 {
65
62
return Err ( syn:: Error :: new (
66
- sig_span ,
63
+ input . sig . span ( ) ,
67
64
"function must have exactly one argument" ,
68
65
) ) ;
69
66
}
70
- let arg = input. sig . inputs . pop ( ) . unwrap ( ) ;
67
+ let arg = input. sig . inputs . last_mut ( ) . unwrap ( ) ;
71
68
let arg_span = arg. span ( ) ;
72
69
73
- let ( ty , module_kind) = match arg. into_value ( ) {
74
- FnArg :: Typed ( PatType { ty, .. } ) if is_mut_globals_builder ( & ty) => {
75
- ( ty , ModuleKind :: Globals )
70
+ let ( pat , module_kind) = match arg {
71
+ FnArg :: Typed ( PatType { ty, pat , .. } ) if is_mut_globals_builder ( & ty) => {
72
+ ( pat , ModuleKind :: Globals )
76
73
}
77
- FnArg :: Typed ( PatType { ty, .. } ) if is_mut_methods_builder ( & ty) => {
78
- ( ty , ModuleKind :: Methods )
74
+ FnArg :: Typed ( PatType { ty, pat , .. } ) if is_mut_methods_builder ( & ty) => {
75
+ ( pat , ModuleKind :: Methods )
79
76
}
80
77
_ => {
81
78
return Err ( syn:: Error :: new (
@@ -84,19 +81,36 @@ pub(crate) fn parse(mut input: ItemFn) -> syn::Result<StarModule> {
84
81
) ) ;
85
82
}
86
83
} ;
84
+ // FIXME(JakobDegen): Pick one form and enforce it
85
+ let ( syn:: Pat :: Ident ( _) | syn:: Pat :: Wild ( _) ) = & mut * * pat else {
86
+ return Err ( syn:: Error :: new ( pat. span ( ) , "Expected ident" ) ) ;
87
+ } ;
88
+ // Replace the argument with a known one - the user can't depend on it anyway
89
+ * pat = Box :: new ( syn:: Pat :: Ident ( syn:: PatIdent {
90
+ attrs : Default :: default ( ) ,
91
+ by_ref : None ,
92
+ mutability : None ,
93
+ ident : syn:: Ident :: new ( "globals_builder" , pat. span ( ) ) ,
94
+ subpat : None ,
95
+ } ) ) ;
96
+
97
+ let stmts = std:: mem:: replace (
98
+ & mut input. block ,
99
+ Box :: new ( syn:: Block {
100
+ brace_token : Default :: default ( ) ,
101
+ stmts : Vec :: new ( ) ,
102
+ } ) ,
103
+ )
104
+ . stmts
105
+ . into_iter ( )
106
+ . map ( |stmt| parse_stmt ( stmt, module_kind) )
107
+ . collect :: < syn:: Result < _ > > ( ) ?;
108
+
87
109
Ok ( StarModule {
88
110
module_kind,
89
- visibility,
90
- globals_builder : * ty,
91
- name,
92
- attrs,
111
+ input,
93
112
docstring : module_docstring,
94
- stmts : input
95
- . block
96
- . stmts
97
- . into_iter ( )
98
- . map ( |stmt| parse_stmt ( stmt, module_kind) )
99
- . collect :: < syn:: Result < _ > > ( ) ?,
113
+ stmts,
100
114
} )
101
115
}
102
116
@@ -127,22 +141,18 @@ fn is_attribute_docstring(x: &Attribute) -> syn::Result<Option<String>> {
127
141
}
128
142
129
143
/// Return (docstring, other attributes)
130
- fn parse_module_attributes ( input : & ItemFn ) -> syn:: Result < ( Option < String > , Vec < Attribute > ) > {
144
+ fn parse_module_docstring ( input : & ItemFn ) -> syn:: Result < Option < String > > {
131
145
let mut doc_attrs = Vec :: new ( ) ;
132
- let mut attrs = Vec :: new ( ) ;
133
146
for attr in & input. attrs {
134
147
if let Some ( ds) = is_attribute_docstring ( attr) ? {
135
148
doc_attrs. push ( ds) ;
136
- } else {
137
- attrs. push ( attr. clone ( ) ) ;
138
149
}
139
150
}
140
- let docs = if doc_attrs. is_empty ( ) {
141
- None
151
+ if doc_attrs. is_empty ( ) {
152
+ Ok ( None )
142
153
} else {
143
- Some ( doc_attrs. join ( "\n " ) )
144
- } ;
145
- Ok ( ( docs, attrs) )
154
+ Ok ( Some ( doc_attrs. join ( "\n " ) ) )
155
+ }
146
156
}
147
157
148
158
fn parse_stmt ( stmt : Stmt , module_kind : ModuleKind ) -> syn:: Result < StarStmt > {
0 commit comments