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 | |
37 | struct 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 | |
47 | class DocData { |
48 | public: |
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 | |