11use proc_macro:: TokenStream ;
2- use proc_macro2:: { Ident , Span } ;
3- use quote:: quote;
4- use syn:: meta:: ParseNestedMeta ;
5- use syn:: { ItemFn , LitStr , Result , parse_macro_input} ;
2+
3+ mod module;
64
75#[ cfg( feature = "macros" ) ]
86use { crate :: chunk:: Chunk , proc_macro_error2:: proc_macro_error} ;
@@ -17,132 +15,16 @@ macro_rules! try_compile {
1715 } ;
1816}
1917
20- #[ derive( Default ) ]
21- struct ModuleAttributes {
22- name : Option < Ident > ,
23- skip_memory_check : bool ,
24- }
25-
26- impl ModuleAttributes {
27- fn parse ( & mut self , meta : ParseNestedMeta ) -> Result < ( ) > {
28- if meta. path . is_ident ( "name" ) {
29- match meta. value ( ) {
30- Ok ( value) => {
31- self . name = Some ( value. parse :: < LitStr > ( ) ?. parse ( ) ?) ;
32- }
33- Err ( _) => {
34- return Err ( meta. error ( "`name` attribute must have a value" ) ) ;
35- }
36- }
37- } else if meta. path . is_ident ( "skip_memory_check" ) {
38- if meta. value ( ) . is_ok ( ) {
39- return Err ( meta. error ( "`skip_memory_check` attribute have no values" ) ) ;
40- }
41- self . skip_memory_check = true ;
42- } else {
43- return Err ( meta. error ( "unsupported module attribute" ) ) ;
44- }
45- Ok ( ( ) )
46- }
47- }
48-
4918#[ proc_macro_attribute]
5019pub fn lua_module ( attr : TokenStream , item : TokenStream ) -> TokenStream {
51- let mut args = ModuleAttributes :: default ( ) ;
52- if !attr. is_empty ( ) {
53- let args_parser = syn:: meta:: parser ( |meta| args. parse ( meta) ) ;
54- parse_macro_input ! ( attr with args_parser) ;
55- }
56-
57- let func = parse_macro_input ! ( item as ItemFn ) ;
58- let func_name = & func. sig . ident ;
59- let module_name = args. name . unwrap_or_else ( || func_name. clone ( ) ) ;
60- let ext_entrypoint_name = Ident :: new ( & format ! ( "luaopen_{module_name}" ) , Span :: call_site ( ) ) ;
61- let skip_memory_check = if args. skip_memory_check {
62- quote ! { lua. skip_memory_check( true ) ; }
63- } else {
64- quote ! { }
65- } ;
66-
67- let wrapped = quote ! {
68- mlua:: require_module_feature!( ) ;
69-
70- #func
71-
72- #[ unsafe ( no_mangle) ]
73- unsafe extern "C-unwind" fn #ext_entrypoint_name( state: * mut mlua:: lua_State) -> :: std:: os:: raw:: c_int {
74- mlua:: Lua :: entrypoint1( state, move |lua| {
75- #skip_memory_check
76- #func_name( lua)
77- } )
78- }
79- } ;
80-
81- wrapped. into ( )
20+ module:: lua_module ( attr, item)
8221}
8322
8423#[ cfg( feature = "macros" ) ]
8524#[ proc_macro]
8625#[ proc_macro_error]
8726pub fn chunk ( input : TokenStream ) -> TokenStream {
88- let chunk = Chunk :: new ( input) ;
89-
90- let source = chunk. source ( ) ;
91-
92- let caps_len = chunk. captures ( ) . len ( ) ;
93- let caps = chunk. captures ( ) . iter ( ) . map ( |cap| {
94- let cap_name = cap. name ( ) ;
95- quote ! { env. raw_set( #cap_name, #cap) ?; }
96- } ) ;
97-
98- let wrapped_code = quote ! { {
99- use mlua:: { AsChunk , ChunkMode , Lua , Result , Table } ;
100- use :: std:: borrow:: Cow ;
101- use :: std:: cell:: Cell ;
102- use :: std:: io:: Result as IoResult ;
103-
104- struct InnerChunk <F : FnOnce ( & Lua ) -> Result <Table >>( Cell <Option <F >>) ;
105-
106- impl <F > AsChunk for InnerChunk <F >
107- where
108- F : FnOnce ( & Lua ) -> Result <Table >,
109- {
110- fn environment( & self , lua: & Lua ) -> Result <Option <Table >> {
111- if #caps_len > 0 {
112- if let Some ( make_env) = self . 0 . take( ) {
113- return make_env( lua) . map( Some ) ;
114- }
115- }
116- Ok ( None )
117- }
118-
119- fn mode( & self ) -> Option <ChunkMode > {
120- Some ( ChunkMode :: Text )
121- }
122-
123- fn source<' a>( & self ) -> IoResult <Cow <' a, [ u8 ] >> {
124- Ok ( Cow :: Borrowed ( ( #source) . as_bytes( ) ) )
125- }
126- }
127-
128- let make_env = move |lua: & Lua | -> Result <Table > {
129- let globals = lua. globals( ) ;
130- let env = lua. create_table( ) ?;
131- let meta = lua. create_table( ) ?;
132- meta. raw_set( "__index" , & globals) ?;
133- meta. raw_set( "__newindex" , & globals) ?;
134-
135- // Add captured variables
136- #( #caps) *
137-
138- env. set_metatable( Some ( meta) ) ?;
139- Ok ( env)
140- } ;
141-
142- InnerChunk ( Cell :: new( Some ( make_env) ) )
143- } } ;
144-
145- wrapped_code. into ( )
27+ Chunk :: new ( input) . expand ( ) . into ( )
14628}
14729
14830#[ cfg( feature = "macros" ) ]
@@ -162,18 +44,12 @@ pub fn userdata(attr: TokenStream, item: TokenStream) -> TokenStream {
16244#[ cfg( feature = "macros" ) ]
16345#[ proc_macro_attribute]
16446pub fn userdata_impl ( attr : TokenStream , item : TokenStream ) -> TokenStream {
165- userdata_impl:: userdata_impl ( attr, item)
47+ userdata :: userdata_impl:: userdata_impl ( attr, item)
16648}
16749
168- #[ cfg( feature = "macros" ) ]
169- mod attr;
17050#[ cfg( feature = "macros" ) ]
17151mod chunk;
17252#[ cfg( feature = "macros" ) ]
17353mod from_lua;
17454#[ cfg( feature = "macros" ) ]
175- mod token;
176- #[ cfg( feature = "macros" ) ]
17755mod userdata;
178- #[ cfg( feature = "macros" ) ]
179- mod userdata_impl;
0 commit comments