| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | /*  doc_tools.cpp                                                        */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | #include "doc_tools.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/config/engine.h"
 | 
					
						
							|  |  |  | #include "core/config/project_settings.h"
 | 
					
						
							|  |  |  | #include "core/core_constants.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/io/compression.h"
 | 
					
						
							|  |  |  | #include "core/io/marshalls.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/object/script_language.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/dir_access.h"
 | 
					
						
							|  |  |  | #include "core/version.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | #include "scene/resources/theme.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 17:57:38 +02:00
										 |  |  | // Used for a hack preserving Mono properties on non-Mono builds.
 | 
					
						
							|  |  |  | #include "modules/modules_enabled.gen.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | void DocTools::merge_from(const DocTools &p_data) { | 
					
						
							|  |  |  | 	for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = E->get(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (!p_data.class_list.has(c.name)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		const DocData::ClassDoc &cf = p_data.class_list[c.name]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		c.description = cf.description; | 
					
						
							|  |  |  | 		c.brief_description = cf.brief_description; | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		c.tutorials = cf.tutorials; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.methods.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::MethodDoc &m = c.methods.write[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < cf.methods.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (cf.methods[j].name != m.name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (cf.methods[j].arguments.size() != m.arguments.size()) { | 
					
						
							| 
									
										
										
										
											2015-04-22 00:25:13 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 				// since polymorphic functions are allowed we need to check the type of
 | 
					
						
							|  |  |  | 				// the arguments so we make sure they are different.
 | 
					
						
							|  |  |  | 				int arg_count = cf.methods[j].arguments.size(); | 
					
						
							| 
									
										
										
										
											2016-05-04 11:46:28 -03:00
										 |  |  | 				Vector<bool> arg_used; | 
					
						
							|  |  |  | 				arg_used.resize(arg_count); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				for (int l = 0; l < arg_count; ++l) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 					arg_used.write[l] = false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 				// also there is no guarantee that argument ordering will match, so we
 | 
					
						
							|  |  |  | 				// have to check one by one so we make sure we have an exact match
 | 
					
						
							|  |  |  | 				for (int k = 0; k < arg_count; ++k) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					for (int l = 0; l < arg_count; ++l) { | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 						if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 							arg_used.write[l] = true; | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				bool not_the_same = false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				for (int l = 0; l < arg_count; ++l) { | 
					
						
							|  |  |  | 					if (!arg_used[l]) { // at least one of the arguments was different
 | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 						not_the_same = true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (not_the_same) { | 
					
						
							| 
									
										
										
										
											2016-05-03 01:45:54 -05:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-04-22 00:25:13 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::MethodDoc &mf = cf.methods[j]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				m.description = mf.description; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.signals.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::MethodDoc &m = c.signals.write[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < cf.signals.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (cf.signals[j].name != m.name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::MethodDoc &mf = cf.signals[j]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				m.description = mf.description; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.constants.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::ConstantDoc &m = c.constants.write[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < cf.constants.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (cf.constants[j].name != m.name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::ConstantDoc &mf = cf.constants[j]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				m.description = mf.description; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.properties.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::PropertyDoc &p = c.properties.write[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < cf.properties.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (cf.properties[j].name != p.name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::PropertyDoc &pf = cf.properties[j]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				p.description = pf.description; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.theme_properties.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::PropertyDoc &p = c.theme_properties.write[i]; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < cf.theme_properties.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (cf.theme_properties[j].name != p.name) { | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::PropertyDoc &pf = cf.theme_properties[j]; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				p.description = pf.description; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-20 17:57:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifndef MODULE_MONO_ENABLED
 | 
					
						
							|  |  |  | 		// The Mono module defines some properties that we want to keep when
 | 
					
						
							|  |  |  | 		// re-generating docs with a non-Mono build, to prevent pointless diffs
 | 
					
						
							|  |  |  | 		// (and loss of descriptions) depending on the config of the doc writer.
 | 
					
						
							|  |  |  | 		// We use a horrible hack to force keeping the relevant properties,
 | 
					
						
							|  |  |  | 		// hardcoded below. At least it's an ad hoc hack... ¯\_(ツ)_/¯
 | 
					
						
							|  |  |  | 		// Don't show this to your kids.
 | 
					
						
							|  |  |  | 		if (c.name == "@GlobalScope") { | 
					
						
							|  |  |  | 			// Retrieve GodotSharp singleton.
 | 
					
						
							|  |  |  | 			for (int j = 0; j < cf.properties.size(); j++) { | 
					
						
							|  |  |  | 				if (cf.properties[j].name == "GodotSharp") { | 
					
						
							|  |  |  | 					c.properties.push_back(cf.properties[j]); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | void DocTools::remove_from(const DocTools &p_data) { | 
					
						
							|  |  |  | 	for (Map<String, DocData::ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (class_list.has(E->key())) { | 
					
						
							| 
									
										
										
										
											2016-12-16 19:12:22 +08:00
										 |  |  | 			class_list.erase(E->key()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-16 19:12:22 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) { | 
					
						
							| 
									
										
										
										
											2020-11-29 08:07:57 +05:30
										 |  |  | 	ERR_FAIL_COND(p_class_doc.name == ""); | 
					
						
							|  |  |  | 	class_list[p_class_doc.name] = p_class_doc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | void DocTools::remove_doc(const String &p_class_name) { | 
					
						
							| 
									
										
										
										
											2020-11-29 08:07:57 +05:30
										 |  |  | 	ERR_FAIL_COND(p_class_name == "" || !class_list.has(p_class_name)); | 
					
						
							|  |  |  | 	class_list.erase(p_class_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | bool DocTools::has_doc(const String &p_class_name) { | 
					
						
							| 
									
										
										
										
											2020-11-29 08:07:57 +05:30
										 |  |  | 	if (p_class_name == "") { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return class_list.has(p_class_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | static Variant get_documentation_default_value(const StringName &p_class_name, const StringName &p_property_name, bool &r_default_value_valid) { | 
					
						
							|  |  |  | 	Variant default_value = Variant(); | 
					
						
							|  |  |  | 	r_default_value_valid = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ClassDB::can_instance(p_class_name)) { | 
					
						
							|  |  |  | 		default_value = ClassDB::class_get_default_property_value(p_class_name, p_property_name, &r_default_value_valid); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// Cannot get default value of classes that can't be instanced
 | 
					
						
							|  |  |  | 		List<StringName> inheriting_classes; | 
					
						
							|  |  |  | 		ClassDB::get_direct_inheriters_from_class(p_class_name, &inheriting_classes); | 
					
						
							|  |  |  | 		for (List<StringName>::Element *E2 = inheriting_classes.front(); E2; E2 = E2->next()) { | 
					
						
							|  |  |  | 			if (ClassDB::can_instance(E2->get())) { | 
					
						
							|  |  |  | 				default_value = ClassDB::class_get_default_property_value(E2->get(), p_property_name, &r_default_value_valid); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (r_default_value_valid) { | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return default_value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | void DocTools::generate(bool p_basic_types) { | 
					
						
							| 
									
										
										
										
											2015-06-29 00:29:49 -03:00
										 |  |  | 	List<StringName> classes; | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	ClassDB::get_class_list(&classes); | 
					
						
							| 
									
										
										
										
											2015-06-29 00:29:49 -03:00
										 |  |  | 	classes.sort_custom<StringName::AlphCompare>(); | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 	// Move ProjectSettings, so that other classes can register properties there.
 | 
					
						
							| 
									
										
										
										
											2020-01-22 22:37:56 +02:00
										 |  |  | 	classes.move_to_back(classes.find("ProjectSettings")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-24 12:32:59 -03:00
										 |  |  | 	bool skip_setter_getter_methods = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (classes.size()) { | 
					
						
							| 
									
										
										
										
											2017-11-24 13:59:43 -03:00
										 |  |  | 		Set<StringName> setters_getters; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		String name = classes.front()->get(); | 
					
						
							| 
									
										
										
										
											2020-04-20 12:29:34 +02:00
										 |  |  | 		if (!ClassDB::is_class_exposed(name)) { | 
					
						
							|  |  |  | 			print_verbose(vformat("Class '%s' is not exposed, skipping.", name)); | 
					
						
							|  |  |  | 			classes.pop_front(); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		String cname = name; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (cname.begins_with("_")) { //proxy class
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			cname = cname.substr(1, name.length()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		class_list[cname] = DocData::ClassDoc(); | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = class_list[cname]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		c.name = cname; | 
					
						
							|  |  |  | 		c.inherits = ClassDB::get_parent_class(name); | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		List<PropertyInfo> properties; | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 		List<PropertyInfo> own_properties; | 
					
						
							| 
									
										
										
										
											2018-06-13 14:42:55 +02:00
										 |  |  | 		if (name == "ProjectSettings") { | 
					
						
							| 
									
										
										
										
											2018-06-11 13:41:16 -03:00
										 |  |  | 			//special case for project settings, so settings can be documented
 | 
					
						
							|  |  |  | 			ProjectSettings::get_singleton()->get_property_list(&properties); | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			own_properties = properties; | 
					
						
							| 
									
										
										
										
											2018-06-11 13:41:16 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			ClassDB::get_property_list(name, &properties); | 
					
						
							|  |  |  | 			ClassDB::get_property_list(name, &own_properties, true); | 
					
						
							| 
									
										
										
										
											2018-06-11 13:41:16 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 		List<PropertyInfo>::Element *EO = own_properties.front(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			bool inherited = EO == nullptr; | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			if (EO && EO->get() == E->get()) { | 
					
						
							|  |  |  | 				inherited = false; | 
					
						
							|  |  |  | 				EO = EO->next(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) { | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::PropertyDoc prop; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			prop.name = E->get().name; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			prop.overridden = inherited; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 15:51:33 +03:00
										 |  |  | 			bool default_value_valid = false; | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 			Variant default_value; | 
					
						
							| 
									
										
										
										
											2019-06-29 15:51:33 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 			if (name == "ProjectSettings") { | 
					
						
							|  |  |  | 				// Special case for project settings, so that settings are not taken from the current project's settings
 | 
					
						
							| 
									
										
										
										
											2020-07-15 18:33:34 +02:00
										 |  |  | 				if (E->get().name == "script" || !ProjectSettings::get_singleton()->is_builtin_setting(E->get().name)) { | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (E->get().usage & PROPERTY_USAGE_EDITOR) { | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 					if (!ProjectSettings::get_singleton()->get_ignore_value_in_docs(E->get().name)) { | 
					
						
							|  |  |  | 						default_value = ProjectSettings::get_singleton()->property_get_revert(E->get().name); | 
					
						
							|  |  |  | 						default_value_valid = true; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				default_value = get_documentation_default_value(name, E->get().name, default_value_valid); | 
					
						
							|  |  |  | 				if (inherited) { | 
					
						
							|  |  |  | 					bool base_default_value_valid = false; | 
					
						
							|  |  |  | 					Variant base_default_value = get_documentation_default_value(ClassDB::get_parent_class(name), E->get().name, base_default_value_valid); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (!default_value_valid || !base_default_value_valid || default_value == base_default_value) { | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 						continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-01-22 15:22:21 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 			//used to track uninitialized values using valgrind
 | 
					
						
							|  |  |  | 			//print_line("getting default value for " + String(name) + "." + String(E->get().name));
 | 
					
						
							| 
									
										
										
										
											2019-07-12 21:17:12 +03:00
										 |  |  | 			if (default_value_valid && default_value.get_type() != Variant::OBJECT) { | 
					
						
							|  |  |  | 				prop.default_value = default_value.get_construct_string().replace("\n", ""); | 
					
						
							| 
									
										
										
										
											2019-06-29 15:51:33 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 			StringName setter = ClassDB::get_property_setter(name, E->get().name); | 
					
						
							|  |  |  | 			StringName getter = ClassDB::get_property_getter(name, E->get().name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			prop.setter = setter; | 
					
						
							|  |  |  | 			prop.getter = getter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 			bool found_type = false; | 
					
						
							|  |  |  | 			if (getter != StringName()) { | 
					
						
							|  |  |  | 				MethodBind *mb = ClassDB::get_method(name, getter); | 
					
						
							|  |  |  | 				if (mb) { | 
					
						
							|  |  |  | 					PropertyInfo retinfo = mb->get_return_info(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					found_type = true; | 
					
						
							|  |  |  | 					if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { | 
					
						
							|  |  |  | 						prop.enumeration = retinfo.class_name; | 
					
						
							|  |  |  | 						prop.type = "int"; | 
					
						
							|  |  |  | 					} else if (retinfo.class_name != StringName()) { | 
					
						
							|  |  |  | 						prop.type = retinfo.class_name; | 
					
						
							| 
									
										
										
										
											2020-04-20 19:06:00 -03:00
										 |  |  | 					} else if (retinfo.type == Variant::ARRAY && retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { | 
					
						
							|  |  |  | 						prop.type = retinfo.hint_string + "[]"; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 					} else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { | 
					
						
							|  |  |  | 						prop.type = retinfo.hint_string; | 
					
						
							|  |  |  | 					} else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { | 
					
						
							|  |  |  | 						prop.type = "Variant"; | 
					
						
							|  |  |  | 					} else if (retinfo.type == Variant::NIL) { | 
					
						
							|  |  |  | 						prop.type = "void"; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						prop.type = Variant::get_type_name(retinfo.type); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-11-24 12:32:59 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				setters_getters.insert(getter); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (setter != StringName()) { | 
					
						
							|  |  |  | 				setters_getters.insert(setter); | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!found_type) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 					prop.type = E->get().hint_string; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 					prop.type = Variant::get_type_name(E->get().type); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			c.properties.push_back(prop); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		List<MethodInfo> method_list; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ClassDB::get_method_list(name, &method_list, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		method_list.sort(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (E->get().name == "" || (E->get().name[0] == '_' && !(E->get().flags & METHOD_FLAG_VIRTUAL))) { | 
					
						
							| 
									
										
										
										
											2017-03-24 21:45:31 +01:00
										 |  |  | 				continue; //hidden, don't count
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 16:10:09 +02:00
										 |  |  | 			if (skip_setter_getter_methods && setters_getters.has(E->get().name)) { | 
					
						
							|  |  |  | 				// Don't skip parametric setters and getters, i.e. method which require
 | 
					
						
							|  |  |  | 				// one or more parameters to define what property should be set or retrieved.
 | 
					
						
							| 
									
										
										
										
											2020-03-30 18:22:57 +02:00
										 |  |  | 				// E.g. CPUParticles3D::set_param(Parameter param, float value).
 | 
					
						
							| 
									
										
										
										
											2019-06-27 16:10:09 +02:00
										 |  |  | 				if (E->get().arguments.size() == 0 /* getter */ || (E->get().arguments.size() == 1 && E->get().return_val.type == Variant::NIL /* setter */)) { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-24 12:32:59 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::MethodDoc method; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			method.name = E->get().name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (E->get().flags & METHOD_FLAG_VIRTUAL) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				method.qualifiers = "virtual"; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-25 20:25:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (E->get().flags & METHOD_FLAG_CONST) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (method.qualifiers != "") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					method.qualifiers += " "; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				method.qualifiers += "const"; | 
					
						
							| 
									
										
										
										
											2021-02-24 10:56:34 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (E->get().flags & METHOD_FLAG_VARARG) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (method.qualifiers != "") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					method.qualifiers += " "; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				method.qualifiers += "vararg"; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-24 10:56:34 -03:00
										 |  |  | 			if (E->get().flags & METHOD_FLAG_STATIC) { | 
					
						
							|  |  |  | 				if (method.qualifiers != "") { | 
					
						
							|  |  |  | 					method.qualifiers += " "; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				method.qualifiers += "static"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int i = -1; i < E->get().arguments.size(); i++) { | 
					
						
							|  |  |  | 				if (i == -1) { | 
					
						
							| 
									
										
										
										
											2015-11-18 22:33:29 +11:00
										 |  |  | #ifdef DEBUG_METHODS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					DocData::return_doc_from_retinfo(method, E->get().return_val); | 
					
						
							| 
									
										
										
										
											2015-11-18 22:33:29 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-29 07:15:46 +02:00
										 |  |  | 					const PropertyInfo &arginfo = E->get().arguments[i]; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					DocData::ArgumentDoc argument; | 
					
						
							|  |  |  | 					DocData::argument_doc_from_arginfo(argument, arginfo); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 					int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); | 
					
						
							|  |  |  | 					if (darg_idx >= 0) { | 
					
						
							|  |  |  | 						Variant default_arg = E->get().default_arguments[darg_idx]; | 
					
						
							|  |  |  | 						argument.default_value = default_arg.get_construct_string(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					method.arguments.push_back(argument); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			c.methods.push_back(method); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		List<MethodInfo> signal_list; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ClassDB::get_signal_list(name, &signal_list, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (signal_list.size()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::MethodDoc signal; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				signal.name = EV->get().name; | 
					
						
							|  |  |  | 				for (int i = 0; i < EV->get().arguments.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 					const PropertyInfo &arginfo = EV->get().arguments[i]; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					DocData::ArgumentDoc argument; | 
					
						
							|  |  |  | 					DocData::argument_doc_from_arginfo(argument, arginfo); | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					signal.arguments.push_back(argument); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				c.signals.push_back(signal); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		List<String> constant_list; | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 		ClassDB::get_integer_constant_list(name, &constant_list, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::ConstantDoc constant; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			constant.name = E->get(); | 
					
						
							|  |  |  | 			constant.value = itos(ClassDB::get_integer_constant(name, E->get())); | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 			constant.is_value_valid = true; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 			constant.enumeration = ClassDB::get_integer_constant_enum(name, E->get()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			c.constants.push_back(constant); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 		//theme stuff
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			List<StringName> l; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Theme::get_default()->get_constant_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							|  |  |  | 				pd.type = "int"; | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 				pd.default_value = itos(Theme::get_default()->get_constant(E->get(), cname)); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			l.clear(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Theme::get_default()->get_color_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							|  |  |  | 				pd.type = "Color"; | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 				pd.default_value = Variant(Theme::get_default()->get_color(E->get(), cname)).get_construct_string(); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			l.clear(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Theme::get_default()->get_icon_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							| 
									
										
										
										
											2019-06-11 15:43:37 -03:00
										 |  |  | 				pd.type = "Texture2D"; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			l.clear(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Theme::get_default()->get_font_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							|  |  |  | 				pd.type = "Font"; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			l.clear(); | 
					
						
							| 
									
										
										
										
											2020-09-03 14:22:16 +03:00
										 |  |  | 			Theme::get_default()->get_font_size_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2020-09-03 14:22:16 +03:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							|  |  |  | 				pd.type = "int"; | 
					
						
							|  |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			l.clear(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Theme::get_default()->get_stylebox_list(cname, &l); | 
					
						
							|  |  |  | 			for (List<StringName>::Element *E = l.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.name = E->get(); | 
					
						
							|  |  |  | 				pd.type = "StyleBox"; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 				c.theme_properties.push_back(pd); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		classes.pop_front(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 19:54:22 -03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 		// So we can document the concept of Variant even if it's not a usable class per se.
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		class_list["Variant"] = DocData::ClassDoc(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		class_list["Variant"].name = "Variant"; | 
					
						
							| 
									
										
										
										
											2016-06-29 19:54:22 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!p_basic_types) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 	// Add Variant types.
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < Variant::VARIANT_MAX; i++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (i == Variant::NIL) { | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 			continue; // Not exposed outside of 'null', should not be in class list.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (i == Variant::OBJECT) { | 
					
						
							| 
									
										
										
										
											2020-01-26 15:18:06 +01:00
										 |  |  | 			continue; // Use the core type instead.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		String cname = Variant::get_type_name(Variant::Type(i)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		class_list[cname] = DocData::ClassDoc(); | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = class_list[cname]; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		c.name = cname; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		Callable::CallError cerror; | 
					
						
							| 
									
										
										
										
											2020-11-09 00:19:09 -03:00
										 |  |  | 		Variant v; | 
					
						
							|  |  |  | 		Variant::construct(Variant::Type(i), v, nullptr, 0, cerror); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		List<MethodInfo> method_list; | 
					
						
							|  |  |  | 		v.get_method_list(&method_list); | 
					
						
							|  |  |  | 		method_list.sort(); | 
					
						
							|  |  |  | 		Variant::get_constructor_list(Variant::Type(i), &method_list); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 14:13:16 +01:00
										 |  |  | 		for (int j = 0; j < Variant::OP_AND; j++) { // Showing above 'and' is pretty confusing and there are a lot of variations.
 | 
					
						
							| 
									
										
										
										
											2020-11-09 14:11:15 -03:00
										 |  |  | 			for (int k = 0; k < Variant::VARIANT_MAX; k++) { | 
					
						
							|  |  |  | 				Variant::Type rt = Variant::get_operator_return_type(Variant::Operator(j), Variant::Type(i), Variant::Type(k)); | 
					
						
							| 
									
										
										
										
											2020-11-10 14:13:16 +01:00
										 |  |  | 				if (rt != Variant::NIL) { // Has operator.
 | 
					
						
							|  |  |  | 					// Skip String % operator as it's registered separately for each Variant arg type,
 | 
					
						
							|  |  |  | 					// we'll add it manually below.
 | 
					
						
							|  |  |  | 					if (i == Variant::STRING && Variant::Operator(j) == Variant::OP_MODULE) { | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-11-09 14:11:15 -03:00
										 |  |  | 					MethodInfo mi; | 
					
						
							|  |  |  | 					mi.name = "operator " + Variant::get_operator_name(Variant::Operator(j)); | 
					
						
							|  |  |  | 					mi.return_val.type = rt; | 
					
						
							|  |  |  | 					if (k != Variant::NIL) { | 
					
						
							|  |  |  | 						PropertyInfo arg; | 
					
						
							|  |  |  | 						arg.name = "right"; | 
					
						
							|  |  |  | 						arg.type = Variant::Type(k); | 
					
						
							|  |  |  | 						mi.arguments.push_back(arg); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					method_list.push_back(mi); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 14:13:16 +01:00
										 |  |  | 		if (i == Variant::STRING) { | 
					
						
							|  |  |  | 			// We skipped % operator above, and we register it manually once for Variant arg type here.
 | 
					
						
							|  |  |  | 			MethodInfo mi; | 
					
						
							|  |  |  | 			mi.name = "operator %"; | 
					
						
							|  |  |  | 			mi.return_val.type = Variant::STRING; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			PropertyInfo arg; | 
					
						
							|  |  |  | 			arg.name = "right"; | 
					
						
							|  |  |  | 			arg.type = Variant::NIL; | 
					
						
							|  |  |  | 			arg.usage = PROPERTY_USAGE_NIL_IS_VARIANT; | 
					
						
							|  |  |  | 			mi.arguments.push_back(arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			method_list.push_back(mi); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-09 14:11:15 -03:00
										 |  |  | 		if (Variant::is_keyed(Variant::Type(i))) { | 
					
						
							|  |  |  | 			MethodInfo mi; | 
					
						
							|  |  |  | 			mi.name = "operator []"; | 
					
						
							|  |  |  | 			mi.return_val.type = Variant::NIL; | 
					
						
							|  |  |  | 			mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			PropertyInfo arg; | 
					
						
							|  |  |  | 			arg.name = "key"; | 
					
						
							|  |  |  | 			arg.type = Variant::NIL; | 
					
						
							|  |  |  | 			arg.usage = PROPERTY_USAGE_NIL_IS_VARIANT; | 
					
						
							|  |  |  | 			mi.arguments.push_back(arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			method_list.push_back(mi); | 
					
						
							|  |  |  | 		} else if (Variant::has_indexing(Variant::Type(i))) { | 
					
						
							|  |  |  | 			MethodInfo mi; | 
					
						
							|  |  |  | 			mi.name = "operator []"; | 
					
						
							|  |  |  | 			mi.return_val.type = Variant::get_indexed_element_type(Variant::Type(i)); | 
					
						
							|  |  |  | 			PropertyInfo arg; | 
					
						
							|  |  |  | 			arg.name = "index"; | 
					
						
							|  |  |  | 			arg.type = Variant::INT; | 
					
						
							|  |  |  | 			mi.arguments.push_back(arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			method_list.push_back(mi); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 			MethodInfo &mi = E->get(); | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::MethodDoc method; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			method.name = mi.name; | 
					
						
							| 
									
										
										
										
											2020-11-09 14:11:15 -03:00
										 |  |  | 			if (method.name == cname) { | 
					
						
							|  |  |  | 				method.qualifiers = "constructor"; | 
					
						
							|  |  |  | 			} else if (method.name.begins_with("operator")) { | 
					
						
							|  |  |  | 				method.qualifiers = "operator"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			for (int j = 0; j < mi.arguments.size(); j++) { | 
					
						
							|  |  |  | 				PropertyInfo arginfo = mi.arguments[j]; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::ArgumentDoc ad; | 
					
						
							|  |  |  | 				DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); | 
					
						
							| 
									
										
										
										
											2017-08-29 07:15:46 +02:00
										 |  |  | 				ad.name = arginfo.name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 10:51:17 +01:00
										 |  |  | 				int darg_idx = mi.default_arguments.size() - mi.arguments.size() + j; | 
					
						
							|  |  |  | 				if (darg_idx >= 0) { | 
					
						
							|  |  |  | 					Variant default_arg = mi.default_arguments[darg_idx]; | 
					
						
							|  |  |  | 					ad.default_value = default_arg.get_construct_string(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-29 07:15:46 +02:00
										 |  |  | 				method.arguments.push_back(ad); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::return_doc_from_retinfo(method, mi.return_val); | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (mi.flags & METHOD_FLAG_VARARG) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (method.qualifiers != "") { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 					method.qualifiers += " "; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 				method.qualifiers += "vararg"; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-24 10:56:34 -03:00
										 |  |  | 			if (mi.flags & METHOD_FLAG_CONST) { | 
					
						
							|  |  |  | 				if (method.qualifiers != "") { | 
					
						
							|  |  |  | 					method.qualifiers += " "; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				method.qualifiers += "const"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (mi.flags & METHOD_FLAG_STATIC) { | 
					
						
							|  |  |  | 				if (method.qualifiers != "") { | 
					
						
							|  |  |  | 					method.qualifiers += " "; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				method.qualifiers += "static"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			c.methods.push_back(method); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		List<PropertyInfo> properties; | 
					
						
							|  |  |  | 		v.get_property_list(&properties); | 
					
						
							|  |  |  | 		for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 			PropertyInfo pi = E->get(); | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::PropertyDoc property; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			property.name = pi.name; | 
					
						
							|  |  |  | 			property.type = Variant::get_type_name(pi.type); | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 			property.default_value = v.get(pi.name).get_construct_string(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			c.properties.push_back(property); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		List<StringName> constants; | 
					
						
							| 
									
										
										
										
											2017-12-15 16:43:27 +01:00
										 |  |  | 		Variant::get_constants_for_type(Variant::Type(i), &constants); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::ConstantDoc constant; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			constant.name = E->get(); | 
					
						
							| 
									
										
										
										
											2017-12-15 16:43:27 +01:00
										 |  |  | 			Variant value = Variant::get_constant_value(Variant::Type(i), E->get()); | 
					
						
							|  |  |  | 			constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(); | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 			constant.is_value_valid = true; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			c.constants.push_back(constant); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//built in constants and functions
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-11-15 18:45:34 +01:00
										 |  |  | 		String cname = "@GlobalScope"; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		class_list[cname] = DocData::ClassDoc(); | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = class_list[cname]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		c.name = cname; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | 		for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::ConstantDoc cd; | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | 			cd.name = CoreConstants::get_global_constant_name(i); | 
					
						
							|  |  |  | 			if (!CoreConstants::get_ignore_value_in_docs(i)) { | 
					
						
							|  |  |  | 				cd.value = itos(CoreConstants::get_global_constant_value(i)); | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 				cd.is_value_valid = true; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				cd.is_value_valid = false; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | 			cd.enumeration = CoreConstants::get_global_constant_enum(i); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			c.constants.push_back(cd); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-13 21:46:57 +01:00
										 |  |  | 		List<Engine::Singleton> singletons; | 
					
						
							|  |  |  | 		Engine::get_singleton()->get_singletons(&singletons); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		//servers (this is kind of hackish)
 | 
					
						
							| 
									
										
										
										
											2017-11-13 21:46:57 +01:00
										 |  |  | 		for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::PropertyDoc pd; | 
					
						
							| 
									
										
										
										
											2017-11-13 21:46:57 +01:00
										 |  |  | 			Engine::Singleton &s = E->get(); | 
					
						
							| 
									
										
										
										
											2018-05-11 11:20:27 -07:00
										 |  |  | 			if (!s.ptr) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			pd.name = s.name; | 
					
						
							|  |  |  | 			pd.type = s.ptr->get_class(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			while (String(ClassDB::get_parent_class(pd.type)) != "Object") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.type = ClassDB::get_parent_class(pd.type); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (pd.type.begins_with("_")) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				pd.type = pd.type.substr(1, pd.type.length()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			c.properties.push_back(pd); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 		List<StringName> utility_functions; | 
					
						
							|  |  |  | 		Variant::get_utility_function_list(&utility_functions); | 
					
						
							|  |  |  | 		utility_functions.sort_custom<StringName::AlphCompare>(); | 
					
						
							|  |  |  | 		for (List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::MethodDoc md; | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 			md.name = E->get(); | 
					
						
							|  |  |  | 			//return
 | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 			if (Variant::has_utility_function_return_value(E->get())) { | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 				PropertyInfo pi; | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 				pi.type = Variant::get_utility_function_return_type(E->get()); | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 				if (pi.type == Variant::NIL) { | 
					
						
							|  |  |  | 					pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				DocData::ArgumentDoc ad; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::argument_doc_from_arginfo(ad, pi); | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 				md.return_type = ad.type; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 			if (Variant::is_utility_function_vararg(E->get())) { | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 				md.qualifiers = "vararg"; | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 				for (int i = 0; i < Variant::get_utility_function_argument_count(E->get()); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 					PropertyInfo pi; | 
					
						
							| 
									
										
										
										
											2020-11-11 13:16:08 -03:00
										 |  |  | 					pi.type = Variant::get_utility_function_argument_type(E->get(), i); | 
					
						
							|  |  |  | 					pi.name = Variant::get_utility_function_argument_name(E->get(), i); | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 					if (pi.type == Variant::NIL) { | 
					
						
							|  |  |  | 						pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					DocData::ArgumentDoc ad; | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					DocData::argument_doc_from_arginfo(ad, pi); | 
					
						
							| 
									
										
										
										
											2020-11-10 18:31:33 -03:00
										 |  |  | 					md.arguments.push_back(ad); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			c.methods.push_back(md); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 15:06:13 +02:00
										 |  |  | 	// Built-in script reference.
 | 
					
						
							|  |  |  | 	// We only add a doc entry for languages which actually define any built-in
 | 
					
						
							|  |  |  | 	// methods or constants.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < ScriptServer::get_language_count(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			ScriptLanguage *lang = ScriptServer::get_language(i); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			String cname = "@" + lang->get_name(); | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::ClassDoc c; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			c.name = cname; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 15:06:13 +02:00
										 |  |  | 			// Get functions.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			List<MethodInfo> minfo; | 
					
						
							|  |  |  | 			lang->get_public_functions(&minfo); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 				MethodInfo &mi = E->get(); | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::MethodDoc md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				md.name = mi.name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-29 18:16:03 +02:00
										 |  |  | 				if (mi.flags & METHOD_FLAG_VARARG) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (md.qualifiers != "") { | 
					
						
							| 
									
										
										
										
											2017-08-29 18:16:03 +02:00
										 |  |  | 						md.qualifiers += " "; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-08-29 18:16:03 +02:00
										 |  |  | 					md.qualifiers += "vararg"; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::return_doc_from_retinfo(md, mi.return_val); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				for (int j = 0; j < mi.arguments.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					DocData::ArgumentDoc ad; | 
					
						
							|  |  |  | 					DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); | 
					
						
							| 
									
										
										
										
											2018-01-30 02:06:19 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 					int darg_idx = j - (mi.arguments.size() - mi.default_arguments.size()); | 
					
						
							| 
									
										
										
										
											2018-01-30 02:06:19 -02:00
										 |  |  | 					if (darg_idx >= 0) { | 
					
						
							|  |  |  | 						Variant default_arg = E->get().default_arguments[darg_idx]; | 
					
						
							|  |  |  | 						ad.default_value = default_arg.get_construct_string(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					md.arguments.push_back(ad); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				c.methods.push_back(md); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 15:06:13 +02:00
										 |  |  | 			// Get constants.
 | 
					
						
							| 
									
										
										
										
											2020-03-17 07:33:00 +01:00
										 |  |  | 			List<Pair<String, Variant>> cinfo; | 
					
						
							| 
									
										
										
										
											2014-02-22 20:28:19 -03:00
										 |  |  | 			lang->get_public_constants(&cinfo); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-17 07:33:00 +01:00
										 |  |  | 			for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				DocData::ConstantDoc cd; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				cd.name = E->get().first; | 
					
						
							|  |  |  | 				cd.value = E->get().second; | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 				cd.is_value_valid = true; | 
					
						
							| 
									
										
										
										
											2014-02-22 20:28:19 -03:00
										 |  |  | 				c.constants.push_back(cd); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-06-17 15:06:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// Skip adding the lang if it doesn't expose anything (e.g. C#).
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			if (c.methods.is_empty() && c.constants.is_empty()) { | 
					
						
							| 
									
										
										
										
											2020-06-17 15:06:13 +02:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			class_list[cname] = c; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &methods) { | 
					
						
							|  |  |  | 	String section = parser->get_node_name(); | 
					
						
							|  |  |  | 	String element = section.substr(0, section.length() - 1); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (parser->read() == OK) { | 
					
						
							|  |  |  | 		if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							|  |  |  | 			if (parser->get_node_name() == element) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				DocData::MethodDoc method; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							|  |  |  | 				method.name = parser->get_attribute_value("name"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (parser->has_attribute("qualifiers")) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					method.qualifiers = parser->get_attribute_value("qualifiers"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				while (parser->read() == OK) { | 
					
						
							|  |  |  | 					if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							|  |  |  | 						String name = parser->get_node_name(); | 
					
						
							|  |  |  | 						if (name == "return") { | 
					
						
							|  |  |  | 							ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); | 
					
						
							|  |  |  | 							method.return_type = parser->get_attribute_value("type"); | 
					
						
							| 
									
										
										
										
											2017-09-02 21:52:45 +02:00
										 |  |  | 							if (parser->has_attribute("enum")) { | 
					
						
							|  |  |  | 								method.return_enum = parser->get_attribute_value("enum"); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						} else if (name == "argument") { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							DocData::ArgumentDoc argument; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							|  |  |  | 							argument.name = parser->get_attribute_value("name"); | 
					
						
							|  |  |  | 							ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); | 
					
						
							|  |  |  | 							argument.type = parser->get_attribute_value("type"); | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 							if (parser->has_attribute("enum")) { | 
					
						
							|  |  |  | 								argument.enumeration = parser->get_attribute_value("enum"); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							method.arguments.push_back(argument); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						} else if (name == "description") { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 							if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 								method.description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == element) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				methods.push_back(method); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 				ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + parser->get_node_name() + "."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == section) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | Error DocTools::load_classes(const String &p_dir) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	Error err; | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 	DirAccessRef da = DirAccess::open(p_dir, &err); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	if (!da) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return err; | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	da->list_dir_begin(); | 
					
						
							|  |  |  | 	String path; | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 	path = da->get_next(); | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 	while (path != String()) { | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 		if (!da->current_is_dir() && path.ends_with("xml")) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 			Ref<XMLParser> parser = memnew(XMLParser); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			Error err2 = parser->open(p_dir.plus_file(path)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (err2) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				return err2; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			_load(parser); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 		path = da->get_next(); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	da->list_dir_end(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | Error DocTools::erase_classes(const String &p_dir) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	Error err; | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 	DirAccessRef da = DirAccess::open(p_dir, &err); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	if (!da) { | 
					
						
							|  |  |  | 		return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	List<String> to_erase; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	da->list_dir_begin(); | 
					
						
							|  |  |  | 	String path; | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 	path = da->get_next(); | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 	while (path != String()) { | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 		if (!da->current_is_dir() && path.ends_with("xml")) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 			to_erase.push_back(path); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-25 11:09:57 +02:00
										 |  |  | 		path = da->get_next(); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	da->list_dir_end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 	while (to_erase.size()) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		da->remove(to_erase.front()->get()); | 
					
						
							|  |  |  | 		to_erase.pop_front(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | Error DocTools::_load(Ref<XMLParser> parser) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 	Error err = OK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while ((err = parser->read()) == OK) { | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "?xml") { | 
					
						
							|  |  |  | 			parser->skip_section(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (parser->get_node_type() != XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; //no idea what this may be, but skipping anyway
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND_V(parser->get_node_name() != "class", ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		String name = parser->get_attribute_value("name"); | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 		class_list[name] = DocData::ClassDoc(); | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = class_list[name]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		c.name = name; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (parser->has_attribute("inherits")) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			c.inherits = parser->get_attribute_value("inherits"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while (parser->read() == OK) { | 
					
						
							|  |  |  | 			if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				String name2 = parser->get_node_name(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				if (name2 == "brief_description") { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 						c.brief_description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "description") { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 						c.description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "tutorials") { | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 					while (parser->read() == OK) { | 
					
						
							|  |  |  | 						if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							String name3 = parser->get_node_name(); | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							if (name3 == "link") { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 								DocData::TutorialDoc tutorial; | 
					
						
							| 
									
										
										
										
											2020-06-06 22:26:35 -03:00
										 |  |  | 								if (parser->has_attribute("title")) { | 
					
						
							|  |  |  | 									tutorial.title = parser->get_attribute_value("title"); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 								parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2020-06-06 22:26:35 -03:00
										 |  |  | 									tutorial.link = parser->get_node_data().strip_edges(); | 
					
						
							|  |  |  | 									c.tutorials.push_back(tutorial); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 							} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 								ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + "."); | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "tutorials") { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 							break; // End of <tutorials>.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "methods") { | 
					
						
							|  |  |  | 					Error err2 = _parse_methods(parser, c.methods); | 
					
						
							|  |  |  | 					ERR_FAIL_COND_V(err2, err2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "signals") { | 
					
						
							|  |  |  | 					Error err2 = _parse_methods(parser, c.signals); | 
					
						
							|  |  |  | 					ERR_FAIL_COND_V(err2, err2); | 
					
						
							|  |  |  | 				} else if (name2 == "members") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					while (parser->read() == OK) { | 
					
						
							|  |  |  | 						if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							String name3 = parser->get_node_name(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							if (name3 == "member") { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 								DocData::PropertyDoc prop2; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								prop2.name = parser->get_attribute_value("name"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								prop2.type = parser->get_attribute_value("type"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								if (parser->has_attribute("setter")) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 									prop2.setter = parser->get_attribute_value("setter"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								if (parser->has_attribute("getter")) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 									prop2.getter = parser->get_attribute_value("getter"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								} | 
					
						
							|  |  |  | 								if (parser->has_attribute("enum")) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 									prop2.enumeration = parser->get_attribute_value("enum"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								if (!parser->is_empty()) { | 
					
						
							|  |  |  | 									parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 										prop2.description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								c.properties.push_back(prop2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 								ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + "."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "members") { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 							break; // End of <members>.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "theme_items") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					while (parser->read() == OK) { | 
					
						
							|  |  |  | 						if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							String name3 = parser->get_node_name(); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							if (name3 == "theme_item") { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 								DocData::PropertyDoc prop2; | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								prop2.name = parser->get_attribute_value("name"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								prop2.type = parser->get_attribute_value("type"); | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								if (!parser->is_empty()) { | 
					
						
							|  |  |  | 									parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 										prop2.description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								c.theme_properties.push_back(prop2); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 							} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 								ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + "."); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "theme_items") { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 							break; // End of <theme_items>.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 				} else if (name2 == "constants") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					while (parser->read() == OK) { | 
					
						
							|  |  |  | 						if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							String name3 = parser->get_node_name(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 							if (name3 == "constant") { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 								DocData::ConstantDoc constant2; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								constant2.name = parser->get_attribute_value("name"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 								ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								constant2.value = parser->get_attribute_value("value"); | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 								constant2.is_value_valid = true; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 								if (parser->has_attribute("enum")) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 									constant2.enumeration = parser->get_attribute_value("enum"); | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								if (!parser->is_empty()) { | 
					
						
							|  |  |  | 									parser->read(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									if (parser->get_node_type() == XMLParser::NODE_TEXT) { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 										constant2.description = parser->get_node_data(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 								c.constants.push_back(constant2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 								ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + "."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "constants") { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 							break; // End of <constants>.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 					ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name2 + "."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "class") { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 				break; // End of <class>.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (p_string == "") { | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	String tab; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	for (int i = 0; i < p_tablevel; i++) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		tab += "\t"; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	f->store_string(tab + p_string + "\n"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | Error DocTools::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { | 
					
						
							|  |  |  | 	for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 		DocData::ClassDoc &c = E->get(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		String save_path; | 
					
						
							|  |  |  | 		if (p_class_path.has(c.name)) { | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 			save_path = p_class_path[c.name]; | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 			save_path = p_default_path; | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Error err; | 
					
						
							| 
									
										
										
										
											2017-09-12 23:06:26 +02:00
										 |  |  | 		String save_file = save_path.plus_file(c.name + ".xml"); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		FileAccessRef f = FileAccess::open(save_file, FileAccess::WRITE, &err); | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		ERR_CONTINUE_MSG(err != OK, "Can't write doc file: " + save_file + "."); | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		String header = "<class name=\"" + c.name + "\""; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (c.inherits != "") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			header += " inherits=\"" + c.inherits + "\""; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-02-14 17:38:20 +01:00
										 |  |  | 		header += String(" version=\"") + VERSION_BRANCH + "\""; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		header += ">"; | 
					
						
							|  |  |  | 		_write_string(f, 0, header); | 
					
						
							| 
									
										
										
										
											2020-01-26 16:01:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "<brief_description>"); | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 		_write_string(f, 2, c.brief_description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "</brief_description>"); | 
					
						
							| 
									
										
										
										
											2020-01-26 16:01:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "<description>"); | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 		_write_string(f, 2, c.description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "</description>"); | 
					
						
							| 
									
										
										
										
											2020-01-26 16:01:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		_write_string(f, 1, "<tutorials>"); | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 		for (int i = 0; i < c.tutorials.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			DocData::TutorialDoc tutorial = c.tutorials.get(i); | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 			String title_attribute = (!tutorial.title.is_empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : ""; | 
					
						
							| 
									
										
										
										
											2020-06-06 22:26:35 -03:00
										 |  |  | 			_write_string(f, 2, "<link" + title_attribute + ">" + tutorial.link.xml_escape() + "</link>"); | 
					
						
							| 
									
										
										
										
											2018-06-11 13:35:44 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-12 17:42:36 -03:00
										 |  |  | 		_write_string(f, 1, "</tutorials>"); | 
					
						
							| 
									
										
										
										
											2020-01-26 16:01:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "<methods>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 17:20:34 -03:00
										 |  |  | 		c.methods.sort(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.methods.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			const DocData::MethodDoc &m = c.methods[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			String qualifiers; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (m.qualifiers != "") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				qualifiers += " qualifiers=\"" + m.qualifiers.xml_escape() + "\""; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 14:13:16 +01:00
										 |  |  | 			_write_string(f, 2, "<method name=\"" + m.name.xml_escape() + "\"" + qualifiers + ">"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (m.return_type != "") { | 
					
						
							| 
									
										
										
										
											2017-09-02 21:52:45 +02:00
										 |  |  | 				String enum_text; | 
					
						
							|  |  |  | 				if (m.return_enum != String()) { | 
					
						
							|  |  |  | 					enum_text = " enum=\"" + m.return_enum + "\""; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				_write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + ">"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 3, "</return>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int j = 0; j < m.arguments.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::ArgumentDoc &a = m.arguments[j]; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				String enum_text; | 
					
						
							|  |  |  | 				if (a.enumeration != String()) { | 
					
						
							| 
									
										
										
										
											2017-08-25 20:25:17 +02:00
										 |  |  | 					enum_text = " enum=\"" + a.enumeration + "\""; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (a.default_value != "") { | 
					
						
							| 
									
										
										
										
											2017-08-25 20:25:17 +02:00
										 |  |  | 					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + " default=\"" + a.default_value.xml_escape(true) + "\">"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-25 20:25:17 +02:00
										 |  |  | 					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + ">"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 3, "</argument>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 3, "<description>"); | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 			_write_string(f, 4, m.description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 3, "</description>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 2, "</method>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "</methods>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (c.properties.size()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "<members>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 17:20:34 -03:00
										 |  |  | 			c.properties.sort(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int i = 0; i < c.properties.size(); i++) { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 				String additional_attributes; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 				if (c.properties[i].enumeration != String()) { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 					additional_attributes += " enum=\"" + c.properties[i].enumeration + "\""; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (c.properties[i].default_value != String()) { | 
					
						
							|  |  |  | 					additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\""; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::PropertyDoc &p = c.properties[i]; | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (c.properties[i].overridden) { | 
					
						
							| 
									
										
										
										
											2019-09-24 13:34:03 +02:00
										 |  |  | 					_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + " />"); | 
					
						
							| 
									
										
										
										
											2019-09-03 13:42:34 +03:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + additional_attributes + ">"); | 
					
						
							|  |  |  | 					_write_string(f, 3, p.description.strip_edges().xml_escape()); | 
					
						
							|  |  |  | 					_write_string(f, 2, "</member>"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "</members>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (c.signals.size()) { | 
					
						
							| 
									
										
										
										
											2016-06-21 17:20:34 -03:00
										 |  |  | 			c.signals.sort(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "<signals>"); | 
					
						
							|  |  |  | 			for (int i = 0; i < c.signals.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::MethodDoc &m = c.signals[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 2, "<signal name=\"" + m.name + "\">"); | 
					
						
							|  |  |  | 				for (int j = 0; j < m.arguments.size(); j++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 					const DocData::ArgumentDoc &a = m.arguments[j]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">"); | 
					
						
							|  |  |  | 					_write_string(f, 3, "</argument>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 3, "<description>"); | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 				_write_string(f, 4, m.description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 3, "</description>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 2, "</signal>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "</signals>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "<constants>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < c.constants.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 			const DocData::ConstantDoc &k = c.constants[i]; | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 			if (k.is_value_valid) { | 
					
						
							|  |  |  | 				if (k.enumeration != String()) { | 
					
						
							|  |  |  | 					_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">"); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-11-24 18:43:52 -03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-05-20 22:49:39 +03:00
										 |  |  | 				if (k.enumeration != String()) { | 
					
						
							|  |  |  | 					_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"platform-dependent\" enum=\"" + k.enumeration + "\">"); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"platform-dependent\">"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-08-23 19:10:32 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-11 09:11:24 +08:00
										 |  |  | 			_write_string(f, 3, k.description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 2, "</constant>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 1, "</constants>"); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (c.theme_properties.size()) { | 
					
						
							| 
									
										
										
										
											2016-06-21 17:20:34 -03:00
										 |  |  | 			c.theme_properties.sort(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "<theme_items>"); | 
					
						
							|  |  |  | 			for (int i = 0; i < c.theme_properties.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | 				const DocData::PropertyDoc &p = c.theme_properties[i]; | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (p.default_value != "") { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 					_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\" default=\"" + p.default_value.xml_escape(true) + "\">"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 					_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 12:57:35 +02:00
										 |  |  | 				_write_string(f, 3, p.description.strip_edges().xml_escape()); | 
					
						
							| 
									
										
										
										
											2019-06-01 16:42:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_write_string(f, 2, "</theme_item>"); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_write_string(f, 1, "</theme_items>"); | 
					
						
							| 
									
										
										
										
											2014-06-29 22:41:02 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_write_string(f, 0, "</class>"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-29 09:12:06 +05:30
										 |  |  | Error DocTools::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Vector<uint8_t> data; | 
					
						
							|  |  |  | 	data.resize(p_uncompressed_size); | 
					
						
							| 
									
										
										
										
											2017-11-25 00:07:54 -03:00
										 |  |  | 	Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	class_list.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Ref<XMLParser> parser = memnew(XMLParser); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	Error err = parser->open_buffer(data); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (err) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		return err; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	_load(parser); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } |