Repository: godotengine/godot
File: editor/doc/doc_tools.cpp (C++)

Code before:
			cd.enumeration = CoreConstants::get_global_constant_enum(i);
			cd.is_bitfield = CoreConstants::is_global_constant_bitfield(i);
			if (!CoreConstants::get_ignore_value_in_docs(i)) {
				cd.value = itos(CoreConstants::get_global_constant_value(i));
				cd.is_value_valid = true;
			} else {
				cd.is_value_valid = false;
			}
			c.constants.push_back(cd);
		}

		// Servers/engine singletons.
		List<Engine::Singleton> singletons;
		Engine::get_singleton()->get_singletons(&singletons);

		// FIXME: this is kind of hackish...
		for (const Engine::Singleton &s : singletons) {
			DocData::PropertyDoc pd;
			if (!s.ptr) {
				continue;
			}
			pd.name = s.name;
			pd.type = s.ptr->get_class();
			c.properties.push_back(pd);
		}

		c.properties.sort();

		// Variant utility functions.
		List<StringName> utility_functions;
		Variant::get_utility_function_list(&utility_functions);
		for (const StringName &E : utility_functions) {
			DocData::MethodDoc md;
			md.name = E;
			// Utility function's return type.
			if (Variant::has_utility_function_return_value(E)) {
				PropertyInfo pi;
				pi.type = Variant::get_utility_function_return_type(E);
				if (pi.type == Variant::NIL) {
					pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
				}
				DocData::ArgumentDoc ad;
				DocData::argument_doc_from_arginfo(ad, pi);
				md.return_type = ad.type;
			} else {
				md.return_type = "void";
			}

			// Utility function's arguments.
			if (Variant::is_utility_function_vararg(E)) {
				md.qualifiers = "vararg";

Review comment (suggestion):
This dates back to GODOT IS OPENSOURCE and does not make any sense to me. Singletons should just be documented with their type.

Although I'm not 100% certain if their might be some GDExtension concern with this.

Code after:
			cd.enumeration = CoreConstants::get_global_constant_enum(i);
			cd.is_bitfield = CoreConstants::is_global_constant_bitfield(i);
			if (!CoreConstants::get_ignore_value_in_docs(i)) {
				cd.value = itos(CoreConstants::get_global_constant_value(i));
				cd.is_value_valid = true;
			} else {
				cd.is_value_valid = false;
			}
			c.constants.push_back(cd);
		}

		// Servers/engine singletons.
		List<Engine::Singleton> singletons;
		Engine::get_singleton()->get_singletons(&singletons);

		// FIXME: this is kind of hackish...
		for (const Engine::Singleton &s : singletons) {
			DocData::PropertyDoc pd;
			if (!s.ptr) {
				continue;
			}
			pd.name = s.name;
			pd.type = s.ptr->get_class();
			while (!ClassDB::is_class_exposed(pd.type)) {
				pd.type = ClassDB::get_parent_class(pd.type);
			}
			c.properties.push_back(pd);
		}

		c.properties.sort();

		// Variant utility functions.
		List<StringName> utility_functions;
		Variant::get_utility_function_list(&utility_functions);
		for (const StringName &E : utility_functions) {
			DocData::MethodDoc md;
			md.name = E;
			// Utility function's return type.
			if (Variant::has_utility_function_return_value(E)) {
				PropertyInfo pi;
				pi.type = Variant::get_utility_function_return_type(E);
				if (pi.type == Variant::NIL) {
					pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
				}
				DocData::ArgumentDoc ad;
				DocData::argument_doc_from_arginfo(ad, pi);
				md.return_type = ad.type;
			} else {
				md.return_type = "void";
			}