bindings_generator.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  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. #ifndef BINDINGS_GENERATOR_H
  31. #define BINDINGS_GENERATOR_H
  32. #include "core/typedefs.h" // DEBUG_METHODS_ENABLED
  33. #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
  34. #include "core/doc_data.h"
  35. #include "core/object/class_db.h"
  36. #include "core/string/string_builder.h"
  37. #include "core/string/ustring.h"
  38. #include "editor/doc_tools.h"
  39. #include "editor/editor_help.h"
  40. class BindingsGenerator {
  41. struct ConstantInterface {
  42. String name;
  43. String proxy_name;
  44. int64_t value = 0;
  45. const DocData::ConstantDoc *const_doc = nullptr;
  46. bool is_deprecated = false;
  47. String deprecation_message;
  48. ConstantInterface() {}
  49. ConstantInterface(const String &p_name, const String &p_proxy_name, int64_t p_value) {
  50. name = p_name;
  51. proxy_name = p_proxy_name;
  52. value = p_value;
  53. }
  54. };
  55. struct EnumInterface {
  56. StringName cname;
  57. String proxy_name;
  58. List<ConstantInterface> constants;
  59. bool is_flags = false;
  60. _FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
  61. return p_ienum.cname == cname;
  62. }
  63. EnumInterface() {}
  64. EnumInterface(const StringName &p_cname, const String &p_proxy_name, bool p_is_flags) {
  65. cname = p_cname;
  66. proxy_name = p_proxy_name;
  67. is_flags = p_is_flags;
  68. }
  69. };
  70. struct PropertyInterface {
  71. StringName cname;
  72. String proxy_name;
  73. int index = 0;
  74. StringName setter;
  75. StringName getter;
  76. /**
  77. * Determines if the property will be hidden with the [EditorBrowsable(EditorBrowsableState.Never)]
  78. * attribute.
  79. * We do this for propertyies that have the PROPERTY_USAGE_INTERNAL flag, because they are not meant
  80. * to be exposed to scripting but we can't remove them to prevent breaking compatibility.
  81. */
  82. bool is_hidden = false;
  83. const DocData::PropertyDoc *prop_doc;
  84. bool is_deprecated = false;
  85. String deprecation_message;
  86. };
  87. struct TypeReference {
  88. StringName cname;
  89. bool is_enum = false;
  90. List<TypeReference> generic_type_parameters;
  91. TypeReference() {}
  92. TypeReference(const StringName &p_cname) :
  93. cname(p_cname) {}
  94. };
  95. struct ArgumentInterface {
  96. enum DefaultParamMode {
  97. CONSTANT,
  98. NULLABLE_VAL,
  99. NULLABLE_REF
  100. };
  101. TypeReference type;
  102. String name;
  103. Variant def_param_value;
  104. DefaultParamMode def_param_mode = CONSTANT;
  105. /**
  106. * Determines the expression for the parameter default value.
  107. * Formatting elements:
  108. * %0 or %s: [cs_type] of the argument type
  109. */
  110. String default_argument;
  111. ArgumentInterface() {}
  112. };
  113. struct MethodInterface {
  114. String name;
  115. StringName cname;
  116. /**
  117. * Name of the C# method
  118. */
  119. String proxy_name;
  120. /**
  121. * Hash of the ClassDB method
  122. */
  123. uint64_t hash = 0;
  124. /**
  125. * [TypeInterface::name] of the return type
  126. */
  127. TypeReference return_type;
  128. /**
  129. * Determines if the method has a variable number of arguments (VarArg)
  130. */
  131. bool is_vararg = false;
  132. /**
  133. * Determines if the method is static.
  134. */
  135. bool is_static = false;
  136. /**
  137. * Virtual methods ("virtual" as defined by the Godot API) are methods that by default do nothing,
  138. * but can be overridden by the user to add custom functionality.
  139. * e.g.: _ready, _process, etc.
  140. */
  141. bool is_virtual = false;
  142. /**
  143. * Determines if the call should fallback to Godot's object.Call(string, params) in C#.
  144. */
  145. bool requires_object_call = false;
  146. /**
  147. * Determines if the method visibility is 'internal' (visible only to files in the same assembly).
  148. * Currently, we only use this for methods that are not meant to be exposed,
  149. * but are required by properties as getters or setters.
  150. * Methods that are not meant to be exposed are those that begin with underscore and are not virtual.
  151. */
  152. bool is_internal = false;
  153. /**
  154. * Determines if the method will be hidden with the [EditorBrowsable(EditorBrowsableState.Never)]
  155. * attribute.
  156. * We do this for methods that we don't want to expose but need to be public to prevent breaking
  157. * compat (i.e: methods with 'is_compat' set to true.)
  158. */
  159. bool is_hidden = false;
  160. /**
  161. * Determines if the method is a compatibility method added to avoid breaking binary compatibility.
  162. * These methods will be generated but hidden and are considered deprecated.
  163. */
  164. bool is_compat = false;
  165. List<ArgumentInterface> arguments;
  166. const DocData::MethodDoc *method_doc = nullptr;
  167. bool is_deprecated = false;
  168. String deprecation_message;
  169. void add_argument(const ArgumentInterface &argument) {
  170. arguments.push_back(argument);
  171. }
  172. MethodInterface() {}
  173. };
  174. struct SignalInterface {
  175. String name;
  176. StringName cname;
  177. /**
  178. * Name of the C# method
  179. */
  180. String proxy_name;
  181. List<ArgumentInterface> arguments;
  182. const DocData::MethodDoc *method_doc = nullptr;
  183. bool is_deprecated = false;
  184. String deprecation_message;
  185. void add_argument(const ArgumentInterface &argument) {
  186. arguments.push_back(argument);
  187. }
  188. SignalInterface() {}
  189. };
  190. struct TypeInterface {
  191. /**
  192. * Identifier name for this type.
  193. * Also used to format [c_out].
  194. */
  195. String name;
  196. StringName cname;
  197. int type_parameter_count = 0;
  198. /**
  199. * Identifier name of the base class.
  200. */
  201. StringName base_name;
  202. /**
  203. * Name of the C# class
  204. */
  205. String proxy_name;
  206. ClassDB::APIType api_type = ClassDB::API_NONE;
  207. bool is_enum = false;
  208. bool is_object_type = false;
  209. bool is_singleton = false;
  210. bool is_singleton_instance = false;
  211. bool is_ref_counted = false;
  212. bool is_span_compatible = false;
  213. /**
  214. * Class is a singleton, but can't be declared as a static class as that would
  215. * break backwards compatibility. As such, instead of going with a static class,
  216. * we use the actual singleton pattern (private constructor with instance property),
  217. * which doesn't break compatibility.
  218. */
  219. bool is_compat_singleton = false;
  220. /**
  221. * Determines whether the native return value of this type must be disposed
  222. * by the generated internal call (think of `godot_string`, whose destructor
  223. * must be called). Some structs that are disposable may still disable this
  224. * flag if the ownership is transferred.
  225. */
  226. bool c_type_is_disposable_struct = false;
  227. /**
  228. * Determines whether the native return value of this type must be zero initialized
  229. * before its address is passed to ptrcall. This is required for types whose destructor
  230. * is called before being assigned the return value by `PtrToArg::encode`, e.g.:
  231. * Array, Dictionary, String, StringName, Variant.
  232. * It's not necessary to set this to `true` if [c_type_is_disposable_struct] is already `true`.
  233. */
  234. bool c_ret_needs_default_initialization = false;
  235. /**
  236. * Used only by Object-derived types.
  237. * Determines if this type is not abstract (incomplete).
  238. * e.g.: CanvasItem cannot be instantiated.
  239. */
  240. bool is_instantiable = false;
  241. /**
  242. * Used only by Object-derived types.
  243. * Determines if the C# class owns the native handle and must free it somehow when disposed.
  244. * e.g.: RefCounted types must notify when the C# instance is disposed, for proper refcounting.
  245. */
  246. bool memory_own = false;
  247. // !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
  248. // !! When renaming those fields, make sure to rename their references in the comments
  249. // --- C INTERFACE ---
  250. /**
  251. * One or more statements that transform the parameter before being passed as argument of a ptrcall.
  252. * If the statement adds a local that must be passed as the argument instead of the parameter,
  253. * the expression with the name of that local must be specified with [c_arg_in].
  254. * Formatting elements:
  255. * %0: [c_type] of the parameter
  256. * %1: name of the parameter
  257. * %2-4: reserved
  258. * %5: indentation text
  259. */
  260. String c_in;
  261. /**
  262. * One or more statements that transform the parameter before being passed as argument of a vararg call.
  263. * If the statement adds a local that must be passed as the argument instead of the parameter,
  264. * the name of that local must be specified with [c_arg_in].
  265. * Formatting elements:
  266. * %0: [c_type] of the parameter
  267. * %1: name of the parameter
  268. * %2-4: reserved
  269. * %5: indentation text
  270. */
  271. String c_in_vararg;
  272. /**
  273. * Determines the expression that will be passed as argument to ptrcall.
  274. * By default the value equals the name of the parameter,
  275. * this varies for types that require special manipulation via [c_in].
  276. * Formatting elements:
  277. * %0 or %s: name of the parameter
  278. */
  279. String c_arg_in = "%s";
  280. /**
  281. * One or more statements that determine how a variable of this type is returned from a function.
  282. * It must contain the return statement(s).
  283. * Formatting elements:
  284. * %0: [c_type_out] of the return type
  285. * %1: name of the variable to be returned
  286. * %2: [name] of the return type
  287. * ---------------------------------------
  288. * If [ret_as_byref_arg] is true, the format is different. Instead of using a return statement,
  289. * the value must be assigned to a parameter. This type of this parameter is a pointer to [c_type_out].
  290. * Formatting elements:
  291. * %0: [c_type_out] of the return type
  292. * %1: name of the variable to be returned
  293. * %2: [name] of the return type
  294. * %3-4: reserved
  295. * %5: indentation text
  296. */
  297. String c_out;
  298. /**
  299. * The actual expected type, as seen (in most cases) in Variant copy constructors
  300. * Used for the type of the return variable and to format [c_in].
  301. * The value must be the following depending of the type:
  302. * Object-derived types: Object*
  303. * Other types: [name]
  304. * -- Exceptions --
  305. * VarArg (fictitious type to represent variable arguments): Array
  306. * float: double (because ptrcall only supports double)
  307. * int: int64_t (because ptrcall only supports int64_t and uint64_t)
  308. * RefCounted types override this for the type of the return variable: Ref<RefCounted>
  309. */
  310. String c_type;
  311. /**
  312. * Determines the type used for parameters in function signatures.
  313. */
  314. String c_type_in;
  315. /**
  316. * Determines the return type used for function signatures.
  317. * Also used to construct a default value to return in case of errors,
  318. * and to format [c_out].
  319. */
  320. String c_type_out;
  321. // --- C# INTERFACE ---
  322. /**
  323. * An expression that overrides the way the parameter is passed to the internal call.
  324. * If empty, the parameter is passed as is.
  325. * Formatting elements:
  326. * %0: name of the parameter
  327. * %1: [c_type] of the parameter
  328. */
  329. String cs_in_expr;
  330. bool cs_in_expr_is_unsafe = false;
  331. /**
  332. * One or more statements that transform the parameter before being passed to the internal call.
  333. * If the statement adds a local that must be passed as the argument instead of the parameter,
  334. * the expression with the name of that local must be specified with [cs_in_expr].
  335. * Formatting elements:
  336. * %0: [c_type] of the parameter
  337. * %1: name of the parameter
  338. * %2-4: reserved
  339. * %5: indentation text
  340. */
  341. String cs_in;
  342. /**
  343. * One or more statements that determine how a variable of this type is returned from a method.
  344. * It must contain the return statement(s).
  345. * Formatting elements:
  346. * %0: internal method name
  347. * %1: internal method call arguments without surrounding parenthesis
  348. * %2: [cs_type] of the return type
  349. * %3: [c_type_out] of the return type
  350. * %4: reserved
  351. * %5: indentation text
  352. */
  353. String cs_out;
  354. /**
  355. * Type used for method signatures, both for parameters and the return type.
  356. * Same as [proxy_name] except for variable arguments (VarArg) and collections (which include the namespace).
  357. */
  358. String cs_type;
  359. /**
  360. * Formatting elements:
  361. * %0: input expression of type `in godot_variant`
  362. * %1: [cs_type] of this type
  363. * %2: [name] of this type
  364. */
  365. String cs_variant_to_managed;
  366. /**
  367. * Formatting elements:
  368. * %0: input expression
  369. * %1: [cs_type] of this type
  370. * %2: [name] of this type
  371. */
  372. String cs_managed_to_variant;
  373. const DocData::ClassDoc *class_doc = nullptr;
  374. bool is_deprecated = false;
  375. String deprecation_message;
  376. List<ConstantInterface> constants;
  377. List<EnumInterface> enums;
  378. List<PropertyInterface> properties;
  379. List<MethodInterface> methods;
  380. List<SignalInterface> signals_;
  381. HashSet<String> ignored_members;
  382. bool has_virtual_methods = false;
  383. const MethodInterface *find_method_by_name(const StringName &p_cname) const {
  384. for (const MethodInterface &E : methods) {
  385. if (E.cname == p_cname) {
  386. return &E;
  387. }
  388. }
  389. return nullptr;
  390. }
  391. const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const {
  392. for (const MethodInterface &E : methods) {
  393. if (E.proxy_name == p_proxy_name) {
  394. return &E;
  395. }
  396. }
  397. return nullptr;
  398. }
  399. const PropertyInterface *find_property_by_name(const StringName &p_cname) const {
  400. for (const PropertyInterface &E : properties) {
  401. if (E.cname == p_cname) {
  402. return &E;
  403. }
  404. }
  405. return nullptr;
  406. }
  407. const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const {
  408. for (const PropertyInterface &E : properties) {
  409. if (E.proxy_name == p_proxy_name) {
  410. return &E;
  411. }
  412. }
  413. return nullptr;
  414. }
  415. const SignalInterface *find_signal_by_name(const StringName &p_cname) const {
  416. for (const SignalInterface &E : signals_) {
  417. if (E.cname == p_cname) {
  418. return &E;
  419. }
  420. }
  421. return nullptr;
  422. }
  423. const SignalInterface *find_signal_by_proxy_name(const String &p_proxy_name) const {
  424. for (const SignalInterface &E : signals_) {
  425. if (E.proxy_name == p_proxy_name) {
  426. return &E;
  427. }
  428. }
  429. return nullptr;
  430. }
  431. bool is_intentionally_ignored(const String &p_name) const {
  432. return ignored_members.has(p_name);
  433. }
  434. private:
  435. static DocData::ClassDoc *_get_type_doc(TypeInterface &itype) {
  436. String doc_name = itype.name.begins_with("_") ? itype.name.substr(1) : itype.name;
  437. return &EditorHelp::get_doc_data()->class_list[doc_name];
  438. }
  439. static void _init_value_type(TypeInterface &itype) {
  440. if (itype.proxy_name.is_empty()) {
  441. itype.proxy_name = itype.name;
  442. }
  443. itype.cs_type = itype.proxy_name;
  444. itype.c_type = itype.cs_type;
  445. itype.c_type_in = itype.cs_type + "*";
  446. itype.c_type_out = itype.cs_type;
  447. itype.class_doc = _get_type_doc(itype);
  448. }
  449. static void _init_object_type(TypeInterface &itype, ClassDB::APIType p_api_type) {
  450. if (itype.proxy_name.is_empty()) {
  451. itype.proxy_name = itype.name;
  452. }
  453. if (itype.proxy_name.begins_with("_")) {
  454. itype.proxy_name = itype.proxy_name.substr(1);
  455. }
  456. itype.api_type = p_api_type;
  457. itype.is_object_type = true;
  458. itype.class_doc = _get_type_doc(itype);
  459. }
  460. public:
  461. static TypeInterface create_value_type(const String &p_name, const String &p_proxy_name) {
  462. TypeInterface itype;
  463. itype.name = p_name;
  464. itype.cname = p_name;
  465. itype.proxy_name = p_proxy_name;
  466. _init_value_type(itype);
  467. return itype;
  468. }
  469. static TypeInterface create_value_type(const StringName &p_cname, const String &p_proxy_name) {
  470. TypeInterface itype;
  471. itype.name = p_cname;
  472. itype.cname = p_cname;
  473. itype.proxy_name = p_proxy_name;
  474. _init_value_type(itype);
  475. return itype;
  476. }
  477. static TypeInterface create_value_type(const String &p_name) {
  478. TypeInterface itype;
  479. itype.name = p_name;
  480. itype.cname = p_name;
  481. _init_value_type(itype);
  482. return itype;
  483. }
  484. static TypeInterface create_value_type(const StringName &p_cname) {
  485. TypeInterface itype;
  486. itype.name = p_cname;
  487. itype.cname = p_cname;
  488. _init_value_type(itype);
  489. return itype;
  490. }
  491. static TypeInterface create_object_type(const StringName &p_cname, const String &p_proxy_name, ClassDB::APIType p_api_type) {
  492. TypeInterface itype;
  493. itype.name = p_cname;
  494. itype.cname = p_cname;
  495. itype.proxy_name = p_proxy_name;
  496. _init_object_type(itype, p_api_type);
  497. return itype;
  498. }
  499. static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) {
  500. TypeInterface itype;
  501. itype.name = p_cname;
  502. itype.cname = p_cname;
  503. _init_object_type(itype, p_api_type);
  504. return itype;
  505. }
  506. static void postsetup_enum_type(TypeInterface &r_enum_itype);
  507. TypeInterface() {
  508. static String default_cs_variant_to_managed = "VariantUtils.ConvertTo<%1>(%0)";
  509. static String default_cs_managed_to_variant = "VariantUtils.CreateFrom<%1>(%0)";
  510. cs_variant_to_managed = default_cs_variant_to_managed;
  511. cs_managed_to_variant = default_cs_managed_to_variant;
  512. }
  513. };
  514. struct InternalCall {
  515. String name;
  516. String unique_sig; // Unique signature to avoid duplicates in containers
  517. bool editor_only = false;
  518. bool is_vararg = false;
  519. bool is_static = false;
  520. TypeReference return_type;
  521. List<TypeReference> argument_types;
  522. _FORCE_INLINE_ int get_arguments_count() const { return argument_types.size(); }
  523. InternalCall() {}
  524. InternalCall(ClassDB::APIType api_type, const String &p_name, const String &p_unique_sig = String()) {
  525. name = p_name;
  526. unique_sig = p_unique_sig;
  527. editor_only = api_type == ClassDB::API_EDITOR;
  528. }
  529. inline bool operator==(const InternalCall &p_a) const {
  530. return p_a.unique_sig == unique_sig;
  531. }
  532. };
  533. bool log_print_enabled = true;
  534. bool initialized = false;
  535. HashMap<StringName, TypeInterface> obj_types;
  536. HashMap<StringName, TypeInterface> builtin_types;
  537. HashMap<StringName, TypeInterface> enum_types;
  538. List<EnumInterface> global_enums;
  539. List<ConstantInterface> global_constants;
  540. List<InternalCall> method_icalls;
  541. /// Stores the unique internal calls from [method_icalls] that are assigned to each method.
  542. HashMap<const MethodInterface *, const InternalCall *> method_icalls_map;
  543. HashMap<StringName, List<StringName>> blacklisted_methods;
  544. HashSet<StringName> compat_singletons;
  545. void _initialize_blacklisted_methods();
  546. void _initialize_compat_singletons();
  547. struct NameCache {
  548. StringName type_void = StaticCString::create("void");
  549. StringName type_Variant = StaticCString::create("Variant");
  550. StringName type_VarArg = StaticCString::create("VarArg");
  551. StringName type_Object = StaticCString::create("Object");
  552. StringName type_RefCounted = StaticCString::create("RefCounted");
  553. StringName type_RID = StaticCString::create("RID");
  554. StringName type_Callable = StaticCString::create("Callable");
  555. StringName type_Signal = StaticCString::create("Signal");
  556. StringName type_String = StaticCString::create("String");
  557. StringName type_StringName = StaticCString::create("StringName");
  558. StringName type_NodePath = StaticCString::create("NodePath");
  559. StringName type_Array_generic = StaticCString::create("Array_@generic");
  560. StringName type_Dictionary_generic = StaticCString::create("Dictionary_@generic");
  561. StringName type_at_GlobalScope = StaticCString::create("@GlobalScope");
  562. StringName enum_Error = StaticCString::create("Error");
  563. StringName type_sbyte = StaticCString::create("sbyte");
  564. StringName type_short = StaticCString::create("short");
  565. StringName type_int = StaticCString::create("int");
  566. StringName type_byte = StaticCString::create("byte");
  567. StringName type_ushort = StaticCString::create("ushort");
  568. StringName type_uint = StaticCString::create("uint");
  569. StringName type_long = StaticCString::create("long");
  570. StringName type_ulong = StaticCString::create("ulong");
  571. StringName type_bool = StaticCString::create("bool");
  572. StringName type_float = StaticCString::create("float");
  573. StringName type_double = StaticCString::create("double");
  574. StringName type_Vector2 = StaticCString::create("Vector2");
  575. StringName type_Rect2 = StaticCString::create("Rect2");
  576. StringName type_Vector3 = StaticCString::create("Vector3");
  577. StringName type_Vector3i = StaticCString::create("Vector3i");
  578. StringName type_Vector4 = StaticCString::create("Vector4");
  579. StringName type_Vector4i = StaticCString::create("Vector4i");
  580. // Object not included as it must be checked for all derived classes
  581. static constexpr int nullable_types_count = 19;
  582. StringName nullable_types[nullable_types_count] = {
  583. type_String,
  584. type_StringName,
  585. type_NodePath,
  586. type_Array_generic,
  587. type_Dictionary_generic,
  588. StaticCString::create(_STR(Array)),
  589. StaticCString::create(_STR(Dictionary)),
  590. StaticCString::create(_STR(Callable)),
  591. StaticCString::create(_STR(Signal)),
  592. StaticCString::create(_STR(PackedByteArray)),
  593. StaticCString::create(_STR(PackedInt32Array)),
  594. StaticCString::create(_STR(PackedInt64Array)),
  595. StaticCString::create(_STR(PackedFloat32Array)),
  596. StaticCString::create(_STR(PackedFloat64Array)),
  597. StaticCString::create(_STR(PackedStringArray)),
  598. StaticCString::create(_STR(PackedVector2Array)),
  599. StaticCString::create(_STR(PackedVector3Array)),
  600. StaticCString::create(_STR(PackedColorArray)),
  601. StaticCString::create(_STR(PackedVector4Array)),
  602. };
  603. bool is_nullable_type(const StringName &p_type) const {
  604. for (int i = 0; i < nullable_types_count; i++) {
  605. if (p_type == nullable_types[i]) {
  606. return true;
  607. }
  608. }
  609. return false;
  610. }
  611. NameCache() {}
  612. private:
  613. NameCache(const NameCache &);
  614. void operator=(const NameCache &);
  615. };
  616. NameCache name_cache;
  617. const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
  618. for (const ConstantInterface &E : p_constants) {
  619. if (E.name == p_name) {
  620. return &E;
  621. }
  622. }
  623. return nullptr;
  624. }
  625. inline String get_arg_unique_sig(const TypeInterface &p_type) {
  626. // For parameters, we treat reference and non-reference derived types the same.
  627. if (p_type.is_object_type) {
  628. return "Obj";
  629. } else if (p_type.is_enum) {
  630. return "int";
  631. } else if (p_type.cname == name_cache.type_Array_generic) {
  632. return "Array";
  633. } else if (p_type.cname == name_cache.type_Dictionary_generic) {
  634. return "Dictionary";
  635. }
  636. return p_type.name;
  637. }
  638. inline String get_ret_unique_sig(const TypeInterface *p_type) {
  639. // Reference derived return types are treated differently.
  640. if (p_type->is_ref_counted) {
  641. return "Ref";
  642. } else if (p_type->is_object_type) {
  643. return "Obj";
  644. } else if (p_type->is_enum) {
  645. return "int";
  646. } else if (p_type->cname == name_cache.type_Array_generic) {
  647. return "Array";
  648. } else if (p_type->cname == name_cache.type_Dictionary_generic) {
  649. return "Dictionary";
  650. }
  651. return p_type->name;
  652. }
  653. String bbcode_to_text(const String &p_bbcode, const TypeInterface *p_itype);
  654. String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype, bool p_is_signal = false);
  655. 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);
  656. 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);
  657. 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);
  658. 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);
  659. 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);
  660. void _append_text_constant_in_global_scope(StringBuilder &p_output, const String &p_target_cname, const String &p_link_target);
  661. void _append_text_param(StringBuilder &p_output, const String &p_link_target);
  662. void _append_text_undeclared(StringBuilder &p_output, const String &p_link_target);
  663. 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);
  664. 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);
  665. 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);
  666. 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);
  667. 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);
  668. void _append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target);
  669. void _append_xml_param(StringBuilder &p_xml_output, const String &p_link_target, bool p_is_signal);
  670. void _append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target);
  671. int _determine_enum_prefix(const EnumInterface &p_ienum);
  672. void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
  673. Error _populate_method_icalls_table(const TypeInterface &p_itype);
  674. const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
  675. const TypeInterface *_get_type_or_singleton_or_null(const TypeReference &p_typeref);
  676. const String _get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters);
  677. StringName _get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta);
  678. StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
  679. StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
  680. bool _arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
  681. bool _arg_default_value_is_assignable_to_type(const Variant &p_val, const TypeInterface &p_arg_type);
  682. bool _populate_object_type_interfaces();
  683. void _populate_builtin_type_interfaces();
  684. void _populate_global_constants();
  685. bool _method_has_conflicting_signature(const MethodInterface &p_imethod, const TypeInterface &p_itype);
  686. bool _method_has_conflicting_signature(const MethodInterface &p_imethod_left, const MethodInterface &p_imethod_right);
  687. Error _generate_cs_type(const TypeInterface &itype, const String &p_output_file);
  688. Error _generate_cs_property(const TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output);
  689. Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output, bool p_use_span);
  690. Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output);
  691. Error _generate_cs_native_calls(const InternalCall &p_icall, StringBuilder &r_output);
  692. void _generate_array_extensions(StringBuilder &p_output);
  693. void _generate_global_constants(StringBuilder &p_output);
  694. Error _save_file(const String &p_path, const StringBuilder &p_content);
  695. void _log(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
  696. void _initialize();
  697. public:
  698. Error generate_cs_core_project(const String &p_proj_dir);
  699. Error generate_cs_editor_project(const String &p_proj_dir);
  700. Error generate_cs_api(const String &p_output_dir);
  701. _FORCE_INLINE_ bool is_log_print_enabled() { return log_print_enabled; }
  702. _FORCE_INLINE_ void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; }
  703. _FORCE_INLINE_ bool is_initialized() { return initialized; }
  704. static void handle_cmdline_args(const List<String> &p_cmdline_args);
  705. BindingsGenerator() {
  706. _initialize();
  707. }
  708. };
  709. #endif
  710. #endif // BINDINGS_GENERATOR_H