@@ -150,6 +150,82 @@ static String apply_pattern(const String &p_pattern, const Dictionary &p_values)
150
150
return ret;
151
151
}
152
152
153
+ static String format_enum_name (const String &enum_name) {
154
+ if (enum_name.begins_with (" Variant." )) {
155
+ return enum_name.replace (" ." , " " );
156
+ }
157
+ return enum_name;
158
+ }
159
+
160
+ void JavaScriptPlugin::_export_enumeration_binding_file (const String &p_path) {
161
+ _export_typescript_declare_file (" " );
162
+ String file_content = " // Tool generated file DO NOT modify manually\n "
163
+ " // Add this script as first autoload to your project to bind enumerations for release build of godot engine\n "
164
+ " \n "
165
+ " if (!godot.DEBUG_ENABLED) {\n "
166
+ " \t function bind(cls, enumerations) {\n "
167
+ " \t\t if (cls) Object.defineProperties(cls, enumerations);\n "
168
+ " \t };\n "
169
+ " \n "
170
+ " ${enumerations}"
171
+ " }\n "
172
+ " export default class extends godot.Node {};\n " ;
173
+
174
+ String enumerations = " " ;
175
+ for (const auto &cls : class_enumerations) {
176
+ const ClassEnumerations &enumeration = cls.value ;
177
+ const String &name = cls.key ;
178
+ String class_name = name;
179
+ if (class_name != " godot" ) {
180
+ class_name = " godot." + class_name;
181
+ }
182
+ String class_enums = " " ;
183
+ uint32_t idx = 0 ;
184
+ for (const auto &E : enumeration) {
185
+ String enum_items_text = " {" ;
186
+ const Vector<const DocData::ConstantDoc *> &consts = E.value ;
187
+ for (int i = 0 ; i < consts.size (); ++i) {
188
+ const DocData::ConstantDoc *c = consts[i];
189
+ enum_items_text += c->name + " : " + c->value ;
190
+ if (i < consts.size () - 1 ) {
191
+ enum_items_text += " , " ;
192
+ }
193
+ }
194
+ enum_items_text += " }" ;
195
+ Dictionary new_dict;
196
+ new_dict[" name" ] = format_enum_name (E.key );
197
+ new_dict[" values" ] = enum_items_text;
198
+ class_enums += apply_pattern (" \n\t\t ${name}: { value: ${values} }" , new_dict);
199
+ if (idx < enumeration.size () - 1 ) {
200
+ class_enums += " , " ;
201
+ } else {
202
+ class_enums += " \n\t " ;
203
+ }
204
+ idx++;
205
+ }
206
+ static String class_template = " \t bind(${class}, {${enumerations}});\n " ;
207
+ Dictionary class_dict;
208
+ class_dict[" class" ] = class_name;
209
+ class_dict[" enumerations" ] = class_enums;
210
+ enumerations += apply_pattern (class_template, class_dict);
211
+ }
212
+ Dictionary enum_dict;
213
+ enum_dict[" enumerations" ] = enumerations;
214
+ file_content = apply_pattern (file_content, enum_dict);
215
+
216
+ dump_to_file (p_path, file_content);
217
+ }
218
+
219
+ void JavaScriptPlugin::_generate_typescript_project () {
220
+ _export_typescript_declare_file (" res://godot.d.ts" );
221
+ dump_to_file (" res://tsconfig.json" , TSCONFIG_CONTENT);
222
+ dump_to_file (" res://decorators.ts" , TS_DECORATORS_CONTENT);
223
+ dump_to_file (" res://package.json" , PACKAGE_JSON_CONTENT);
224
+ }
225
+
226
+ // The following functions are used to generate a godot.d.ts file out of the docs folder from godot
227
+ #pragma region TS declare file
228
+
153
229
static String format_doc_text (const String &p_bbcode, const String &p_indent = " \t " ) {
154
230
String markdown = p_bbcode.strip_edges ();
155
231
@@ -222,16 +298,15 @@ static String format_property_name(const String &p_ident) {
222
298
return p_ident;
223
299
}
224
300
225
- static String format_enum_name (const String &enum_name) {
226
- if (enum_name.begins_with (" Variant." )) {
227
- return enum_name.replace (" ." , " " );
228
- }
229
- return enum_name;
230
- }
231
-
232
301
static String get_type_name (const String &p_type) {
233
- if (p_type.is_empty ())
302
+ if (p_type.is_empty () || p_type == " void " )
234
303
return " void" ;
304
+
305
+ if (p_type.ends_with (" []" )) {
306
+ String base_type = p_type.substr (0 , p_type.length () - 2 );
307
+ return " Array<" + get_type_name (base_type) + " >" ;
308
+ }
309
+
235
310
if (p_type == " int" || p_type == " float" )
236
311
return " number" ;
237
312
if (p_type == " bool" )
@@ -242,8 +317,10 @@ static String get_type_name(const String &p_type) {
242
317
return " any[]" ;
243
318
if (p_type == " Dictionary" )
244
319
return " object" ;
245
- if (p_type == " Variant" )
320
+ if (p_type == " Variant" || p_type. contains ( " * " ) )
246
321
return " any" ;
322
+ if (p_type == " StringName" )
323
+ return " StringName | string" ;
247
324
return p_type;
248
325
}
249
326
@@ -276,6 +353,11 @@ String _export_method(const DocData::MethodDoc &p_method, bool is_function = fal
276
353
}
277
354
} else {
278
355
default_value += arg.default_value ;
356
+ // we don't want to have pointers or addresses in TS
357
+ default_value = default_value
358
+ .replace (" &" , " " )
359
+ .replace (" *" , " " )
360
+ .replace (" **" , " " );
279
361
}
280
362
}
281
363
@@ -316,17 +398,23 @@ String _export_method(const DocData::MethodDoc &p_method, bool is_function = fal
316
398
return apply_pattern (method_template, dict);
317
399
}
318
400
319
- String _export_class (const DocData::ClassDoc &class_doc) {
401
+ /* This function generates all classes for godot.d.ts based on DocData::ClassDoc */
402
+ String _export_class (const DocData::ClassDoc &class_doc,
403
+ Dictionary missing_constructors,
404
+ Dictionary missing_enums,
405
+ Array ignore_methods) {
320
406
String class_template = " \n "
321
407
" \t /** ${brief_description}\n "
322
408
" \t ${description} */\n "
323
409
" ${TS_IGNORE}"
324
410
" \t class ${name}${extends}${inherits} {\n "
411
+ " ${missingConstructors}"
325
412
" ${properties}"
326
413
" ${methods}"
327
414
" ${extrals}"
328
415
" \t }\n "
329
416
" \t namespace ${name} {\n "
417
+ " ${missingEnums}"
330
418
" ${signals}"
331
419
" ${enumerations}"
332
420
" ${constants}"
@@ -345,6 +433,9 @@ String _export_class(const DocData::ClassDoc &class_doc) {
345
433
dict[" description" ] = description;
346
434
}
347
435
436
+ dict[" missingConstructors" ] = missing_constructors.get (class_doc.name , " " );
437
+ dict[" missingEnums" ] = missing_enums.get (class_doc.name , " " );
438
+
348
439
HashSet<String> ignore_members;
349
440
if (removed_members.has (class_doc.name )) {
350
441
ignore_members = removed_members[class_doc.name ];
@@ -439,15 +530,15 @@ String _export_class(const DocData::ClassDoc &class_doc) {
439
530
new_dict[" static" ] = Engine::get_singleton ()->has_singleton (class_doc.name ) ? " static " : " " ;
440
531
properties += apply_pattern (prop_str, new_dict);
441
532
442
- if (!prop_doc.getter .is_empty ()) {
533
+ if (!prop_doc.getter .is_empty () && !ignore_methods. has (prop_doc. getter ) ) {
443
534
DocData::MethodDoc md;
444
535
md.name = prop_doc.getter ;
445
536
md.return_type = get_type_name (prop_doc.type );
446
537
md.description = String (" Getter of `" ) + prop_doc.name + " ` property" ;
447
538
method_list.push_back (md);
448
539
}
449
540
450
- if (!prop_doc.setter .is_empty ()) {
541
+ if (!prop_doc.setter .is_empty () && !ignore_methods. has (prop_doc. setter ) ) {
451
542
DocData::MethodDoc md;
452
543
md.name = prop_doc.setter ;
453
544
DocData::ArgumentDoc arg;
@@ -566,27 +657,6 @@ void JavaScriptPlugin::_export_typescript_declare_file(const String &p_path) {
566
657
ignored_classes.insert (" Variant" );
567
658
ignored_classes.insert (" Array" );
568
659
ignored_classes.insert (" Dictionary" );
569
- #if 1
570
- ignored_classes.insert (" Vector2" );
571
- ignored_classes.insert (" Vector3" );
572
- ignored_classes.insert (" Color" );
573
- ignored_classes.insert (" Rect2" );
574
- ignored_classes.insert (" RID" );
575
- ignored_classes.insert (" NodePath" );
576
- ignored_classes.insert (" Transform2D" );
577
- ignored_classes.insert (" Transform3D" );
578
- ignored_classes.insert (" Basis" );
579
- ignored_classes.insert (" Quaternion" );
580
- ignored_classes.insert (" Plane" );
581
- ignored_classes.insert (" AABB" );
582
- ignored_classes.insert (" PackedByteArray" );
583
- ignored_classes.insert (" PackedInt32Array" );
584
- ignored_classes.insert (" PackedFloat32Array" );
585
- ignored_classes.insert (" PackedStringArray" );
586
- ignored_classes.insert (" PackedVector2Array" );
587
- ignored_classes.insert (" PackedVector3Array" );
588
- ignored_classes.insert (" PackedColorArray" );
589
- #endif
590
660
ignored_classes.insert (" Semaphore" );
591
661
ignored_classes.insert (" Thread" );
592
662
ignored_classes.insert (" Mutex" );
@@ -601,7 +671,11 @@ void JavaScriptPlugin::_export_typescript_declare_file(const String &p_path) {
601
671
if (ignored_classes.has (class_doc.name )) {
602
672
continue ;
603
673
}
604
- class_doc.name = get_type_name (class_doc.name );
674
+
675
+ if (class_doc.name != " StringName" && class_doc.name != " NodePath" ) {
676
+ class_doc.name = get_type_name (class_doc.name );
677
+ }
678
+
605
679
if (class_doc.name .begins_with (" @" )) {
606
680
HashMap<String, Vector<const DocData::ConstantDoc *>> enumerations;
607
681
if (class_doc.name == " @GlobalScope" || class_doc.name == " @GDScript" ) {
@@ -666,7 +740,11 @@ void JavaScriptPlugin::_export_typescript_declare_file(const String &p_path) {
666
740
}
667
741
continue ;
668
742
}
669
- classes += _export_class (class_doc);
743
+ classes += _export_class (
744
+ class_doc,
745
+ DECLARATION_CONSTRUCTORS,
746
+ DECLARATION_ENUMS,
747
+ IGNORE_METHODS);
670
748
}
671
749
dict[" classes" ] = classes;
672
750
dict[" constants" ] = constants;
@@ -681,70 +759,6 @@ void JavaScriptPlugin::_export_typescript_declare_file(const String &p_path) {
681
759
}
682
760
}
683
761
684
- void JavaScriptPlugin::_export_enumeration_binding_file (const String &p_path) {
685
- _export_typescript_declare_file (" " );
686
- String file_content = " // Tool generated file DO NOT modify manually\n "
687
- " // Add this script as first autoload to your project to bind enumerations for release build of godot engine\n "
688
- " \n "
689
- " if (!godot.DEBUG_ENABLED) {\n "
690
- " \t function bind(cls, enumerations) {\n "
691
- " \t\t if (cls) Object.defineProperties(cls, enumerations);\n "
692
- " \t };\n "
693
- " \n "
694
- " ${enumerations}"
695
- " }\n "
696
- " export default class extends godot.Node {};\n " ;
697
-
698
- String enumerations = " " ;
699
- for (const auto &cls : class_enumerations) {
700
- const ClassEnumerations &enumeration = cls.value ;
701
- const String &name = cls.key ;
702
- String class_name = name;
703
- if (class_name != " godot" ) {
704
- class_name = " godot." + class_name;
705
- }
706
- String class_enums = " " ;
707
- uint32_t idx = 0 ;
708
- for (const auto &E : enumeration) {
709
- String enum_items_text = " {" ;
710
- const Vector<const DocData::ConstantDoc *> &consts = E.value ;
711
- for (int i = 0 ; i < consts.size (); ++i) {
712
- const DocData::ConstantDoc *c = consts[i];
713
- enum_items_text += c->name + " : " + c->value ;
714
- if (i < consts.size () - 1 ) {
715
- enum_items_text += " , " ;
716
- }
717
- }
718
- enum_items_text += " }" ;
719
- Dictionary new_dict;
720
- new_dict[" name" ] = format_enum_name (E.key );
721
- new_dict[" values" ] = enum_items_text;
722
- class_enums += apply_pattern (" \n\t\t ${name}: { value: ${values} }" , new_dict);
723
- if (idx < enumeration.size () - 1 ) {
724
- class_enums += " , " ;
725
- } else {
726
- class_enums += " \n\t " ;
727
- }
728
- idx++;
729
- }
730
- static String class_template = " \t bind(${class}, {${enumerations}});\n " ;
731
- Dictionary class_dict;
732
- class_dict[" class" ] = class_name;
733
- class_dict[" enumerations" ] = class_enums;
734
- enumerations += apply_pattern (class_template, class_dict);
735
- }
736
- Dictionary enum_dict;
737
- enum_dict[" enumerations" ] = enumerations;
738
- file_content = apply_pattern (file_content, enum_dict);
739
-
740
- dump_to_file (p_path, file_content);
741
- }
742
-
743
- void JavaScriptPlugin::_generate_typescript_project () {
744
- _export_typescript_declare_file (" res://godot.d.ts" );
745
- dump_to_file (" res://tsconfig.json" , TSCONFIG_CONTENT);
746
- dump_to_file (" res://decorators.ts" , TS_DECORATORS_CONTENT);
747
- dump_to_file (" res://package.json" , PACKAGE_JSON_CONTENT);
748
- }
762
+ #pragma endregion TS declare file
749
763
750
764
#endif // TOOLS_ENABLED
0 commit comments