@@ -45,6 +45,7 @@ pub fn generate_class_files(
45
45
own_notification_enum_name : generated_class. notification_enum . try_to_own_name ( ) ,
46
46
inherits_macro_ident : generated_class. inherits_macro_ident ,
47
47
is_pub_sidecar : generated_class. has_sidecar_module ,
48
+ has_interface_trait : generated_class. has_interface_trait ,
48
49
} ) ;
49
50
}
50
51
@@ -63,6 +64,7 @@ struct GeneratedClass {
63
64
inherits_macro_ident : Option < Ident > ,
64
65
/// Sidecars are the associated modules with related enum/flag types, such as `node_3d` for `Node3D` class.
65
66
has_sidecar_module : bool ,
67
+ has_interface_trait : bool ,
66
68
}
67
69
68
70
struct GeneratedClassModule {
@@ -71,6 +73,7 @@ struct GeneratedClassModule {
71
73
own_notification_enum_name : Option < Ident > ,
72
74
inherits_macro_ident : Option < Ident > ,
73
75
is_pub_sidecar : bool ,
76
+ has_interface_trait : bool ,
74
77
}
75
78
76
79
struct Construction {
@@ -86,7 +89,6 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
86
89
// Strings
87
90
let godot_class_str = & class_name. godot_ty ;
88
91
let class_name_cstr = util:: c_str ( godot_class_str) ;
89
- let virtual_trait_str = class_name. virtual_trait_name ( ) ;
90
92
91
93
// Idents and tokens
92
94
let ( base_ty, base_ident_opt) = match class. inherits . as_ref ( ) {
@@ -157,25 +159,33 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
157
159
// This checks if token streams (i.e. code) is empty.
158
160
let has_sidecar_module = !enums. is_empty ( ) || !builders. is_empty ( ) || has_own_signals;
159
161
162
+ let module_doc = docs:: make_module_doc ( class_name) ;
163
+
164
+ // Classes that can't be inherited from don't need to provide an interface with overridable virtual methods.
165
+ let has_interface_trait = !class. is_final ;
166
+ let interface_trait = if has_interface_trait {
167
+ let virtual_trait_str = class_name. virtual_trait_name ( ) ;
168
+ virtual_traits:: make_virtual_methods_trait (
169
+ class,
170
+ & all_bases,
171
+ & virtual_trait_str,
172
+ & notification_enum_name,
173
+ & cfg_attributes,
174
+ view,
175
+ )
176
+ } else {
177
+ TokenStream :: new ( )
178
+ } ;
179
+
160
180
let class_doc = docs:: make_class_doc (
161
181
class_name,
162
182
base_ident_opt,
163
183
notification_enum. is_some ( ) ,
164
184
has_sidecar_module,
185
+ has_interface_trait,
165
186
has_own_signals,
166
187
) ;
167
188
168
- let module_doc = docs:: make_module_doc ( class_name) ;
169
-
170
- let virtual_trait = virtual_traits:: make_virtual_methods_trait (
171
- class,
172
- & all_bases,
173
- & virtual_trait_str,
174
- & notification_enum_name,
175
- & cfg_attributes,
176
- view,
177
- ) ;
178
-
179
189
// notify() and notify_reversed() are added after other methods, to list others first in docs.
180
190
let notify_methods = notifications:: make_notify_methods ( class_name, ctx) ;
181
191
@@ -220,7 +230,7 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
220
230
// The RawGd<T>'s identity field can be None because of generality (it can represent null pointers, as opposed to Gd<T>).
221
231
rtti: Option <crate :: private:: ObjectRtti >,
222
232
}
223
- #virtual_trait
233
+ #interface_trait
224
234
#notification_enum
225
235
impl #class_name {
226
236
#constructor
@@ -274,6 +284,7 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
274
284
} ,
275
285
inherits_macro_ident,
276
286
has_sidecar_module,
287
+ has_interface_trait,
277
288
}
278
289
}
279
290
@@ -351,10 +362,14 @@ fn make_class_module_file(classes_and_modules: Vec<GeneratedClassModule>) -> Tok
351
362
352
363
let vis = is_pub. then_some ( quote ! { pub } ) ;
353
364
365
+ let interface_reexport = m. has_interface_trait . then ( || {
366
+ quote ! { pub use #module_name:: re_export:: #virtual_trait_name; }
367
+ } ) ;
368
+
354
369
let class_decl = quote ! {
355
370
#vis mod #module_name;
356
371
pub use #module_name:: re_export:: #class_name;
357
- pub use #module_name :: re_export :: #virtual_trait_name ;
372
+ #interface_reexport
358
373
} ;
359
374
class_decls. push ( class_decl) ;
360
375
@@ -452,7 +467,7 @@ fn make_constructor_and_default(class: &Class, ctx: &Context) -> Construction {
452
467
let final_doc = if class. is_final {
453
468
Some (
454
469
"\n \n # Final class\n \n \
455
- This class is _final_, meaning you cannot inherit from it.",
470
+ This class is _final_, meaning you cannot inherit from it, and it comes without `I*` interface trait .",
456
471
)
457
472
} else {
458
473
None
0 commit comments