|
1 | 1 | use super::Diagnostic;
|
2 | 2 | use crate::util::{def_to_name, ItemIdent, ItemMeta};
|
3 | 3 | use proc_macro2::{Span, TokenStream as TokenStream2};
|
4 |
| -use quote::{quote, quote_spanned}; |
| 4 | +use quote::{quote, quote_spanned, ToTokens}; |
5 | 5 | use std::collections::HashSet;
|
6 | 6 | use syn::{parse_quote, spanned::Spanned, Attribute, AttributeArgs, Ident, Item, Meta, NestedMeta};
|
7 | 7 |
|
@@ -156,62 +156,57 @@ fn extract_module_items(mut items: Vec<ItemIdent>) -> Result<TokenStream2, Diagn
|
156 | 156 | }
|
157 | 157 |
|
158 | 158 | pub fn impl_pymodule(attr: AttributeArgs, item: Item) -> Result<TokenStream2, Diagnostic> {
|
159 |
| - match item { |
160 |
| - Item::Mod(mut module) => { |
161 |
| - let module_name = def_to_name(&module.ident, "pymodule", attr)?; |
162 |
| - |
163 |
| - if let Some(content) = module.content.as_mut() { |
164 |
| - let items = content |
165 |
| - .1 |
166 |
| - .iter_mut() |
167 |
| - .filter_map(|item| match item { |
168 |
| - Item::Fn(syn::ItemFn { attrs, sig, .. }) => Some(ItemIdent { |
169 |
| - attrs, |
170 |
| - ident: &sig.ident, |
171 |
| - }), |
172 |
| - Item::Struct(syn::ItemStruct { attrs, ident, .. }) => { |
173 |
| - Some(ItemIdent { attrs, ident }) |
174 |
| - } |
175 |
| - Item::Enum(syn::ItemEnum { attrs, ident, .. }) => { |
176 |
| - Some(ItemIdent { attrs, ident }) |
177 |
| - } |
178 |
| - _ => None, |
179 |
| - }) |
180 |
| - .collect(); |
181 |
| - |
182 |
| - let extend_mod = extract_module_items(items)?; |
183 |
| - content.1.push(parse_quote! { |
184 |
| - const MODULE_NAME: &str = #module_name; |
185 |
| - }); |
186 |
| - content.1.push(parse_quote! { |
187 |
| - pub(crate) fn extend_module( |
188 |
| - vm: &::rustpython_vm::vm::VirtualMachine, |
189 |
| - module: &::rustpython_vm::pyobject::PyObjectRef, |
190 |
| - ) { |
191 |
| - #extend_mod |
192 |
| - } |
193 |
| - }); |
194 |
| - content.1.push(parse_quote! { |
195 |
| - #[allow(dead_code)] |
196 |
| - pub(crate) fn make_module( |
197 |
| - vm: &::rustpython_vm::vm::VirtualMachine |
198 |
| - ) -> ::rustpython_vm::pyobject::PyObjectRef { |
199 |
| - let module = vm.new_module(MODULE_NAME, vm.ctx.new_dict()); |
200 |
| - extend_module(vm, &module); |
201 |
| - module |
202 |
| - } |
203 |
| - }); |
204 |
| - |
205 |
| - Ok(quote! { |
206 |
| - #module |
207 |
| - }) |
208 |
| - } else { |
209 |
| - bail_span!( |
210 |
| - module, |
211 |
| - "#[pymodule] can only be on a module declaration with body" |
212 |
| - ) |
213 |
| - } |
214 |
| - } |
| 159 | + let mut module = match item { |
| 160 | + Item::Mod(m) => m, |
215 | 161 | other => bail_span!(other, "#[pymodule] can only be on a module declaration"),
|
216 |
| - } |
| 162 | + }; |
| 163 | + let module_name = def_to_name(&module.ident, "pymodule", attr)?; |
| 164 | + |
| 165 | + let (_, content) = match module.content.as_mut() { |
| 166 | + Some(c) => c, |
| 167 | + None => bail_span!( |
| 168 | + module, |
| 169 | + "#[pymodule] can only be on a module declaration with body" |
| 170 | + ), |
| 171 | + }; |
| 172 | + |
| 173 | + let items = content |
| 174 | + .iter_mut() |
| 175 | + .filter_map(|item| match item { |
| 176 | + Item::Fn(syn::ItemFn { attrs, sig, .. }) => Some(ItemIdent { |
| 177 | + attrs, |
| 178 | + ident: &sig.ident, |
| 179 | + }), |
| 180 | + Item::Struct(syn::ItemStruct { attrs, ident, .. }) => Some(ItemIdent { attrs, ident }), |
| 181 | + Item::Enum(syn::ItemEnum { attrs, ident, .. }) => Some(ItemIdent { attrs, ident }), |
| 182 | + _ => None, |
| 183 | + }) |
| 184 | + .collect(); |
| 185 | + |
| 186 | + let extend_mod = extract_module_items(items)?; |
| 187 | + content.extend(vec![ |
| 188 | + parse_quote! { |
| 189 | + const MODULE_NAME: &str = #module_name; |
| 190 | + }, |
| 191 | + parse_quote! { |
| 192 | + pub(crate) fn extend_module( |
| 193 | + vm: &::rustpython_vm::vm::VirtualMachine, |
| 194 | + module: &::rustpython_vm::pyobject::PyObjectRef, |
| 195 | + ) { |
| 196 | + #extend_mod |
| 197 | + } |
| 198 | + }, |
| 199 | + parse_quote! { |
| 200 | + #[allow(dead_code)] |
| 201 | + pub(crate) fn make_module( |
| 202 | + vm: &::rustpython_vm::vm::VirtualMachine |
| 203 | + ) -> ::rustpython_vm::pyobject::PyObjectRef { |
| 204 | + let module = vm.new_module(MODULE_NAME, vm.ctx.new_dict()); |
| 205 | + extend_module(vm, &module); |
| 206 | + module |
| 207 | + } |
| 208 | + }, |
| 209 | + ]); |
| 210 | + |
| 211 | + Ok(module.into_token_stream()) |
217 | 212 | }
|
0 commit comments