pbni_codegen/lib.rs
1use proc_macro::TokenStream;
2use syn::{parse_macro_input, AttributeArgs};
3
4#[cfg(feature = "global_function")]
5mod global_function;
6
7#[cfg(any(feature = "nonvisualobject", feature = "visualobject"))]
8mod object;
9
10/// 生成全局函数
11///
12/// # Parameters
13/// - `name`: 映射的PB函数名 (默认为Rust函数名)
14///
15/// # Examples
16/// ```no_run
17/// #[global_function(name = "gf_bitor")]
18/// fn bit_or(session: Session, a: pblong, b: pblong) -> pblong { a | b }
19/// ```
20#[cfg(feature = "global_function")]
21#[proc_macro_attribute]
22pub fn global_function(args: TokenStream, input: TokenStream) -> TokenStream {
23 match global_function::gen(parse_macro_input!(args as AttributeArgs), input) {
24 Ok(stream) => stream,
25 Err(e) => e.to_compile_error().into()
26 }
27}
28
29/// 生成不可视对象
30///
31/// # Parameters
32///
33/// - `name`: 映射的PB对象类名 (默认为Rust对象名)
34/// - `inherit`: 继承的对象 (此对象的字段)
35///
36/// # Notice
37///
38/// 继承模式不支持覆盖(override)方法实现,并且在PB端需要将父类的方法声明在子类中重新声明
39///
40/// # Examples
41///
42/// - PowerBuilder
43///
44/// ```vbscript
45/// /* 父类声明 */
46/// forward
47/// global type n_parent from nonvisualobject
48/// end type
49/// end forward
50///
51/// global type n_parent from nonvisualobject native "pbrs.dll"
52/// public function string of_hello (string world)
53/// end type
54/// global n_parent n_parent
55///
56/// type variables
57/// end variables
58///
59/// on n_parent.create
60/// call super::create
61/// TriggerEvent( this, "constructor" )
62/// end on
63///
64/// on n_parent.destroy
65/// TriggerEvent( this, "destructor" )
66/// call super::destroy
67/// end on
68///
69/// /* 子类声明 */
70/// forward
71/// global type n_child from n_parent
72/// end type
73/// end forward
74///
75/// global type n_child from n_parent native "pbrs.dll"
76/// // 重新声明父类方法
77/// public function string of_hello (string world)
78/// // 声明子类私有的方法
79/// public function string of_foo (string bar)
80/// end type
81/// global n_child n_child
82///
83/// type variables
84/// end variables
85///
86/// on n_child.create
87/// call super::create
88/// TriggerEvent( this, "constructor" )
89/// end on
90///
91/// on n_child.destroy
92/// TriggerEvent( this, "destructor" )
93/// call super::destroy
94/// end on
95/// ```
96///
97/// - Rust(pbni-rs)
98///
99/// ```no_run
100/// struct RustObject {
101/// session: Session,
102/// ctx: ContextObject
103/// }
104///
105/// #[nonvisualobject(name = "n_pbni")]
106/// impl RustObject {
107/// #[constructor]
108/// fn new(session: Session, ctx: ContextObject) -> RustObject {
109/// RustObject {
110/// session,
111/// ctx
112/// }
113/// }
114/// #[method(name="of_Hello")]
115/// fn hello(&self, world: String) -> String {
116/// format!("hello {}!",world)
117/// }
118/// }
119///
120/// struct RustChildObject {
121/// parent: RustObject
122/// }
123///
124/// #[nonvisualobject(name = "n_pbni_child", inherit = "parent")]
125/// impl RustChildObject {
126/// #[constructor]
127/// fn new(session: Session, ctx: ContextObject) -> RustChildObject {
128/// RustChildObject {
129/// parent : RustObject {
130/// session,
131/// ctx
132/// }
133/// }
134/// }
135/// #[method(name="of_Foo")]
136/// fn foo(&self, bar: String) -> String {
137/// format!("foo {}!",bar)
138/// }
139/// }
140/// ```
141#[cfg(feature = "nonvisualobject")]
142#[proc_macro_attribute]
143pub fn nonvisualobject(args: TokenStream, input: TokenStream) -> TokenStream {
144 match object::gen_nvo(parse_macro_input!(args as AttributeArgs), input) {
145 Ok(stream) => stream,
146 Err(e) => e.to_compile_error().into()
147 }
148}
149
150/// 生成可视对象
151///
152/// # Parameters
153///
154/// - `name`: 映射的PB对象类名 (默认为Rust对象名)
155/// - `inherit`: 继承的对象 (此对象的字段)
156///
157/// # Notice
158///
159/// 继承模式不支持覆盖(override)方法实现,并且在PB端需要将父类的方法声明在子类中重新声明,参见[`nonvisualobject`]说明
160///
161/// [`nonvisualobject`]: macro@nonvisualobject
162///
163/// # Examples
164///
165/// ```no_run
166/// struct RustObject {
167/// session: Session,
168/// ctx: ContextObject
169/// }
170///
171/// #[visualobject(name = "u_canvas")]
172/// impl RustObject {
173/// #[constructor]
174/// fn new(session: Session, ctx: ContextObject) -> RustObject {
175/// RustObject {
176/// session,
177/// ctx
178/// }
179/// }
180/// #[method(name="of_Hello")]
181/// fn hello(&self, world: String) -> String {
182/// format!("hello {}!",world)
183/// }
184/// }
185/// ```
186#[cfg(feature = "visualobject")]
187#[proc_macro_attribute]
188pub fn visualobject(args: TokenStream, input: TokenStream) -> TokenStream {
189 match object::gen_vo(parse_macro_input!(args as AttributeArgs), input) {
190 Ok(stream) => stream,
191 Err(e) => e.to_compile_error().into()
192 }
193}
194
195/// 标记对象的构造函数
196///
197/// # Examples
198///
199/// ```no_run
200/// #[constructor]
201/// fn new(session: Session, ctx: ContextObject) -> RustObject {
202/// RustObject {
203/// session,
204/// ctx
205/// }
206/// }
207/// ```
208#[cfg(any(feature = "nonvisualobject", feature = "visualobject"))]
209#[proc_macro_attribute]
210pub fn constructor(_: TokenStream, input: TokenStream) -> TokenStream { input }
211
212/// 标记对象函数
213///
214/// # Parameters
215///
216/// - `name`: 映射的PB函数类名 (默认为Rust函数名)
217/// - `overload`: 重载次数 (默认0,意为没有重载)
218///
219/// # Examples
220///
221/// ```no_run
222/// #[method(name="of_Hello")]
223/// fn hello(&self, world: String) -> String {
224/// format!("hello {}!",world)
225/// }
226/// ```
227#[cfg(any(feature = "nonvisualobject", feature = "visualobject"))]
228#[proc_macro_attribute]
229pub fn method(_: TokenStream, input: TokenStream) -> TokenStream { input }
230
231/// 标记对象事件,如果方法体没有代码,则自动生成对应的调用代码
232///
233/// # Parameters
234///
235/// - `name`: 映射的PB事件名 (默认为Rust函数名)
236///
237/// # Required
238///
239/// 自动生成事件代码,需要对象实现`context_mut`方法:
240///
241/// # Examples
242///
243/// ```no_run
244/// struct RustObject {
245/// session: Session,
246/// ctx: ContextObject
247/// }
248///
249/// impl RustObject {
250/// fn context_mut(&mut self) -> &mut ContextObject { &mut self.ctx }
251/// }
252///
253/// #[nonvisualobject(name = "n_pbni")]
254/// impl RustObject {
255/// #[constructor]
256/// fn new(session: Session, ctx: ContextObject) -> RustObject {
257/// RustObject {
258/// session,
259/// ctx
260/// }
261/// }
262/// #[event(name="onFire")]
263/// fn on_fire(&mut self) {}
264/// }
265/// ```
266#[cfg(any(feature = "nonvisualobject", feature = "visualobject"))]
267#[proc_macro_attribute]
268pub fn event(args: TokenStream, input: TokenStream) -> TokenStream {
269 match object::gen_event(parse_macro_input!(args as AttributeArgs), input) {
270 Ok(stream) => stream,
271 Err(e) => e.to_compile_error().into()
272 }
273}