diff options
Diffstat (limited to 'editor/doc/doc_data.cpp')
-rw-r--r-- | editor/doc/doc_data.cpp | 265 |
1 files changed, 164 insertions, 101 deletions
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 208341add3..d35dc53ae1 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -32,6 +32,7 @@ #include "global_constants.h" #include "io/compression.h" #include "io/marshalls.h" +#include "os/dir_access.h" #include "project_settings.h" #include "scene/resources/theme.h" #include "script_language.h" @@ -50,6 +51,8 @@ void DocData::merge_from(const DocData &p_data) { c.description = cf.description; c.brief_description = cf.brief_description; + c.tutorials = cf.tutorials; + c.demos = cf.demos; for (int i = 0; i < c.methods.size(); i++) { @@ -163,6 +166,47 @@ void DocData::remove_from(const DocData &p_data) { } } +static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) { + + if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + p_method.return_enum = p_retinfo.class_name; + if (p_method.return_enum.begins_with("_")) //proxy class + p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); + p_method.return_type = "int"; + } else if (p_retinfo.class_name != StringName()) { + p_method.return_type = p_retinfo.class_name; + } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + p_method.return_type = p_retinfo.hint_string; + } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + p_method.return_type = "Variant"; + } else if (p_retinfo.type == Variant::NIL) { + p_method.return_type = "void"; + } else { + p_method.return_type = Variant::get_type_name(p_retinfo.type); + } +} + +static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) { + + p_argument.name = p_arginfo.name; + + if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + p_argument.enumeration = p_arginfo.class_name; + if (p_argument.enumeration.begins_with("_")) //proxy class + p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); + p_argument.type = "int"; + } else if (p_arginfo.class_name != StringName()) { + p_argument.type = p_arginfo.class_name; + } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + p_argument.type = p_arginfo.hint_string; + } else if (p_arginfo.type == Variant::NIL) { + // Parameters cannot be void, so PROPERTY_USAGE_NIL_IS_VARIANT is not necessary + p_argument.type = "Variant"; + } else { + p_argument.type = Variant::get_type_name(p_arginfo.type); + } +} + void DocData::generate(bool p_basic_types) { List<StringName> classes; @@ -263,51 +307,17 @@ void DocData::generate(bool p_basic_types) { for (int i = -1; i < E->get().arguments.size(); i++) { if (i == -1) { - #ifdef DEBUG_METHODS_ENABLED - - PropertyInfo retinfo = E->get().return_val; - - if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - method.return_enum = retinfo.class_name; - method.return_type = "int"; - } else if (retinfo.class_name != StringName()) { - method.return_type = retinfo.class_name; - } else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - - method.return_type = retinfo.hint_string; - } else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - - method.return_type = "Variant"; - } else if (retinfo.type == Variant::NIL) { - method.return_type = "void"; - } else { - method.return_type = Variant::get_type_name(retinfo.type); - } + return_doc_from_retinfo(method, E->get().return_val); #endif - } else { - ArgumentDoc argument; - - PropertyInfo arginfo = E->get().arguments[i]; - - if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - argument.enumeration = arginfo.class_name; - argument.type = "int"; - } else if (arginfo.class_name != StringName()) { - argument.type = arginfo.class_name; - } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { + const PropertyInfo &arginfo = E->get().arguments[i]; - argument.type = arginfo.hint_string; - } else if (arginfo.type == Variant::NIL && arginfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + ArgumentDoc argument; - argument.type = "Variant"; - } else { - argument.type = Variant::get_type_name(arginfo.type); - } + argument_doc_from_arginfo(argument, arginfo); - argument.name = E->get().arguments[i].name; int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); if (darg_idx >= 0) { @@ -464,26 +474,26 @@ void DocData::generate(bool p_basic_types) { for (int i = 0; i < mi.arguments.size(); i++) { - ArgumentDoc arg; - PropertyInfo pi = mi.arguments[i]; + PropertyInfo arginfo = mi.arguments[i]; - arg.name = pi.name; - //print_line("arg name: "+arg.name); - if (pi.type == Variant::NIL) - arg.type = "var"; + ArgumentDoc ad; + ad.name = arginfo.name; + + if (arginfo.type == Variant::NIL) + ad.type = "var"; else - arg.type = Variant::get_type_name(pi.type); + ad.type = Variant::get_type_name(arginfo.type); + int defarg = mi.default_arguments.size() - mi.arguments.size() + i; if (defarg >= 0) - arg.default_value = mi.default_arguments[defarg]; + ad.default_value = mi.default_arguments[defarg]; - method.arguments.push_back(arg); + method.arguments.push_back(ad); } if (mi.return_val.type == Variant::NIL) { if (mi.return_val.name != "") method.return_type = "var"; - } else { method.return_type = Variant::get_type_name(mi.return_val.type); } @@ -572,26 +582,19 @@ void DocData::generate(bool p_basic_types) { MethodInfo &mi = E->get(); MethodDoc md; md.name = mi.name; - if (mi.return_val.name != "") - md.return_type = mi.return_val.name; - else if (mi.name.find(":") != -1) { - md.return_type = mi.name.get_slice(":", 1); - md.name = mi.name.get_slice(":", 0); - } else - md.return_type = Variant::get_type_name(mi.return_val.type); - - for (int i = 0; i < mi.arguments.size(); i++) { - PropertyInfo &pi = mi.arguments[i]; + if (mi.flags & METHOD_FLAG_VARARG) { + if (md.qualifiers != "") + md.qualifiers += " "; + md.qualifiers += "vararg"; + } - ArgumentDoc ad; - ad.name = pi.name; + return_doc_from_retinfo(md, mi.return_val); - if (pi.type == Variant::NIL) - ad.type = "Variant"; - else - ad.type = Variant::get_type_name(pi.type); + for (int i = 0; i < mi.arguments.size(); i++) { + ArgumentDoc ad; + argument_doc_from_arginfo(ad, mi.arguments[i]); md.arguments.push_back(ad); } @@ -638,6 +641,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); method.return_type = parser->get_attribute_value("type"); + if (parser->has_attribute("enum")) { + method.return_enum = parser->get_attribute_value("enum"); + } } else if (name == "argument") { DocData::ArgumentDoc argument; @@ -676,36 +682,72 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & return OK; } -Error DocData::load(const String &p_path) { +Error DocData::load_classes(const String &p_dir) { - Ref<XMLParser> parser = memnew(XMLParser); - Error err = parser->open(p_path); - if (err) + Error err; + DirAccessRef da = DirAccess::open(p_dir, &err); + if (!da) { return err; - return _load(parser); -} -Error DocData::_load(Ref<XMLParser> parser) { + } - Error err = OK; + da->list_dir_begin(); + String path; + bool isdir; + path = da->get_next(&isdir); + while (path != String()) { + if (!isdir && path.ends_with("xml")) { + Ref<XMLParser> parser = memnew(XMLParser); + Error err = parser->open(p_dir.plus_file(path)); + if (err) + return err; + + _load(parser); + } + path = da->get_next(&isdir); + } - while ((err = parser->read()) == OK) { + da->list_dir_end(); - if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { + return OK; +} +Error DocData::erase_classes(const String &p_dir) { - if (parser->get_node_name() == "doc") { - break; - } else if (!parser->is_empty()) - parser->skip_section(); // unknown section, likely headers + Error err; + DirAccessRef da = DirAccess::open(p_dir, &err); + if (!da) { + return err; + } + + List<String> to_erase; + + da->list_dir_begin(); + String path; + bool isdir; + path = da->get_next(&isdir); + while (path != String()) { + if (!isdir && path.ends_with("xml")) { + to_erase.push_back(path); } + path = da->get_next(&isdir); } + da->list_dir_end(); - if (parser->has_attribute("version")) - version = parser->get_attribute_value("version"); + while (to_erase.size()) { + da->remove(to_erase.front()->get()); + to_erase.pop_front(); + } + + return OK; +} +Error DocData::_load(Ref<XMLParser> parser) { + + Error err = OK; while ((err = parser->read()) == OK) { - if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "doc") - break; //end of <doc> + if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "?xml") { + parser->skip_section(); + } if (parser->get_node_type() != XMLParser::NODE_ELEMENT) continue; //no idea what this may be, but skipping anyway @@ -740,6 +782,14 @@ Error DocData::_load(Ref<XMLParser> parser) { parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) c.description = parser->get_node_data().strip_edges(); + } else if (name == "tutorials") { + parser->read(); + if (parser->get_node_type() == XMLParser::NODE_TEXT) + c.tutorials = parser->get_node_data().strip_edges(); + } else if (name == "demos") { + parser->read(); + if (parser->get_node_type() == XMLParser::NODE_TEXT) + c.demos = parser->get_node_data().strip_edges(); } else if (name == "methods") { Error err = _parse_methods(parser, c.methods); @@ -769,8 +819,6 @@ Error DocData::_load(Ref<XMLParser> parser) { prop.setter = parser->get_attribute_value("setter"); if (parser->has_attribute("getter")) prop.getter = parser->get_attribute_value("getter"); - if (parser->has_attribute("brief")) - prop.brief_description = parser->get_attribute_value("brief").xml_unescape(); if (parser->has_attribute("enum")) prop.enumeration = parser->get_attribute_value("enum"); parser->read(); @@ -868,23 +916,29 @@ static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) f->store_string(tab + p_string + "\n"); } -Error DocData::save(const String &p_path) { +Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { - Error err; - FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err); + for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - if (err) { - ERR_EXPLAIN("Can't write doc file: " + p_path); + ClassDoc &c = E->get(); - ERR_FAIL_V(err); - } + String save_path; + if (p_class_path.has(c.name)) { + save_path = p_class_path[c.name]; + } else { + save_path = p_default_path; + } - _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); - _write_string(f, 0, "<doc version=\"" + String(VERSION_MKSTRING) + "\" name=\"Engine Types\">"); + Error err; + String save_file = save_path.plus_file(c.name + ".xml"); + FileAccessRef f = FileAccess::open(save_file, FileAccess::WRITE, &err); + if (err) { + ERR_EXPLAIN("Can't write doc file: " + save_file); - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { + ERR_FAIL_V(err); + } - ClassDoc &c = E->get(); + _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); String header = "<class name=\"" + c.name + "\""; if (c.inherits != "") @@ -894,6 +948,7 @@ Error DocData::save(const String &p_path) { if (c.category == "") category = "Core"; header += " category=\"" + category + "\""; + header += " version=\"" + String(VERSION_MKSTRING) + "\""; header += ">"; _write_string(f, 0, header); _write_string(f, 1, "<brief_description>"); @@ -904,6 +959,14 @@ Error DocData::save(const String &p_path) { if (c.description != "") _write_string(f, 2, c.description.xml_escape()); _write_string(f, 1, "</description>"); + _write_string(f, 1, "<tutorials>"); + if (c.tutorials != "") + _write_string(f, 2, c.tutorials.xml_escape()); + _write_string(f, 1, "</tutorials>"); + _write_string(f, 1, "<demos>"); + if (c.demos != "") + _write_string(f, 2, c.demos.xml_escape()); + _write_string(f, 1, "</demos>"); _write_string(f, 1, "<methods>"); c.methods.sort(); @@ -920,7 +983,11 @@ Error DocData::save(const String &p_path) { if (m.return_type != "") { - _write_string(f, 3, "<return type=\"" + m.return_type + "\">"); + 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 + ">"); _write_string(f, 3, "</return>"); } @@ -963,7 +1030,7 @@ Error DocData::save(const String &p_path) { enum_text = " enum=\"" + c.properties[i].enumeration + "\""; } PropertyDoc &p = c.properties[i]; - _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" brief=\"" + p.brief_description.xml_escape(true) + "\"" + enum_text + ">"); + _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">"); if (p.description != "") _write_string(f, 3, p.description.xml_escape()); _write_string(f, 2, "</member>"); @@ -1032,10 +1099,6 @@ Error DocData::save(const String &p_path) { _write_string(f, 0, "</class>"); } - _write_string(f, 0, "</doc>"); - f->close(); - memdelete(f); - return OK; } |