@ -205,6 +205,29 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (r_default_value_valid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
void DocData::generate(bool p_basic_types) {
|
||||
|
||||
List<StringName> classes;
|
||||
@ -229,47 +252,53 @@ void DocData::generate(bool p_basic_types) {
|
||||
c.category = ClassDB::get_category(name);
|
||||
|
||||
List<PropertyInfo> properties;
|
||||
List<PropertyInfo> own_properties;
|
||||
if (name == "ProjectSettings") {
|
||||
//special case for project settings, so settings can be documented
|
||||
ProjectSettings::get_singleton()->get_property_list(&properties);
|
||||
own_properties = properties;
|
||||
} else {
|
||||
ClassDB::get_property_list(name, &properties, true);
|
||||
ClassDB::get_property_list(name, &properties);
|
||||
ClassDB::get_property_list(name, &own_properties, true);
|
||||
}
|
||||
|
||||
List<PropertyInfo>::Element *EO = own_properties.front();
|
||||
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
|
||||
bool inherited = EO == NULL;
|
||||
if (EO && EO->get() == E->get()) {
|
||||
inherited = false;
|
||||
EO = EO->next();
|
||||
}
|
||||
|
||||
if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL)
|
||||
continue;
|
||||
|
||||
PropertyDoc prop;
|
||||
StringName setter = ClassDB::get_property_setter(name, E->get().name);
|
||||
StringName getter = ClassDB::get_property_getter(name, E->get().name);
|
||||
|
||||
prop.name = E->get().name;
|
||||
prop.setter = setter;
|
||||
prop.getter = getter;
|
||||
|
||||
Variant default_value = Variant();
|
||||
prop.overridden = inherited;
|
||||
|
||||
bool default_value_valid = false;
|
||||
Variant default_value = get_documentation_default_value(name, E->get().name, default_value_valid);
|
||||
|
||||
if (ClassDB::can_instance(name)) {
|
||||
default_value = ClassDB::class_get_default_property_value(name, E->get().name, &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(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(), E->get().name, &default_value_valid);
|
||||
if (default_value_valid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (!default_value_valid || !base_default_value_valid || default_value == base_default_value)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (default_value_valid && default_value.get_type() != Variant::OBJECT) {
|
||||
prop.default_value = default_value.get_construct_string().replace("\n", "");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
bool found_type = false;
|
||||
if (getter != StringName()) {
|
||||
MethodBind *mb = ClassDB::get_method(name, getter);
|
||||
@ -1076,10 +1105,16 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
|
||||
if (c.properties[i].default_value != String()) {
|
||||
additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\"";
|
||||
}
|
||||
|
||||
const PropertyDoc &p = c.properties[i];
|
||||
_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>");
|
||||
|
||||
if (c.properties[i].overridden) {
|
||||
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + "/>");
|
||||
} 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>");
|
||||
}
|
||||
}
|
||||
_write_string(f, 1, "</members>");
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ public:
|
||||
String description;
|
||||
String setter, getter;
|
||||
String default_value;
|
||||
bool overridden;
|
||||
bool operator<(const PropertyDoc &p_prop) const {
|
||||
return name < p_prop.name;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user