1/**************************************************************************/
2/* doc_data.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#ifndef DOC_DATA_H
32#define DOC_DATA_H
33
34#include "core/io/xml_parser.h"
35#include "core/variant/variant.h"
36
37struct ScriptMemberInfo {
38 PropertyInfo propinfo;
39 String doc_string;
40 StringName setter;
41 StringName getter;
42
43 bool has_default_value = false;
44 Variant default_value;
45};
46
47class DocData {
48public:
49 struct ArgumentDoc {
50 String name;
51 String type;
52 String enumeration;
53 bool is_bitfield = false;
54 String default_value;
55 bool operator<(const ArgumentDoc &p_arg) const {
56 if (name == p_arg.name) {
57 return type < p_arg.type;
58 }
59 return name < p_arg.name;
60 }
61 static ArgumentDoc from_dict(const Dictionary &p_dict) {
62 ArgumentDoc doc;
63
64 if (p_dict.has("name")) {
65 doc.name = p_dict["name"];
66 }
67
68 if (p_dict.has("type")) {
69 doc.type = p_dict["type"];
70 }
71
72 if (p_dict.has("enumeration")) {
73 doc.enumeration = p_dict["enumeration"];
74 if (p_dict.has("is_bitfield")) {
75 doc.is_bitfield = p_dict["is_bitfield"];
76 }
77 }
78
79 if (p_dict.has("default_value")) {
80 doc.default_value = p_dict["default_value"];
81 }
82
83 return doc;
84 }
85 static Dictionary to_dict(const ArgumentDoc &p_doc) {
86 Dictionary dict;
87
88 if (!p_doc.name.is_empty()) {
89 dict["name"] = p_doc.name;
90 }
91
92 if (!p_doc.type.is_empty()) {
93 dict["type"] = p_doc.type;
94 }
95
96 if (!p_doc.enumeration.is_empty()) {
97 dict["enumeration"] = p_doc.enumeration;
98 dict["is_bitfield"] = p_doc.is_bitfield;
99 }
100
101 if (!p_doc.default_value.is_empty()) {
102 dict["default_value"] = p_doc.default_value;
103 }
104
105 return dict;
106 }
107 };
108
109 struct MethodDoc {
110 String name;
111 String return_type;
112 String return_enum;
113 bool return_is_bitfield = false;
114 String qualifiers;
115 String description;
116 bool is_deprecated = false;
117 bool is_experimental = false;
118 Vector<ArgumentDoc> arguments;
119 Vector<int> errors_returned;
120 bool operator<(const MethodDoc &p_method) const {
121 if (name == p_method.name) {
122 // Must be an operator or a constructor since there is no other overloading
123 if (name.left(8) == "operator") {
124 if (arguments.size() == p_method.arguments.size()) {
125 if (arguments.size() == 0) {
126 return false;
127 }
128 return arguments[0].type < p_method.arguments[0].type;
129 }
130 return arguments.size() < p_method.arguments.size();
131 } else {
132 // Must be a constructor
133 // We want this arbitrary order for a class "Foo":
134 // - 1. Default constructor: Foo()
135 // - 2. Copy constructor: Foo(Foo)
136 // - 3+. Other constructors Foo(Bar, ...) based on first argument's name
137 if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
138 return arguments.size() < p_method.arguments.size();
139 }
140 if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
141 return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type);
142 }
143 return arguments[0] < p_method.arguments[0];
144 }
145 }
146 return name.naturalcasecmp_to(p_method.name) < 0;
147 }
148 static MethodDoc from_dict(const Dictionary &p_dict) {
149 MethodDoc doc;
150
151 if (p_dict.has("name")) {
152 doc.name = p_dict["name"];
153 }
154
155 if (p_dict.has("return_type")) {
156 doc.return_type = p_dict["return_type"];
157 }
158
159 if (p_dict.has("return_enum")) {
160 doc.return_enum = p_dict["return_enum"];
161 if (p_dict.has("return_is_bitfield")) {
162 doc.return_is_bitfield = p_dict["return_is_bitfield"];
163 }
164 }
165
166 if (p_dict.has("qualifiers")) {
167 doc.qualifiers = p_dict["qualifiers"];
168 }
169
170 if (p_dict.has("description")) {
171 doc.description = p_dict["description"];
172 }
173
174 if (p_dict.has("is_deprecated")) {
175 doc.is_deprecated = p_dict["is_deprecated"];
176 }
177
178 if (p_dict.has("is_experimental")) {
179 doc.is_experimental = p_dict["is_experimental"];
180 }
181
182 Array arguments;
183 if (p_dict.has("arguments")) {
184 arguments = p_dict["arguments"];
185 }
186 for (int i = 0; i < arguments.size(); i++) {
187 doc.arguments.push_back(ArgumentDoc::from_dict(arguments[i]));
188 }
189
190 Array errors_returned;
191 if (p_dict.has("errors_returned")) {
192 errors_returned = p_dict["errors_returned"];
193 }
194 for (int i = 0; i < errors_returned.size(); i++) {
195 doc.errors_returned.push_back(errors_returned[i]);
196 }
197
198 return doc;
199 }
200 static Dictionary to_dict(const MethodDoc &p_doc) {
201 Dictionary dict;
202
203 if (!p_doc.name.is_empty()) {
204 dict["name"] = p_doc.name;
205 }
206
207 if (!p_doc.return_type.is_empty()) {
208 dict["return_type"] = p_doc.return_type;
209 }
210
211 if (!p_doc.return_enum.is_empty()) {
212 dict["return_enum"] = p_doc.return_enum;
213 dict["return_is_bitfield"] = p_doc.return_is_bitfield;
214 }
215
216 if (!p_doc.qualifiers.is_empty()) {
217 dict["qualifiers"] = p_doc.qualifiers;
218 }
219
220 if (!p_doc.description.is_empty()) {
221 dict["description"] = p_doc.description;
222 }
223
224 dict["is_deprecated"] = p_doc.is_deprecated;
225
226 dict["is_experimental"] = p_doc.is_experimental;
227
228 if (!p_doc.arguments.is_empty()) {
229 Array arguments;
230 for (int i = 0; i < p_doc.arguments.size(); i++) {
231 arguments.push_back(ArgumentDoc::to_dict(p_doc.arguments[i]));
232 }
233 dict["arguments"] = arguments;
234 }
235
236 if (!p_doc.errors_returned.is_empty()) {
237 Array errors_returned;
238 for (int i = 0; i < p_doc.errors_returned.size(); i++) {
239 errors_returned.push_back(p_doc.errors_returned[i]);
240 }
241 dict["errors_returned"] = errors_returned;
242 }
243
244 return dict;
245 }
246 };
247
248 struct ConstantDoc {
249 String name;
250 String value;
251 bool is_value_valid = false;
252 String enumeration;
253 bool is_bitfield = false;
254 String description;
255 bool is_deprecated = false;
256 bool is_experimental = false;
257 bool operator<(const ConstantDoc &p_const) const {
258 return name < p_const.name;
259 }
260 static ConstantDoc from_dict(const Dictionary &p_dict) {
261 ConstantDoc doc;
262
263 if (p_dict.has("name")) {
264 doc.name = p_dict["name"];
265 }
266
267 if (p_dict.has("value")) {
268 doc.value = p_dict["value"];
269 }
270
271 if (p_dict.has("is_value_valid")) {
272 doc.is_value_valid = p_dict["is_value_valid"];
273 }
274
275 if (p_dict.has("enumeration")) {
276 doc.enumeration = p_dict["enumeration"];
277 if (p_dict.has("is_bitfield")) {
278 doc.is_bitfield = p_dict["is_bitfield"];
279 }
280 }
281
282 if (p_dict.has("description")) {
283 doc.description = p_dict["description"];
284 }
285
286 if (p_dict.has("is_deprecated")) {
287 doc.is_deprecated = p_dict["is_deprecated"];
288 }
289
290 if (p_dict.has("is_experimental")) {
291 doc.is_experimental = p_dict["is_experimental"];
292 }
293
294 return doc;
295 }
296 static Dictionary to_dict(const ConstantDoc &p_doc) {
297 Dictionary dict;
298
299 if (!p_doc.name.is_empty()) {
300 dict["name"] = p_doc.name;
301 }
302
303 if (!p_doc.value.is_empty()) {
304 dict["value"] = p_doc.value;
305 }
306
307 dict["is_value_valid"] = p_doc.is_value_valid;
308
309 if (!p_doc.enumeration.is_empty()) {
310 dict["enumeration"] = p_doc.enumeration;
311 dict["is_bitfield"] = p_doc.is_bitfield;
312 }
313
314 if (!p_doc.description.is_empty()) {
315 dict["description"] = p_doc.description;
316 }
317
318 dict["is_deprecated"] = p_doc.is_deprecated;
319
320 dict["is_experimental"] = p_doc.is_experimental;
321
322 return dict;
323 }
324 };
325
326 struct PropertyDoc {
327 String name;
328 String type;
329 String enumeration;
330 bool is_bitfield = false;
331 String description;
332 String setter, getter;
333 String default_value;
334 bool overridden = false;
335 String overrides;
336 bool is_deprecated = false;
337 bool is_experimental = false;
338 bool operator<(const PropertyDoc &p_prop) const {
339 return name.naturalcasecmp_to(p_prop.name) < 0;
340 }
341 static PropertyDoc from_dict(const Dictionary &p_dict) {
342 PropertyDoc doc;
343
344 if (p_dict.has("name")) {
345 doc.name = p_dict["name"];
346 }
347
348 if (p_dict.has("type")) {
349 doc.type = p_dict["type"];
350 }
351
352 if (p_dict.has("enumeration")) {
353 doc.enumeration = p_dict["enumeration"];
354 if (p_dict.has("is_bitfield")) {
355 doc.is_bitfield = p_dict["is_bitfield"];
356 }
357 }
358
359 if (p_dict.has("description")) {
360 doc.description = p_dict["description"];
361 }
362
363 if (p_dict.has("setter")) {
364 doc.setter = p_dict["setter"];
365 }
366
367 if (p_dict.has("getter")) {
368 doc.getter = p_dict["getter"];
369 }
370
371 if (p_dict.has("default_value")) {
372 doc.default_value = p_dict["default_value"];
373 }
374
375 if (p_dict.has("overridden")) {
376 doc.overridden = p_dict["overridden"];
377 }
378
379 if (p_dict.has("overrides")) {
380 doc.overrides = p_dict["overrides"];
381 }
382
383 if (p_dict.has("is_deprecated")) {
384 doc.is_deprecated = p_dict["is_deprecated"];
385 }
386
387 if (p_dict.has("is_experimental")) {
388 doc.is_experimental = p_dict["is_experimental"];
389 }
390
391 return doc;
392 }
393 static Dictionary to_dict(const PropertyDoc &p_doc) {
394 Dictionary dict;
395
396 if (!p_doc.name.is_empty()) {
397 dict["name"] = p_doc.name;
398 }
399
400 if (!p_doc.type.is_empty()) {
401 dict["type"] = p_doc.type;
402 }
403
404 if (!p_doc.enumeration.is_empty()) {
405 dict["enumeration"] = p_doc.enumeration;
406 dict["is_bitfield"] = p_doc.is_bitfield;
407 }
408
409 if (!p_doc.description.is_empty()) {
410 dict["description"] = p_doc.description;
411 }
412
413 if (!p_doc.setter.is_empty()) {
414 dict["setter"] = p_doc.setter;
415 }
416
417 if (!p_doc.getter.is_empty()) {
418 dict["getter"] = p_doc.getter;
419 }
420
421 if (!p_doc.default_value.is_empty()) {
422 dict["default_value"] = p_doc.default_value;
423 }
424
425 dict["overridden"] = p_doc.overridden;
426
427 if (!p_doc.overrides.is_empty()) {
428 dict["overrides"] = p_doc.overrides;
429 }
430
431 dict["is_deprecated"] = p_doc.is_deprecated;
432
433 dict["is_experimental"] = p_doc.is_experimental;
434
435 return dict;
436 }
437 };
438
439 struct ThemeItemDoc {
440 String name;
441 String type;
442 String data_type;
443 String description;
444 String default_value;
445 bool operator<(const ThemeItemDoc &p_theme_item) const {
446 // First sort by the data type, then by name.
447 if (data_type == p_theme_item.data_type) {
448 return name.naturalcasecmp_to(p_theme_item.name) < 0;
449 }
450 return data_type < p_theme_item.data_type;
451 }
452 static ThemeItemDoc from_dict(const Dictionary &p_dict) {
453 ThemeItemDoc doc;
454
455 if (p_dict.has("name")) {
456 doc.name = p_dict["name"];
457 }
458
459 if (p_dict.has("type")) {
460 doc.type = p_dict["type"];
461 }
462
463 if (p_dict.has("data_type")) {
464 doc.data_type = p_dict["data_type"];
465 }
466
467 if (p_dict.has("description")) {
468 doc.description = p_dict["description"];
469 }
470
471 if (p_dict.has("default_value")) {
472 doc.default_value = p_dict["default_value"];
473 }
474
475 return doc;
476 }
477 static Dictionary to_dict(const ThemeItemDoc &p_doc) {
478 Dictionary dict;
479
480 if (!p_doc.name.is_empty()) {
481 dict["name"] = p_doc.name;
482 }
483
484 if (!p_doc.type.is_empty()) {
485 dict["type"] = p_doc.type;
486 }
487
488 if (!p_doc.data_type.is_empty()) {
489 dict["data_type"] = p_doc.data_type;
490 }
491
492 if (!p_doc.description.is_empty()) {
493 dict["description"] = p_doc.description;
494 }
495
496 if (!p_doc.default_value.is_empty()) {
497 dict["default_value"] = p_doc.default_value;
498 }
499
500 return dict;
501 }
502 };
503
504 struct TutorialDoc {
505 String link;
506 String title;
507 static TutorialDoc from_dict(const Dictionary &p_dict) {
508 TutorialDoc doc;
509
510 if (p_dict.has("link")) {
511 doc.link = p_dict["link"];
512 }
513
514 if (p_dict.has("title")) {
515 doc.title = p_dict["title"];
516 }
517
518 return doc;
519 }
520 static Dictionary to_dict(const TutorialDoc &p_doc) {
521 Dictionary dict;
522
523 if (!p_doc.link.is_empty()) {
524 dict["link"] = p_doc.link;
525 }
526
527 if (!p_doc.title.is_empty()) {
528 dict["title"] = p_doc.title;
529 }
530
531 return dict;
532 }
533 };
534
535 struct EnumDoc {
536 String description;
537 bool is_deprecated = false;
538 bool is_experimental = false;
539 static EnumDoc from_dict(const Dictionary &p_dict) {
540 EnumDoc doc;
541
542 if (p_dict.has("description")) {
543 doc.description = p_dict["description"];
544 }
545
546 if (p_dict.has("is_deprecated")) {
547 doc.is_deprecated = p_dict["is_deprecated"];
548 }
549
550 if (p_dict.has("is_experimental")) {
551 doc.is_experimental = p_dict["is_experimental"];
552 }
553
554 return doc;
555 }
556 static Dictionary to_dict(const EnumDoc &p_doc) {
557 Dictionary dict;
558
559 if (!p_doc.description.is_empty()) {
560 dict["description"] = p_doc.description;
561 }
562
563 dict["is_deprecated"] = p_doc.is_deprecated;
564
565 dict["is_experimental"] = p_doc.is_experimental;
566
567 return dict;
568 }
569 };
570
571 struct ClassDoc {
572 String name;
573 String inherits;
574 String brief_description;
575 String description;
576 Vector<TutorialDoc> tutorials;
577 Vector<MethodDoc> constructors;
578 Vector<MethodDoc> methods;
579 Vector<MethodDoc> operators;
580 Vector<MethodDoc> signals;
581 Vector<ConstantDoc> constants;
582 HashMap<String, EnumDoc> enums;
583 Vector<PropertyDoc> properties;
584 Vector<MethodDoc> annotations;
585 Vector<ThemeItemDoc> theme_properties;
586 bool is_deprecated = false;
587 bool is_experimental = false;
588 bool is_script_doc = false;
589 String script_path;
590 bool operator<(const ClassDoc &p_class) const {
591 return name < p_class.name;
592 }
593 static ClassDoc from_dict(const Dictionary &p_dict) {
594 ClassDoc doc;
595
596 if (p_dict.has("name")) {
597 doc.name = p_dict["name"];
598 }
599
600 if (p_dict.has("inherits")) {
601 doc.inherits = p_dict["inherits"];
602 }
603
604 if (p_dict.has("brief_description")) {
605 doc.brief_description = p_dict["brief_description"];
606 }
607
608 if (p_dict.has("description")) {
609 doc.description = p_dict["description"];
610 }
611
612 Array tutorials;
613 if (p_dict.has("tutorials")) {
614 tutorials = p_dict["tutorials"];
615 }
616 for (int i = 0; i < tutorials.size(); i++) {
617 doc.tutorials.push_back(TutorialDoc::from_dict(tutorials[i]));
618 }
619
620 Array constructors;
621 if (p_dict.has("constructors")) {
622 constructors = p_dict["constructors"];
623 }
624 for (int i = 0; i < constructors.size(); i++) {
625 doc.constructors.push_back(MethodDoc::from_dict(constructors[i]));
626 }
627
628 Array methods;
629 if (p_dict.has("methods")) {
630 methods = p_dict["methods"];
631 }
632 for (int i = 0; i < methods.size(); i++) {
633 doc.methods.push_back(MethodDoc::from_dict(methods[i]));
634 }
635
636 Array operators;
637 if (p_dict.has("operators")) {
638 operators = p_dict["operators"];
639 }
640 for (int i = 0; i < operators.size(); i++) {
641 doc.operators.push_back(MethodDoc::from_dict(operators[i]));
642 }
643
644 Array signals;
645 if (p_dict.has("signals")) {
646 signals = p_dict["signals"];
647 }
648 for (int i = 0; i < signals.size(); i++) {
649 doc.signals.push_back(MethodDoc::from_dict(signals[i]));
650 }
651
652 Array constants;
653 if (p_dict.has("constants")) {
654 constants = p_dict["constants"];
655 }
656 for (int i = 0; i < constants.size(); i++) {
657 doc.constants.push_back(ConstantDoc::from_dict(constants[i]));
658 }
659
660 Dictionary enums;
661 if (p_dict.has("enums")) {
662 enums = p_dict["enums"];
663 }
664 for (int i = 0; i < enums.size(); i++) {
665 doc.enums[enums.get_key_at_index(i)] = EnumDoc::from_dict(enums.get_value_at_index(i));
666 }
667
668 Array properties;
669 if (p_dict.has("properties")) {
670 properties = p_dict["properties"];
671 }
672 for (int i = 0; i < properties.size(); i++) {
673 doc.properties.push_back(PropertyDoc::from_dict(properties[i]));
674 }
675
676 Array annotations;
677 if (p_dict.has("annotations")) {
678 annotations = p_dict["annotations"];
679 }
680 for (int i = 0; i < annotations.size(); i++) {
681 doc.annotations.push_back(MethodDoc::from_dict(annotations[i]));
682 }
683
684 Array theme_properties;
685 if (p_dict.has("theme_properties")) {
686 theme_properties = p_dict["theme_properties"];
687 }
688 for (int i = 0; i < theme_properties.size(); i++) {
689 doc.theme_properties.push_back(ThemeItemDoc::from_dict(theme_properties[i]));
690 }
691
692 if (p_dict.has("is_deprecated")) {
693 doc.is_deprecated = p_dict["is_deprecated"];
694 }
695
696 if (p_dict.has("is_experimental")) {
697 doc.is_experimental = p_dict["is_experimental"];
698 }
699
700 if (p_dict.has("is_script_doc")) {
701 doc.is_script_doc = p_dict["is_script_doc"];
702 }
703
704 if (p_dict.has("script_path")) {
705 doc.script_path = p_dict["script_path"];
706 }
707
708 return doc;
709 }
710 static Dictionary to_dict(const ClassDoc &p_doc) {
711 Dictionary dict;
712
713 if (!p_doc.name.is_empty()) {
714 dict["name"] = p_doc.name;
715 }
716
717 if (!p_doc.inherits.is_empty()) {
718 dict["inherits"] = p_doc.inherits;
719 }
720
721 if (!p_doc.brief_description.is_empty()) {
722 dict["brief_description"] = p_doc.brief_description;
723 }
724
725 if (!p_doc.description.is_empty()) {
726 dict["description"] = p_doc.description;
727 }
728
729 if (!p_doc.tutorials.is_empty()) {
730 Array tutorials;
731 for (int i = 0; i < p_doc.tutorials.size(); i++) {
732 tutorials.push_back(TutorialDoc::to_dict(p_doc.tutorials[i]));
733 }
734 dict["tutorials"] = tutorials;
735 }
736
737 if (!p_doc.constructors.is_empty()) {
738 Array constructors;
739 for (int i = 0; i < p_doc.constructors.size(); i++) {
740 constructors.push_back(MethodDoc::to_dict(p_doc.constructors[i]));
741 }
742 dict["constructors"] = constructors;
743 }
744
745 if (!p_doc.methods.is_empty()) {
746 Array methods;
747 for (int i = 0; i < p_doc.methods.size(); i++) {
748 methods.push_back(MethodDoc::to_dict(p_doc.methods[i]));
749 }
750 dict["methods"] = methods;
751 }
752
753 if (!p_doc.operators.is_empty()) {
754 Array operators;
755 for (int i = 0; i < p_doc.operators.size(); i++) {
756 operators.push_back(MethodDoc::to_dict(p_doc.operators[i]));
757 }
758 dict["operators"] = operators;
759 }
760
761 if (!p_doc.signals.is_empty()) {
762 Array signals;
763 for (int i = 0; i < p_doc.signals.size(); i++) {
764 signals.push_back(MethodDoc::to_dict(p_doc.signals[i]));
765 }
766 dict["signals"] = signals;
767 }
768
769 if (!p_doc.constants.is_empty()) {
770 Array constants;
771 for (int i = 0; i < p_doc.constants.size(); i++) {
772 constants.push_back(ConstantDoc::to_dict(p_doc.constants[i]));
773 }
774 dict["constants"] = constants;
775 }
776
777 if (!p_doc.enums.is_empty()) {
778 Dictionary enums;
779 for (const KeyValue<String, EnumDoc> &E : p_doc.enums) {
780 enums[E.key] = EnumDoc::to_dict(E.value);
781 }
782 dict["enums"] = enums;
783 }
784
785 if (!p_doc.properties.is_empty()) {
786 Array properties;
787 for (int i = 0; i < p_doc.properties.size(); i++) {
788 properties.push_back(PropertyDoc::to_dict(p_doc.properties[i]));
789 }
790 dict["properties"] = properties;
791 }
792
793 if (!p_doc.annotations.is_empty()) {
794 Array annotations;
795 for (int i = 0; i < p_doc.annotations.size(); i++) {
796 annotations.push_back(MethodDoc::to_dict(p_doc.annotations[i]));
797 }
798 dict["annotations"] = annotations;
799 }
800
801 if (!p_doc.theme_properties.is_empty()) {
802 Array theme_properties;
803 for (int i = 0; i < p_doc.theme_properties.size(); i++) {
804 theme_properties.push_back(ThemeItemDoc::to_dict(p_doc.theme_properties[i]));
805 }
806 dict["theme_properties"] = theme_properties;
807 }
808
809 dict["is_deprecated"] = p_doc.is_deprecated;
810
811 dict["is_experimental"] = p_doc.is_experimental;
812
813 dict["is_script_doc"] = p_doc.is_script_doc;
814
815 if (!p_doc.script_path.is_empty()) {
816 dict["script_path"] = p_doc.script_path;
817 }
818
819 return dict;
820 }
821 };
822
823 static String get_default_value_string(const Variant &p_value);
824
825 static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo);
826 static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo);
827 static void property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo);
828 static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc);
829 static void constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc);
830 static void signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc);
831};
832
833#endif // DOC_DATA_H
834