8
8
use crate :: generator:: functions_common:: FnCode ;
9
9
use crate :: generator:: { docs, functions_common} ;
10
10
use crate :: models:: domain:: {
11
- ApiView , Class , ClassLike , ClassMethod , FnQualifier , Function , TyName ,
11
+ ApiView , Class , ClassLike , ClassMethod , FnQualifier , Function , TyName , VirtualMethodPresence ,
12
12
} ;
13
13
use crate :: special_cases;
14
14
use crate :: util:: ident;
@@ -153,12 +153,20 @@ fn make_special_virtual_methods(notification_enum_name: &Ident) -> TokenStream {
153
153
154
154
fn make_virtual_method (
155
155
method : & ClassMethod ,
156
- override_is_required : Option < bool > ,
156
+ presence : VirtualMethodPresence ,
157
157
) -> Option < TokenStream > {
158
158
if !method. is_virtual ( ) {
159
159
return None ;
160
160
}
161
161
162
+ // Possibly change behavior of required/optional-ness of the virtual method in derived classes.
163
+ // It's also possible that it's removed, which would not declare it at all in the `I*` trait.
164
+ let is_virtual_required = match presence {
165
+ VirtualMethodPresence :: Inherit => method. is_virtual_required ( ) ,
166
+ VirtualMethodPresence :: Override { is_required } => is_required,
167
+ VirtualMethodPresence :: Remove => return None ,
168
+ } ;
169
+
162
170
// Virtual methods are never static.
163
171
let qualifier = method. qualifier ( ) ;
164
172
assert ! ( matches!( qualifier, FnQualifier :: Mut | FnQualifier :: Const ) ) ;
@@ -170,8 +178,7 @@ fn make_virtual_method(
170
178
// make_return() requests following args, but they are not used for virtual methods. We can provide empty streams.
171
179
varcall_invocation : TokenStream :: new ( ) ,
172
180
ptrcall_invocation : TokenStream :: new ( ) ,
173
- is_virtual_required : override_is_required
174
- . unwrap_or_else ( || method. is_virtual_required ( ) ) ,
181
+ is_virtual_required,
175
182
is_varcall_fallible : true ,
176
183
} ,
177
184
None ,
@@ -191,7 +198,7 @@ fn make_all_virtual_methods(
191
198
192
199
for method in class. methods . iter ( ) {
193
200
// Assumes that inner function filters on is_virtual.
194
- if let Some ( tokens) = make_virtual_method ( method, None ) {
201
+ if let Some ( tokens) = make_virtual_method ( method, VirtualMethodPresence :: Inherit ) {
195
202
all_tokens. push ( tokens) ;
196
203
}
197
204
}
@@ -201,14 +208,17 @@ fn make_all_virtual_methods(
201
208
for method in base_class. methods . iter ( ) {
202
209
// Certain derived classes in Godot implement a virtual method declared in a base class, thus no longer
203
210
// making it required. This isn't advertised in the extension_api, but instead manually tracked via special cases.
204
- let is_required =
205
- special_cases:: is_derived_virtual_method_required ( class. name ( ) , method. name ( ) ) ;
211
+ let derived_presence =
212
+ special_cases:: get_derived_virtual_method_presence ( class. name ( ) , method. name ( ) ) ;
206
213
207
- if let Some ( tokens) = make_virtual_method ( method, is_required ) {
214
+ if let Some ( tokens) = make_virtual_method ( method, derived_presence ) {
208
215
all_tokens. push ( tokens) ;
209
216
}
210
217
}
211
218
}
212
219
213
220
all_tokens
214
221
}
222
+
223
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
224
+ // Helper types
0 commit comments