Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/mono/editor/bindings_generator.h
10278 views
1
/**************************************************************************/
2
/* bindings_generator.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#ifdef DEBUG_ENABLED
34
35
#include "core/doc_data.h"
36
#include "core/object/class_db.h"
37
#include "core/string/string_builder.h"
38
#include "core/string/ustring.h"
39
#include "core/typedefs.h"
40
#include "editor/doc/doc_tools.h"
41
#include "editor/doc/editor_help.h"
42
43
class BindingsGenerator {
44
struct ConstantInterface {
45
String name;
46
String proxy_name;
47
int64_t value = 0;
48
const DocData::ConstantDoc *const_doc = nullptr;
49
50
bool is_deprecated = false;
51
String deprecation_message;
52
53
ConstantInterface() {}
54
55
ConstantInterface(const String &p_name, const String &p_proxy_name, int64_t p_value) {
56
name = p_name;
57
proxy_name = p_proxy_name;
58
value = p_value;
59
}
60
};
61
62
struct EnumInterface {
63
StringName cname;
64
String proxy_name;
65
List<ConstantInterface> constants;
66
bool is_flags = false;
67
68
_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
69
return p_ienum.cname == cname;
70
}
71
72
EnumInterface() {}
73
74
EnumInterface(const StringName &p_cname, const String &p_proxy_name, bool p_is_flags) {
75
cname = p_cname;
76
proxy_name = p_proxy_name;
77
is_flags = p_is_flags;
78
}
79
};
80
81
struct PropertyInterface {
82
StringName cname;
83
String proxy_name;
84
int index = 0;
85
86
StringName setter;
87
StringName getter;
88
89
/**
90
* Determines if the property will be hidden with the [EditorBrowsable(EditorBrowsableState.Never)]
91
* attribute.
92
* We do this for propertyies that have the PROPERTY_USAGE_INTERNAL flag, because they are not meant
93
* to be exposed to scripting but we can't remove them to prevent breaking compatibility.
94
*/
95
bool is_hidden = false;
96
97
const DocData::PropertyDoc *prop_doc;
98
99
bool is_deprecated = false;
100
String deprecation_message;
101
};
102
103
struct TypeReference {
104
StringName cname;
105
bool is_enum = false;
106
107
List<TypeReference> generic_type_parameters;
108
109
TypeReference() {}
110
111
TypeReference(const StringName &p_cname) :
112
cname(p_cname) {}
113
};
114
115
struct ArgumentInterface {
116
enum DefaultParamMode {
117
CONSTANT,
118
NULLABLE_VAL,
119
NULLABLE_REF
120
};
121
122
TypeReference type;
123
124
String name;
125
126
Variant def_param_value;
127
DefaultParamMode def_param_mode = CONSTANT;
128
129
/**
130
* Determines the expression for the parameter default value.
131
* Formatting elements:
132
* %0 or %s: [cs_type] of the argument type
133
*/
134
String default_argument;
135
136
ArgumentInterface() {}
137
};
138
139
struct MethodInterface {
140
String name;
141
StringName cname;
142
143
/**
144
* Name of the C# method
145
*/
146
String proxy_name;
147
148
/**
149
* Hash of the ClassDB method
150
*/
151
uint64_t hash = 0;
152
153
/**
154
* [TypeInterface::name] of the return type
155
*/
156
TypeReference return_type;
157
158
/**
159
* Determines if the method has a variable number of arguments (VarArg)
160
*/
161
bool is_vararg = false;
162
163
/**
164
* Determines if the method is static.
165
*/
166
bool is_static = false;
167
168
/**
169
* Virtual methods ("virtual" as defined by the Godot API) are methods that by default do nothing,
170
* but can be overridden by the user to add custom functionality.
171
* e.g.: _ready, _process, etc.
172
*/
173
bool is_virtual = false;
174
175
/**
176
* Determines if the call should fallback to Godot's object.Call(string, params) in C#.
177
*/
178
bool requires_object_call = false;
179
180
/**
181
* Determines if the method visibility is 'internal' (visible only to files in the same assembly).
182
* Currently, we only use this for methods that are not meant to be exposed,
183
* but are required by properties as getters or setters.
184
* Methods that are not meant to be exposed are those that begin with underscore and are not virtual.
185
*/
186
bool is_internal = false;
187
188
/**
189
* Determines if the method will be hidden with the [EditorBrowsable(EditorBrowsableState.Never)]
190
* attribute.
191
* We do this for methods that we don't want to expose but need to be public to prevent breaking
192
* compat (i.e: methods with 'is_compat' set to true.)
193
*/
194
bool is_hidden = false;
195
196
/**
197
* Determines if the method is a compatibility method added to avoid breaking binary compatibility.
198
* These methods will be generated but hidden and are considered deprecated.
199
*/
200
bool is_compat = false;
201
202
List<ArgumentInterface> arguments;
203
204
const DocData::MethodDoc *method_doc = nullptr;
205
206
bool is_deprecated = false;
207
String deprecation_message;
208
209
void add_argument(const ArgumentInterface &argument) {
210
arguments.push_back(argument);
211
}
212
213
MethodInterface() {}
214
};
215
216
struct SignalInterface {
217
String name;
218
StringName cname;
219
220
/**
221
* Name of the C# method
222
*/
223
String proxy_name;
224
225
List<ArgumentInterface> arguments;
226
227
const DocData::MethodDoc *method_doc = nullptr;
228
229
bool is_deprecated = false;
230
String deprecation_message;
231
232
void add_argument(const ArgumentInterface &argument) {
233
arguments.push_back(argument);
234
}
235
236
SignalInterface() {}
237
};
238
239
struct TypeInterface {
240
/**
241
* Identifier name for this type.
242
* Also used to format [c_out].
243
*/
244
String name;
245
StringName cname;
246
247
int type_parameter_count = 0;
248
249
/**
250
* Identifier name of the base class.
251
*/
252
StringName base_name;
253
254
/**
255
* Name of the C# class
256
*/
257
String proxy_name;
258
259
ClassDB::APIType api_type = ClassDB::API_NONE;
260
261
bool is_enum = false;
262
bool is_object_type = false;
263
bool is_singleton = false;
264
bool is_singleton_instance = false;
265
bool is_ref_counted = false;
266
bool is_span_compatible = false;
267
268
/**
269
* Class is a singleton, but can't be declared as a static class as that would
270
* break backwards compatibility. As such, instead of going with a static class,
271
* we use the actual singleton pattern (private constructor with instance property),
272
* which doesn't break compatibility.
273
*/
274
bool is_compat_singleton = false;
275
276
/**
277
* Determines whether the native return value of this type must be disposed
278
* by the generated internal call (think of `godot_string`, whose destructor
279
* must be called). Some structs that are disposable may still disable this
280
* flag if the ownership is transferred.
281
*/
282
bool c_type_is_disposable_struct = false;
283
284
/**
285
* Determines whether the native return value of this type must be zero initialized
286
* before its address is passed to ptrcall. This is required for types whose destructor
287
* is called before being assigned the return value by `PtrToArg::encode`, e.g.:
288
* Array, Dictionary, String, StringName, Variant.
289
* It's not necessary to set this to `true` if [c_type_is_disposable_struct] is already `true`.
290
*/
291
bool c_ret_needs_default_initialization = false;
292
293
/**
294
* Used only by Object-derived types.
295
* Determines if this type is not abstract (incomplete).
296
* e.g.: CanvasItem cannot be instantiated.
297
*/
298
bool is_instantiable = false;
299
300
/**
301
* Used only by Object-derived types.
302
* Determines if the C# class owns the native handle and must free it somehow when disposed.
303
* e.g.: RefCounted types must notify when the C# instance is disposed, for proper refcounting.
304
*/
305
bool memory_own = false;
306
307
// !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
308
// !! When renaming those fields, make sure to rename their references in the comments
309
310
// --- C INTERFACE ---
311
312
/**
313
* One or more statements that transform the parameter before being passed as argument of a ptrcall.
314
* If the statement adds a local that must be passed as the argument instead of the parameter,
315
* the expression with the name of that local must be specified with [c_arg_in].
316
* Formatting elements:
317
* %0: [c_type] of the parameter
318
* %1: name of the parameter
319
* %2-4: reserved
320
* %5: indentation text
321
*/
322
String c_in;
323
324
/**
325
* One or more statements that transform the parameter before being passed as argument of a vararg call.
326
* If the statement adds a local that must be passed as the argument instead of the parameter,
327
* the name of that local must be specified with [c_arg_in].
328
* Formatting elements:
329
* %0: [c_type] of the parameter
330
* %1: name of the parameter
331
* %2-4: reserved
332
* %5: indentation text
333
*/
334
String c_in_vararg;
335
336
/**
337
* Determines the expression that will be passed as argument to ptrcall.
338
* By default the value equals the name of the parameter,
339
* this varies for types that require special manipulation via [c_in].
340
* Formatting elements:
341
* %0 or %s: name of the parameter
342
*/
343
String c_arg_in = "%s";
344
345
/**
346
* One or more statements that determine how a variable of this type is returned from a function.
347
* It must contain the return statement(s).
348
* Formatting elements:
349
* %0: [c_type_out] of the return type
350
* %1: name of the variable to be returned
351
* %2: [name] of the return type
352
* ---------------------------------------
353
* If [ret_as_byref_arg] is true, the format is different. Instead of using a return statement,
354
* the value must be assigned to a parameter. This type of this parameter is a pointer to [c_type_out].
355
* Formatting elements:
356
* %0: [c_type_out] of the return type
357
* %1: name of the variable to be returned
358
* %2: [name] of the return type
359
* %3-4: reserved
360
* %5: indentation text
361
*/
362
String c_out;
363
364
/**
365
* The actual expected type, as seen (in most cases) in Variant copy constructors
366
* Used for the type of the return variable and to format [c_in].
367
* The value must be the following depending of the type:
368
* Object-derived types: Object*
369
* Other types: [name]
370
* -- Exceptions --
371
* VarArg (fictitious type to represent variable arguments): Array
372
* float: double (because ptrcall only supports double)
373
* int: int64_t (because ptrcall only supports int64_t and uint64_t)
374
* RefCounted types override this for the type of the return variable: Ref<RefCounted>
375
*/
376
String c_type;
377
378
/**
379
* Determines the type used for parameters in function signatures.
380
*/
381
String c_type_in;
382
383
/**
384
* Determines the return type used for function signatures.
385
* Also used to construct a default value to return in case of errors,
386
* and to format [c_out].
387
*/
388
String c_type_out;
389
390
// --- C# INTERFACE ---
391
392
/**
393
* An expression that overrides the way the parameter is passed to the internal call.
394
* If empty, the parameter is passed as is.
395
* Formatting elements:
396
* %0: name of the parameter
397
* %1: [c_type] of the parameter
398
*/
399
String cs_in_expr;
400
bool cs_in_expr_is_unsafe = false;
401
402
/**
403
* One or more statements that transform the parameter before being passed to the internal call.
404
* If the statement adds a local that must be passed as the argument instead of the parameter,
405
* the expression with the name of that local must be specified with [cs_in_expr].
406
* Formatting elements:
407
* %0: [c_type] of the parameter
408
* %1: name of the parameter
409
* %2-4: reserved
410
* %5: indentation text
411
*/
412
String cs_in;
413
414
/**
415
* One or more statements that determine how a variable of this type is returned from a method.
416
* It must contain the return statement(s).
417
* Formatting elements:
418
* %0: internal method name
419
* %1: internal method call arguments without surrounding parenthesis
420
* %2: [cs_type] of the return type
421
* %3: [c_type_out] of the return type
422
* %4: reserved
423
* %5: indentation text
424
*/
425
String cs_out;
426
427
/**
428
* Type used for method signatures, both for parameters and the return type.
429
* Same as [proxy_name] except for variable arguments (VarArg) and collections (which include the namespace).
430
*/
431
String cs_type;
432
433
/**
434
* Formatting elements:
435
* %0: input expression of type `in godot_variant`
436
* %1: [cs_type] of this type
437
* %2: [name] of this type
438
*/
439
String cs_variant_to_managed;
440
441
/**
442
* Formatting elements:
443
* %0: input expression
444
* %1: [cs_type] of this type
445
* %2: [name] of this type
446
*/
447
String cs_managed_to_variant;
448
449
const DocData::ClassDoc *class_doc = nullptr;
450
451
bool is_deprecated = false;
452
String deprecation_message;
453
454
List<ConstantInterface> constants;
455
List<EnumInterface> enums;
456
List<PropertyInterface> properties;
457
List<MethodInterface> methods;
458
List<SignalInterface> signals_;
459
HashSet<String> ignored_members;
460
461
bool has_virtual_methods = false;
462
463
const MethodInterface *find_method_by_name(const StringName &p_cname) const {
464
for (const MethodInterface &E : methods) {
465
if (E.cname == p_cname) {
466
return &E;
467
}
468
}
469
470
return nullptr;
471
}
472
473
const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const {
474
for (const MethodInterface &E : methods) {
475
if (E.proxy_name == p_proxy_name) {
476
return &E;
477
}
478
}
479
480
return nullptr;
481
}
482
483
const PropertyInterface *find_property_by_name(const StringName &p_cname) const {
484
for (const PropertyInterface &E : properties) {
485
if (E.cname == p_cname) {
486
return &E;
487
}
488
}
489
490
return nullptr;
491
}
492
493
const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const {
494
for (const PropertyInterface &E : properties) {
495
if (E.proxy_name == p_proxy_name) {
496
return &E;
497
}
498
}
499
500
return nullptr;
501
}
502
503
const SignalInterface *find_signal_by_name(const StringName &p_cname) const {
504
for (const SignalInterface &E : signals_) {
505
if (E.cname == p_cname) {
506
return &E;
507
}
508
}
509
510
return nullptr;
511
}
512
513
const SignalInterface *find_signal_by_proxy_name(const String &p_proxy_name) const {
514
for (const SignalInterface &E : signals_) {
515
if (E.proxy_name == p_proxy_name) {
516
return &E;
517
}
518
}
519
520
return nullptr;
521
}
522
523
bool is_intentionally_ignored(const String &p_name) const {
524
return ignored_members.has(p_name);
525
}
526
527
private:
528
static DocData::ClassDoc *_get_type_doc(TypeInterface &itype) {
529
String doc_name = itype.name.begins_with("_") ? itype.name.substr(1) : itype.name;
530
return &EditorHelp::get_doc_data()->class_list[doc_name];
531
}
532
533
static void _init_value_type(TypeInterface &itype) {
534
if (itype.proxy_name.is_empty()) {
535
itype.proxy_name = itype.name;
536
}
537
538
itype.cs_type = itype.proxy_name;
539
itype.c_type = itype.cs_type;
540
itype.c_type_in = itype.cs_type + "*";
541
itype.c_type_out = itype.cs_type;
542
543
itype.class_doc = _get_type_doc(itype);
544
}
545
546
static void _init_object_type(TypeInterface &itype, ClassDB::APIType p_api_type) {
547
if (itype.proxy_name.is_empty()) {
548
itype.proxy_name = itype.name;
549
}
550
551
if (itype.proxy_name.begins_with("_")) {
552
itype.proxy_name = itype.proxy_name.substr(1);
553
}
554
555
itype.api_type = p_api_type;
556
itype.is_object_type = true;
557
558
itype.class_doc = _get_type_doc(itype);
559
}
560
561
public:
562
static TypeInterface create_value_type(const String &p_name, const String &p_proxy_name) {
563
TypeInterface itype;
564
itype.name = p_name;
565
itype.cname = p_name;
566
itype.proxy_name = p_proxy_name;
567
_init_value_type(itype);
568
return itype;
569
}
570
571
static TypeInterface create_value_type(const StringName &p_cname, const String &p_proxy_name) {
572
TypeInterface itype;
573
itype.name = p_cname;
574
itype.cname = p_cname;
575
itype.proxy_name = p_proxy_name;
576
_init_value_type(itype);
577
return itype;
578
}
579
580
static TypeInterface create_value_type(const String &p_name) {
581
TypeInterface itype;
582
itype.name = p_name;
583
itype.cname = p_name;
584
_init_value_type(itype);
585
return itype;
586
}
587
588
static TypeInterface create_value_type(const StringName &p_cname) {
589
TypeInterface itype;
590
itype.name = p_cname;
591
itype.cname = p_cname;
592
_init_value_type(itype);
593
return itype;
594
}
595
596
static TypeInterface create_object_type(const StringName &p_cname, const String &p_proxy_name, ClassDB::APIType p_api_type) {
597
TypeInterface itype;
598
itype.name = p_cname;
599
itype.cname = p_cname;
600
itype.proxy_name = p_proxy_name;
601
_init_object_type(itype, p_api_type);
602
return itype;
603
}
604
605
static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) {
606
TypeInterface itype;
607
itype.name = p_cname;
608
itype.cname = p_cname;
609
_init_object_type(itype, p_api_type);
610
return itype;
611
}
612
613
static void postsetup_enum_type(TypeInterface &r_enum_itype);
614
615
TypeInterface() {
616
static String default_cs_variant_to_managed = "VariantUtils.ConvertTo<%1>(%0)";
617
static String default_cs_managed_to_variant = "VariantUtils.CreateFrom<%1>(%0)";
618
cs_variant_to_managed = default_cs_variant_to_managed;
619
cs_managed_to_variant = default_cs_managed_to_variant;
620
}
621
};
622
623
struct InternalCall {
624
String name;
625
String unique_sig; // Unique signature to avoid duplicates in containers
626
bool editor_only = false;
627
628
bool is_vararg = false;
629
bool is_static = false;
630
TypeReference return_type;
631
List<TypeReference> argument_types;
632
633
_FORCE_INLINE_ int get_arguments_count() const { return argument_types.size(); }
634
635
InternalCall() {}
636
637
InternalCall(ClassDB::APIType api_type, const String &p_name, const String &p_unique_sig = String()) {
638
name = p_name;
639
unique_sig = p_unique_sig;
640
editor_only = api_type == ClassDB::API_EDITOR;
641
}
642
643
inline bool operator==(const InternalCall &p_a) const {
644
return p_a.unique_sig == unique_sig;
645
}
646
};
647
648
bool log_print_enabled = true;
649
bool initialized = false;
650
651
HashMap<StringName, TypeInterface> obj_types;
652
653
HashMap<StringName, TypeInterface> builtin_types;
654
HashMap<StringName, TypeInterface> enum_types;
655
656
List<EnumInterface> global_enums;
657
List<ConstantInterface> global_constants;
658
659
List<InternalCall> method_icalls;
660
/// Stores the unique internal calls from [method_icalls] that are assigned to each method.
661
HashMap<const MethodInterface *, const InternalCall *> method_icalls_map;
662
663
HashMap<StringName, List<StringName>> blacklisted_methods;
664
HashSet<StringName> compat_singletons;
665
666
void _initialize_blacklisted_methods();
667
void _initialize_compat_singletons();
668
669
struct NameCache {
670
StringName type_void = "void";
671
StringName type_Variant = "Variant";
672
StringName type_VarArg = "VarArg";
673
StringName type_Object = "Object";
674
StringName type_RefCounted = "RefCounted";
675
StringName type_RID = "RID";
676
StringName type_Callable = "Callable";
677
StringName type_Signal = "Signal";
678
StringName type_String = "String";
679
StringName type_StringName = "StringName";
680
StringName type_NodePath = "NodePath";
681
StringName type_Array_generic = "Array_@generic";
682
StringName type_Dictionary_generic = "Dictionary_@generic";
683
StringName type_at_GlobalScope = "@GlobalScope";
684
StringName enum_Error = "Error";
685
686
StringName type_sbyte = "sbyte";
687
StringName type_short = "short";
688
StringName type_int = "int";
689
StringName type_byte = "byte";
690
StringName type_ushort = "ushort";
691
StringName type_uint = "uint";
692
StringName type_long = "long";
693
StringName type_ulong = "ulong";
694
695
StringName type_bool = "bool";
696
StringName type_float = "float";
697
StringName type_double = "double";
698
699
StringName type_Vector2 = "Vector2";
700
StringName type_Rect2 = "Rect2";
701
StringName type_Vector3 = "Vector3";
702
StringName type_Vector3i = "Vector3i";
703
StringName type_Vector4 = "Vector4";
704
StringName type_Vector4i = "Vector4i";
705
706
// Object not included as it must be checked for all derived classes
707
static constexpr int nullable_types_count = 19;
708
StringName nullable_types[nullable_types_count] = {
709
type_String,
710
type_StringName,
711
type_NodePath,
712
713
type_Array_generic,
714
type_Dictionary_generic,
715
StringName(_STR(Array)),
716
StringName(_STR(Dictionary)),
717
StringName(_STR(Callable)),
718
StringName(_STR(Signal)),
719
720
StringName(_STR(PackedByteArray)),
721
StringName(_STR(PackedInt32Array)),
722
StringName(_STR(PackedInt64Array)),
723
StringName(_STR(PackedFloat32Array)),
724
StringName(_STR(PackedFloat64Array)),
725
StringName(_STR(PackedStringArray)),
726
StringName(_STR(PackedVector2Array)),
727
StringName(_STR(PackedVector3Array)),
728
StringName(_STR(PackedColorArray)),
729
StringName(_STR(PackedVector4Array)),
730
};
731
732
bool is_nullable_type(const StringName &p_type) const {
733
for (int i = 0; i < nullable_types_count; i++) {
734
if (p_type == nullable_types[i]) {
735
return true;
736
}
737
}
738
739
return false;
740
}
741
742
NameCache() {}
743
744
private:
745
NameCache(const NameCache &);
746
void operator=(const NameCache &);
747
};
748
749
NameCache name_cache;
750
751
const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
752
for (const ConstantInterface &E : p_constants) {
753
if (E.name == p_name) {
754
return &E;
755
}
756
}
757
758
return nullptr;
759
}
760
761
inline String get_arg_unique_sig(const TypeInterface &p_type) {
762
// For parameters, we treat reference and non-reference derived types the same.
763
if (p_type.is_object_type) {
764
return "Obj";
765
} else if (p_type.is_enum) {
766
return "int";
767
} else if (p_type.cname == name_cache.type_Array_generic) {
768
return "Array";
769
} else if (p_type.cname == name_cache.type_Dictionary_generic) {
770
return "Dictionary";
771
}
772
773
return p_type.name;
774
}
775
776
inline String get_ret_unique_sig(const TypeInterface *p_type) {
777
// Reference derived return types are treated differently.
778
if (p_type->is_ref_counted) {
779
return "Ref";
780
} else if (p_type->is_object_type) {
781
return "Obj";
782
} else if (p_type->is_enum) {
783
return "int";
784
} else if (p_type->cname == name_cache.type_Array_generic) {
785
return "Array";
786
} else if (p_type->cname == name_cache.type_Dictionary_generic) {
787
return "Dictionary";
788
}
789
790
return p_type->name;
791
}
792
793
String bbcode_to_text(const String &p_bbcode, const TypeInterface *p_itype);
794
String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype, bool p_is_signal = false);
795
796
void _append_text_method(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
797
void _append_text_member(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
798
void _append_text_signal(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
799
void _append_text_enum(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
800
void _append_text_constant(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
801
void _append_text_constant_in_global_scope(StringBuilder &p_output, const String &p_target_cname, const String &p_link_target);
802
void _append_text_param(StringBuilder &p_output, const String &p_link_target);
803
void _append_text_undeclared(StringBuilder &p_output, const String &p_link_target);
804
805
void _append_xml_method(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts, const TypeInterface *p_source_itype);
806
void _append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts, const TypeInterface *p_source_itype);
807
void _append_xml_signal(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts, const TypeInterface *p_source_itype);
808
void _append_xml_enum(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts, const TypeInterface *p_source_itype);
809
void _append_xml_constant(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
810
void _append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target);
811
void _append_xml_param(StringBuilder &p_xml_output, const String &p_link_target, bool p_is_signal);
812
void _append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target);
813
814
bool _validate_api_type(const TypeInterface *p_target_itype, const TypeInterface *p_source_itype);
815
816
int _determine_enum_prefix(const EnumInterface &p_ienum);
817
void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
818
819
Error _populate_method_icalls_table(const TypeInterface &p_itype);
820
821
const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
822
const TypeInterface *_get_type_or_singleton_or_null(const TypeReference &p_typeref);
823
824
const String _get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters);
825
826
StringName _get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta);
827
StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
828
StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
829
830
bool _arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
831
bool _arg_default_value_is_assignable_to_type(const Variant &p_val, const TypeInterface &p_arg_type);
832
833
bool _populate_object_type_interfaces();
834
void _populate_builtin_type_interfaces();
835
836
void _populate_global_constants();
837
838
bool _method_has_conflicting_signature(const MethodInterface &p_imethod, const TypeInterface &p_itype);
839
bool _method_has_conflicting_signature(const MethodInterface &p_imethod_left, const MethodInterface &p_imethod_right);
840
841
Error _generate_cs_type(const TypeInterface &itype, const String &p_output_file);
842
843
Error _generate_cs_property(const TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output);
844
Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output, bool p_use_span);
845
Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output);
846
847
Error _generate_cs_native_calls(const InternalCall &p_icall, StringBuilder &r_output);
848
849
void _generate_array_extensions(StringBuilder &p_output);
850
void _generate_global_constants(StringBuilder &p_output);
851
852
Error _save_file(const String &p_path, const StringBuilder &p_content);
853
854
void _log(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
855
856
void _initialize();
857
858
public:
859
Error generate_cs_core_project(const String &p_proj_dir);
860
Error generate_cs_editor_project(const String &p_proj_dir);
861
Error generate_cs_api(const String &p_output_dir);
862
863
_FORCE_INLINE_ bool is_log_print_enabled() { return log_print_enabled; }
864
_FORCE_INLINE_ void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; }
865
866
_FORCE_INLINE_ bool is_initialized() { return initialized; }
867
868
static void handle_cmdline_args(const List<String> &p_cmdline_args);
869
870
BindingsGenerator() {
871
_initialize();
872
}
873
};
874
875
#endif // DEBUG_ENABLED
876
877