diff options
30 files changed, 390 insertions, 261 deletions
diff --git a/core/doc_data.cpp b/core/doc_data.cpp new file mode 100644 index 0000000000..d84ac6d05b --- /dev/null +++ b/core/doc_data.cpp @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* doc_data.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "doc_data.h" + +void DocData::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.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_method.return_type = p_retinfo.hint_string + "[]"; + } 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); + } +} + +void DocData::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.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_argument.type = p_arginfo.hint_string + "[]"; + } 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::property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo) { + p_property.name = p_memberinfo.propinfo.name; + p_property.description = p_memberinfo.doc_string; + + if (p_memberinfo.propinfo.type == Variant::OBJECT) { + p_property.type = p_memberinfo.propinfo.class_name; + } else if (p_memberinfo.propinfo.type == Variant::NIL && p_memberinfo.propinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + p_property.type = "Variant"; + } else { + p_property.type = Variant::get_type_name(p_memberinfo.propinfo.type); + } + + p_property.setter = p_memberinfo.setter; + p_property.getter = p_memberinfo.getter; + + if (p_memberinfo.has_default_value && p_memberinfo.default_value.get_type() != Variant::OBJECT) { + p_property.default_value = p_memberinfo.default_value.get_construct_string().replace("\n", ""); + } + + p_property.overridden = false; +} + +void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc) { + p_method.name = p_methodinfo.name; + p_method.description = p_desc; + + return_doc_from_retinfo(p_method, p_methodinfo.return_val); + + for (int i = 0; i < p_methodinfo.arguments.size(); i++) { + DocData::ArgumentDoc argument; + argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]); + int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); + if (default_arg_index >= 0) { + Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; + argument.default_value = default_arg.get_construct_string(); + } + p_method.arguments.push_back(argument); + } +} + +void DocData::constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc) { + p_const.name = p_name; + p_const.value = p_value; + p_const.description = p_desc; +} + +void DocData::signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc) { + return method_doc_from_methodinfo(p_signal, p_methodinfo, p_desc); +} diff --git a/editor/doc_data.h b/core/doc_data.h index 0090a97c93..bf016792ea 100644 --- a/editor/doc_data.h +++ b/core/doc_data.h @@ -141,30 +141,12 @@ public: } }; - String version; - - Map<String, ClassDoc> class_list; - Error _load(Ref<XMLParser> parser); - -public: static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo); static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo); static void property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo); static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc); static void constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc); static void signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc); - - void merge_from(const DocData &p_data); - void remove_from(const DocData &p_data); - void add_doc(const ClassDoc &p_class_doc); - void remove_doc(const String &p_class_name); - bool has_doc(const String &p_class_name); - void generate(bool p_basic_types = false); - Error load_classes(const String &p_dir); - static Error erase_classes(const String &p_dir); - Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path); - - Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); }; #endif // DOC_DATA_H diff --git a/core/object/script_language.h b/core/object/script_language.h index e34e5060a4..72586780ae 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -31,11 +31,11 @@ #ifndef SCRIPT_LANGUAGE_H #define SCRIPT_LANGUAGE_H +#include "core/doc_data.h" #include "core/io/multiplayer_api.h" #include "core/io/resource.h" #include "core/templates/map.h" #include "core/templates/pair.h" -#include "editor/doc_data.h" class ScriptLanguage; @@ -310,12 +310,12 @@ public: virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0; virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {} virtual bool is_using_templates() { return false; } - virtual bool has_documentation() { return false; } virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const = 0; virtual String validate_path(const String &p_path) const { return ""; } virtual Script *create_script() const = 0; virtual bool has_named_classes() const = 0; virtual bool supports_builtin_mode() const = 0; + virtual bool supports_documentation() const { return false; } virtual bool can_inherit_from_file() { return false; } virtual int find_function(const String &p_function, const String &p_code) const = 0; virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const = 0; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 320e5d8510..a8ff8a6854 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -31,6 +31,7 @@ #include "connections_dialog.h" #include "core/string/print_string.h" +#include "editor/doc_tools.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" @@ -997,7 +998,7 @@ void ConnectionsDock::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(base); while (F && descr == String()) { for (int i = 0; i < F->get().signals.size(); i++) { diff --git a/editor/doc_data.cpp b/editor/doc_tools.cpp index d786806ffa..5ee9abb183 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_tools.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* doc_data.cpp */ +/* doc_tools.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "doc_data.h" +#include "doc_tools.h" #include "core/config/engine.h" #include "core/config/project_settings.h" @@ -43,22 +43,22 @@ // Used for a hack preserving Mono properties on non-Mono builds. #include "modules/modules_enabled.gen.h" -void DocData::merge_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +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(); if (!p_data.class_list.has(c.name)) { continue; } - const ClassDoc &cf = p_data.class_list[c.name]; + const DocData::ClassDoc &cf = p_data.class_list[c.name]; c.description = cf.description; c.brief_description = cf.brief_description; c.tutorials = cf.tutorials; for (int i = 0; i < c.methods.size(); i++) { - MethodDoc &m = c.methods.write[i]; + DocData::MethodDoc &m = c.methods.write[i]; for (int j = 0; j < cf.methods.size(); j++) { if (cf.methods[j].name != m.name) { @@ -95,7 +95,7 @@ void DocData::merge_from(const DocData &p_data) { continue; } - const MethodDoc &mf = cf.methods[j]; + const DocData::MethodDoc &mf = cf.methods[j]; m.description = mf.description; break; @@ -103,13 +103,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.signals.size(); i++) { - MethodDoc &m = c.signals.write[i]; + DocData::MethodDoc &m = c.signals.write[i]; for (int j = 0; j < cf.signals.size(); j++) { if (cf.signals[j].name != m.name) { continue; } - const MethodDoc &mf = cf.signals[j]; + const DocData::MethodDoc &mf = cf.signals[j]; m.description = mf.description; break; @@ -117,13 +117,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.constants.size(); i++) { - ConstantDoc &m = c.constants.write[i]; + DocData::ConstantDoc &m = c.constants.write[i]; for (int j = 0; j < cf.constants.size(); j++) { if (cf.constants[j].name != m.name) { continue; } - const ConstantDoc &mf = cf.constants[j]; + const DocData::ConstantDoc &mf = cf.constants[j]; m.description = mf.description; break; @@ -131,13 +131,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.properties.size(); i++) { - PropertyDoc &p = c.properties.write[i]; + DocData::PropertyDoc &p = c.properties.write[i]; for (int j = 0; j < cf.properties.size(); j++) { if (cf.properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.properties[j]; + const DocData::PropertyDoc &pf = cf.properties[j]; p.description = pf.description; break; @@ -145,13 +145,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.theme_properties.size(); i++) { - PropertyDoc &p = c.theme_properties.write[i]; + DocData::PropertyDoc &p = c.theme_properties.write[i]; for (int j = 0; j < cf.theme_properties.size(); j++) { if (cf.theme_properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.theme_properties[j]; + const DocData::PropertyDoc &pf = cf.theme_properties[j]; p.description = pf.description; break; @@ -177,126 +177,31 @@ void DocData::merge_from(const DocData &p_data) { } } -void DocData::remove_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { +void DocTools::remove_from(const DocTools &p_data) { + for (Map<String, DocData::ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { if (class_list.has(E->key())) { class_list.erase(E->key()); } } } -void DocData::add_doc(const ClassDoc &p_class_doc) { +void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) { ERR_FAIL_COND(p_class_doc.name == ""); class_list[p_class_doc.name] = p_class_doc; } -void DocData::remove_doc(const String &p_class_name) { +void DocTools::remove_doc(const String &p_class_name) { ERR_FAIL_COND(p_class_name == "" || !class_list.has(p_class_name)); class_list.erase(p_class_name); } -bool DocData::has_doc(const String &p_class_name) { +bool DocTools::has_doc(const String &p_class_name) { if (p_class_name == "") { return false; } return class_list.has(p_class_name); } -void DocData::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.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_method.return_type = p_retinfo.hint_string + "[]"; - } 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); - } -} - -void DocData::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.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_argument.type = p_arginfo.hint_string + "[]"; - } 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::property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo) { - p_property.name = p_memberinfo.propinfo.name; - p_property.description = p_memberinfo.doc_string; - - if (p_memberinfo.propinfo.type == Variant::OBJECT) { - p_property.type = p_memberinfo.propinfo.class_name; - } else if (p_memberinfo.propinfo.type == Variant::NIL && p_memberinfo.propinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - p_property.type = "Variant"; - } else { - p_property.type = Variant::get_type_name(p_memberinfo.propinfo.type); - } - - p_property.setter = p_memberinfo.setter; - p_property.getter = p_memberinfo.getter; - - if (p_memberinfo.has_default_value && p_memberinfo.default_value.get_type() != Variant::OBJECT) { - p_property.default_value = p_memberinfo.default_value.get_construct_string().replace("\n", ""); - } - - p_property.overridden = false; -} - -void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc) { - p_method.name = p_methodinfo.name; - p_method.description = p_desc; - - return_doc_from_retinfo(p_method, p_methodinfo.return_val); - - for (int i = 0; i < p_methodinfo.arguments.size(); i++) { - ArgumentDoc argument; - argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]); - int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); - if (default_arg_index >= 0) { - Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; - argument.default_value = default_arg.get_construct_string(); - } - p_method.arguments.push_back(argument); - } -} - -void DocData::constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc) { - p_const.name = p_name; - p_const.value = p_value; - p_const.description = p_desc; -} - -void DocData::signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc) { - return method_doc_from_methodinfo(p_signal, p_methodinfo, p_desc); -} - 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; @@ -320,7 +225,7 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c return default_value; } -void DocData::generate(bool p_basic_types) { +void DocTools::generate(bool p_basic_types) { List<StringName> classes; ClassDB::get_class_list(&classes); classes.sort_custom<StringName::AlphCompare>(); @@ -344,8 +249,8 @@ void DocData::generate(bool p_basic_types) { cname = cname.substr(1, name.length()); } - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; c.inherits = ClassDB::get_parent_class(name); @@ -372,7 +277,7 @@ void DocData::generate(bool p_basic_types) { continue; } - PropertyDoc prop; + DocData::PropertyDoc prop; prop.name = E->get().name; @@ -476,7 +381,7 @@ void DocData::generate(bool p_basic_types) { } } - MethodDoc method; + DocData::MethodDoc method; method.name = E->get().name; @@ -499,12 +404,12 @@ void DocData::generate(bool p_basic_types) { for (int i = -1; i < E->get().arguments.size(); i++) { if (i == -1) { #ifdef DEBUG_METHODS_ENABLED - return_doc_from_retinfo(method, E->get().return_val); + DocData::return_doc_from_retinfo(method, E->get().return_val); #endif } else { const PropertyInfo &arginfo = E->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); if (darg_idx >= 0) { @@ -524,12 +429,12 @@ void DocData::generate(bool p_basic_types) { if (signal_list.size()) { for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) { - MethodDoc signal; + DocData::MethodDoc signal; signal.name = EV->get().name; for (int i = 0; i < EV->get().arguments.size(); i++) { const PropertyInfo &arginfo = EV->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); signal.arguments.push_back(argument); } @@ -542,7 +447,7 @@ void DocData::generate(bool p_basic_types) { ClassDB::get_integer_constant_list(name, &constant_list, true); for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); constant.value = itos(ClassDB::get_integer_constant(name, E->get())); constant.is_value_valid = true; @@ -556,7 +461,7 @@ void DocData::generate(bool p_basic_types) { List<StringName> l; Theme::get_default()->get_constant_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; pd.default_value = itos(Theme::get_default()->get_constant(E->get(), cname)); @@ -566,7 +471,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_color_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Color"; pd.default_value = Variant(Theme::get_default()->get_color(E->get(), cname)).get_construct_string(); @@ -576,7 +481,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_icon_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Texture2D"; c.theme_properties.push_back(pd); @@ -584,7 +489,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Font"; c.theme_properties.push_back(pd); @@ -592,7 +497,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_size_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; c.theme_properties.push_back(pd); @@ -600,7 +505,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_stylebox_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "StyleBox"; c.theme_properties.push_back(pd); @@ -612,7 +517,7 @@ void DocData::generate(bool p_basic_types) { { // So we can document the concept of Variant even if it's not a usable class per se. - class_list["Variant"] = ClassDoc(); + class_list["Variant"] = DocData::ClassDoc(); class_list["Variant"].name = "Variant"; } @@ -631,8 +536,8 @@ void DocData::generate(bool p_basic_types) { String cname = Variant::get_type_name(Variant::Type(i)); - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; Callable::CallError cerror; @@ -709,7 +614,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc method; + DocData::MethodDoc method; method.name = mi.name; if (method.name == cname) { @@ -720,8 +625,8 @@ void DocData::generate(bool p_basic_types) { for (int j = 0; j < mi.arguments.size(); j++) { PropertyInfo arginfo = mi.arguments[j]; - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); ad.name = arginfo.name; int darg_idx = mi.default_arguments.size() - mi.arguments.size() + j; @@ -733,7 +638,7 @@ void DocData::generate(bool p_basic_types) { method.arguments.push_back(ad); } - return_doc_from_retinfo(method, mi.return_val); + DocData::return_doc_from_retinfo(method, mi.return_val); if (mi.flags & METHOD_FLAG_VARARG) { if (method.qualifiers != "") { @@ -749,7 +654,7 @@ void DocData::generate(bool p_basic_types) { v.get_property_list(&properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { PropertyInfo pi = E->get(); - PropertyDoc property; + DocData::PropertyDoc property; property.name = pi.name; property.type = Variant::get_type_name(pi.type); property.default_value = v.get(pi.name).get_construct_string(); @@ -761,7 +666,7 @@ void DocData::generate(bool p_basic_types) { Variant::get_constants_for_type(Variant::Type(i), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); Variant value = Variant::get_constant_value(Variant::Type(i), E->get()); constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(); @@ -774,12 +679,12 @@ void DocData::generate(bool p_basic_types) { { String cname = "@GlobalScope"; - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { - ConstantDoc cd; + DocData::ConstantDoc cd; 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)); @@ -796,7 +701,7 @@ void DocData::generate(bool p_basic_types) { //servers (this is kind of hackish) for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; Engine::Singleton &s = E->get(); if (!s.ptr) { continue; @@ -816,7 +721,7 @@ void DocData::generate(bool p_basic_types) { 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()) { - MethodDoc md; + DocData::MethodDoc md; md.name = E->get(); //return if (Variant::has_utility_function_return_value(E->get())) { @@ -826,7 +731,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.return_type = ad.type; } @@ -841,7 +746,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.arguments.push_back(ad); } } @@ -858,7 +763,7 @@ void DocData::generate(bool p_basic_types) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptLanguage *lang = ScriptServer::get_language(i); String cname = "@" + lang->get_name(); - ClassDoc c; + DocData::ClassDoc c; c.name = cname; // Get functions. @@ -867,7 +772,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc md; + DocData::MethodDoc md; md.name = mi.name; if (mi.flags & METHOD_FLAG_VARARG) { @@ -877,11 +782,11 @@ void DocData::generate(bool p_basic_types) { md.qualifiers += "vararg"; } - return_doc_from_retinfo(md, mi.return_val); + DocData::return_doc_from_retinfo(md, mi.return_val); for (int j = 0; j < mi.arguments.size(); j++) { - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); int darg_idx = j - (mi.arguments.size() - mi.default_arguments.size()); if (darg_idx >= 0) { @@ -900,7 +805,7 @@ void DocData::generate(bool p_basic_types) { lang->get_public_constants(&cinfo); for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { - ConstantDoc cd; + DocData::ConstantDoc cd; cd.name = E->get().first; cd.value = E->get().second; cd.is_value_valid = true; @@ -978,7 +883,7 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & return OK; } -Error DocData::load_classes(const String &p_dir) { +Error DocTools::load_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -1006,7 +911,7 @@ Error DocData::load_classes(const String &p_dir) { return OK; } -Error DocData::erase_classes(const String &p_dir) { +Error DocTools::erase_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -1034,7 +939,7 @@ Error DocData::erase_classes(const String &p_dir) { return OK; } -Error DocData::_load(Ref<XMLParser> parser) { +Error DocTools::_load(Ref<XMLParser> parser) { Error err = OK; while ((err = parser->read()) == OK) { @@ -1050,8 +955,8 @@ Error DocData::_load(Ref<XMLParser> parser) { ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); String name = parser->get_attribute_value("name"); - class_list[name] = ClassDoc(); - ClassDoc &c = class_list[name]; + class_list[name] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[name]; c.name = name; if (parser->has_attribute("inherits")) { @@ -1079,7 +984,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "link") { - TutorialDoc tutorial; + DocData::TutorialDoc tutorial; if (parser->has_attribute("title")) { tutorial.title = parser->get_attribute_value("title"); } @@ -1108,7 +1013,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "member") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1145,7 +1050,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "theme_item") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1173,7 +1078,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "constant") { - ConstantDoc constant2; + DocData::ConstantDoc constant2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); constant2.name = parser->get_attribute_value("name"); ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT); @@ -1222,9 +1127,9 @@ static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) f->store_string(tab + p_string + "\n"); } -Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +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(); String save_path; if (p_class_path.has(c.name)) { @@ -1259,7 +1164,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<tutorials>"); for (int i = 0; i < c.tutorials.size(); i++) { - TutorialDoc tutorial = c.tutorials.get(i); + DocData::TutorialDoc tutorial = c.tutorials.get(i); String title_attribute = (!tutorial.title.empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : ""; _write_string(f, 2, "<link" + title_attribute + ">" + tutorial.link.xml_escape() + "</link>"); } @@ -1270,7 +1175,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri c.methods.sort(); for (int i = 0; i < c.methods.size(); i++) { - const MethodDoc &m = c.methods[i]; + const DocData::MethodDoc &m = c.methods[i]; String qualifiers; if (m.qualifiers != "") { @@ -1289,7 +1194,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri } for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; String enum_text; if (a.enumeration != String()) { @@ -1328,7 +1233,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\""; } - const PropertyDoc &p = c.properties[i]; + const DocData::PropertyDoc &p = c.properties[i]; 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 + " />"); @@ -1346,10 +1251,10 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<signals>"); for (int i = 0; i < c.signals.size(); i++) { - const MethodDoc &m = c.signals[i]; + const DocData::MethodDoc &m = c.signals[i]; _write_string(f, 2, "<signal name=\"" + m.name + "\">"); for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; _write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">"); _write_string(f, 3, "</argument>"); } @@ -1367,7 +1272,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<constants>"); for (int i = 0; i < c.constants.size(); i++) { - const ConstantDoc &k = c.constants[i]; + const DocData::ConstantDoc &k = c.constants[i]; if (k.is_value_valid) { if (k.enumeration != String()) { _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">"); @@ -1392,7 +1297,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<theme_items>"); for (int i = 0; i < c.theme_properties.size(); i++) { - const PropertyDoc &p = c.theme_properties[i]; + const DocData::PropertyDoc &p = c.theme_properties[i]; if (p.default_value != "") { _write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\" default=\"" + p.default_value.xml_escape(true) + "\">"); @@ -1413,7 +1318,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri return OK; } -Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { +Error DocTools::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { Vector<uint8_t> data; data.resize(p_uncompressed_size); Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE); diff --git a/editor/doc_tools.h b/editor/doc_tools.h new file mode 100644 index 0000000000..db27e38c8b --- /dev/null +++ b/editor/doc_tools.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* doc_tools.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef DOC_TOOLS_H +#define DOC_TOOLS_H + +#include "core/doc_data.h" + +class DocTools { +public: + String version; + Map<String, DocData::ClassDoc> class_list; + + static Error erase_classes(const String &p_dir); + + void merge_from(const DocTools &p_data); + void remove_from(const DocTools &p_data); + void add_doc(const DocData::ClassDoc &p_class_doc); + void remove_doc(const String &p_class_name); + bool has_doc(const String &p_class_name); + void generate(bool p_basic_types = false); + Error load_classes(const String &p_dir); + Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path); + + Error _load(Ref<XMLParser> parser); + Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); +}; + +#endif // DOC_DATA_H diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 44c29ab81f..6dcc505a11 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -799,11 +799,16 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } } - if (fc) { - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptLanguage *lang = ScriptServer::get_language(i); - if (lang->has_documentation() && fc->type == lang->get_type()) { - ResourceLoader::load(path); + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptLanguage *lang = ScriptServer::get_language(i); + if (lang->supports_documentation() && fi->type == lang->get_type()) { + Ref<Script> script = ResourceLoader::load(path); + if (script == nullptr) { + continue; + } + const Vector<DocData::ClassDoc> &docs = script->get_documentation(); + for (int j = 0; j < docs.size(); j++) { + EditorHelp::get_doc_data()->add_doc(docs[j]); } } } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index e9f6b16b88..4c553950a7 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -40,7 +40,7 @@ #define CONTRIBUTE_URL "https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html" -DocData *EditorHelp::doc = nullptr; +DocTools *EditorHelp::doc = nullptr; void EditorHelp::_init_colors() { title_color = get_theme_color("accent_color", "Editor"); @@ -1323,7 +1323,7 @@ void EditorHelp::_help_callback(const String &p_topic) { } static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); String base_path; Ref<Font> doc_font = p_rt->get_theme_font("doc", "EditorFonts"); @@ -1618,9 +1618,9 @@ void EditorHelp::_add_text(const String &p_bbcode) { } void EditorHelp::generate_doc() { - doc = memnew(DocData); + doc = memnew(DocTools); doc->generate(true); - DocData compdoc; + DocTools compdoc; compdoc.load_compressed(_doc_data_compressed, _doc_data_compressed_size, _doc_data_uncompressed_size); doc->merge_from(compdoc); //ensure all is up to date } diff --git a/editor/editor_help.h b/editor/editor_help.h index 545147f6f5..737f841d30 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -32,7 +32,7 @@ #define EDITOR_HELP_H #include "editor/code_editor.h" -#include "editor/doc_data.h" +#include "editor/doc_tools.h" #include "editor/editor_plugin.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" @@ -118,7 +118,7 @@ class EditorHelp : public VBoxContainer { RichTextLabel *class_desc; HSplitContainer *h_split; - static DocData *doc; + static DocTools *doc; ConfirmationDialog *search_dialog; LineEdit *search; @@ -166,7 +166,7 @@ protected: public: static void generate_doc(); - static DocData *get_doc_data() { return doc; } + static DocTools *get_doc_data() { return doc; } void go_to_help(const String &p_help); void go_to_class(const String &p_class, int p_scroll = 0); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 0c419168c0..d88a0e3ff8 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -32,6 +32,7 @@ #include "array_property_edit.h" #include "dictionary_property_edit.h" +#include "editor/doc_tools.h" #include "editor_feature_profile.h" #include "editor_node.h" #include "editor_scale.h" @@ -1708,7 +1709,7 @@ void EditorInspector::update_tree() { StringName type2 = p.name; if (!class_descr_cache.has(type2)) { String descr; - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2); if (E) { descr = DTR(E->get().brief_description); @@ -1878,7 +1879,7 @@ void EditorInspector::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(classname); while (F && descr == String()) { for (int i = 0; i < F->get().properties.size(); i++) { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index fa70415210..12790a6746 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1249,13 +1249,35 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { current->apply_code(); _save_text_file(text_file, text_file->get_path()); break; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } + } break; case FILE_SAVE_AS: { if (trim_trailing_whitespace_on_save) { @@ -1274,6 +1296,8 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); @@ -1289,9 +1313,27 @@ void ScriptEditor::_menu_option(int p_option) { break; } + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->push_item(resource.ptr()); editor->save_resource_as(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } break; case FILE_TOOL_RELOAD: @@ -2318,11 +2360,33 @@ void ScriptEditor::save_all_scripts() { if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) { Ref<TextFile> text_file = edited_res; + Ref<Script> script = edited_res; + if (text_file != nullptr) { _save_text_file(text_file, text_file->get_path()); continue; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(edited_res); //external script, save it + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } } diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 75420a1ef4..1ff73f25c5 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -31,6 +31,7 @@ #include "property_selector.h" #include "core/os/keyboard.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor_scale.h" @@ -349,7 +350,7 @@ void PropertySelector::_item_selected() { class_type = base_type; } - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); String text; if (properties) { diff --git a/main/main.cpp b/main/main.cpp index 3bef04b15d..555ae4e88a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -81,8 +81,8 @@ #ifdef TOOLS_ENABLED -#include "editor/doc_data.h" #include "editor/doc_data_class_path.gen.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/progress_dialog.h" @@ -1914,10 +1914,10 @@ bool Main::start() { GLOBAL_DEF("mono/project/auto_update_project", true); #endif - DocData doc; + DocTools doc; doc.generate(doc_base); - DocData docsrc; + DocTools docsrc; Map<String, String> doc_data_classes; Set<String> checked_paths; print_line("Loading docs..."); @@ -1957,7 +1957,7 @@ bool Main::start() { doc.merge_from(docsrc); for (Set<String>::Element *E = checked_paths.front(); E; E = E->next()) { print_line("Erasing old docs at: " + E->get()); - DocData::erase_classes(E->get()); + DocTools::erase_classes(E->get()); } print_line("Generating new docs..."); diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 7f736bdea7..e91d9b7bfb 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -31,6 +31,7 @@ #ifndef NATIVE_SCRIPT_H #define NATIVE_SCRIPT_H +#include "core/doc_data.h" #include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 790e4d5ffb..dc1ed6d576 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -32,6 +32,8 @@ #define PLUGINSCRIPT_SCRIPT_H // Godot imports + +#include "core/doc_data.h" #include "core/object/script_language.h" // PluginScript imports #include "pluginscript_language.h" diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8524ec276a..b00eb6f75b 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -39,8 +39,6 @@ #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "editor/editor_help.h" -#include "editor/plugins/script_editor_plugin.h" #include "gdscript_analyzer.h" #include "gdscript_cache.h" #include "gdscript_compiler.h" @@ -242,7 +240,7 @@ void GDScript::_get_script_method_list(List<MethodInfo> *r_list, bool p_include_ mi.name = E->key(); for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arginfo = func->get_argument_type(i); -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED arginfo.name = func->get_argument_name(i); #endif mi.arguments.push_back(arginfo); @@ -419,11 +417,8 @@ void GDScript::_add_doc(const DocData::ClassDoc &p_inner_class) { } void GDScript::_clear_doc() { - if (EditorHelp::get_doc_data() && EditorHelp::get_doc_data()->has_doc(doc.name)) { - EditorHelp::get_doc_data()->remove_doc(doc.name); - doc = DocData::ClassDoc(); - } docs.clear(); + doc = DocData::ClassDoc(); } void GDScript::_update_doc() { @@ -581,13 +576,6 @@ void GDScript::_update_doc() { E->get()->_update_doc(); } - if (EditorHelp::get_doc_data()) { - EditorHelp::get_doc_data()->add_doc(doc); - } - if (ScriptEditor::get_singleton()) { - ScriptEditor::get_singleton()->update_doc(doc.name); - } - _add_doc(doc); } #endif @@ -845,8 +833,8 @@ Error GDScript::reload(bool p_keep_state) { GDScriptCompiler compiler; err = compiler.compile(&parser, this, p_keep_state); -#if TOOLS_ENABLED - this->_update_doc(); +#ifdef TOOLS_ENABLED + _update_doc(); #endif if (err) { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index a7052914ba..3eb260f95f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -33,10 +33,10 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/doc_data.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/object/script_language.h" -#include "editor/doc_data.h" #include "gdscript_function.h" class GDScriptNativeClass : public Reference { @@ -470,6 +470,7 @@ public: virtual Script *create_script() const; virtual bool has_named_classes() const; virtual bool supports_builtin_mode() const; + virtual bool supports_documentation() const; virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 3de09eec05..97f10d4013 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2009,7 +2009,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } } -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED p_script->doc_functions.clear(); p_script->doc_variables.clear(); p_script->doc_constants.clear(); @@ -2142,7 +2142,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } else { prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE; } -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED p_script->doc_variables[name] = variable->doc_description; #endif @@ -2224,7 +2224,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar parameters_names.write[j] = signal->parameters[j]->identifier->name; } p_script->_signals[name] = parameters_names; -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED if (!signal->doc_description.empty()) { p_script->doc_signals[name] = signal->doc_description; } diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index a426046797..4f847923a4 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -193,6 +193,10 @@ bool GDScriptLanguage::supports_builtin_mode() const { return true; } +bool GDScriptLanguage::supports_documentation() const { + return true; +} + int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const { GDScriptTokenizer tokenizer; tokenizer.set_source_code(p_code); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 5259e831e9..48fca16ab1 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -561,11 +561,7 @@ void GDScriptParser::parse_program() { #ifdef TOOLS_ENABLED for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) { if (E->get().new_line && E->get().comment.begins_with("##")) { - if (class_doc_line == -1) { - class_doc_line = E->key(); - } else { - class_doc_line = MIN(class_doc_line, E->key()); - } + class_doc_line = MIN(class_doc_line, E->key()); } } if (has_comment(class_doc_line)) { @@ -708,6 +704,7 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() #ifdef TOOLS_ENABLED // Consume doc comments. + class_doc_line = MIN(class_doc_line, doc_comment_line - 1); if (has_comment(doc_comment_line)) { if constexpr (std::is_same_v<T, ClassNode>) { get_class_doc_comment(doc_comment_line, member->doc_brief_description, member->doc_description, member->doc_tutorials, true); @@ -2741,12 +2738,6 @@ String GDScriptParser::get_doc_comment(int p_line, bool p_single_line) { line--; } - if (class_doc_line == -1) { - class_doc_line = line - 1; - } else { - class_doc_line = MIN(class_doc_line, line) - 1; - } - int codeblock_begins = 0; while (comments.has(line)) { if (!comments[line].new_line || !comments[line].comment.begins_with("##")) { @@ -2800,11 +2791,6 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & } line--; } - if (class_doc_line == -1) { - class_doc_line = line - 1; - } else { - class_doc_line = MIN(class_doc_line, line) - 1; - } } int codeblock_begins = 0; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 598ac9cd34..44605bc20f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1303,7 +1303,7 @@ private: TypeNode *parse_type(bool p_allow_void = false); #ifdef TOOLS_ENABLED // Doc comments. - int class_doc_line = -1; + int class_doc_line = 0x7FFFFFFF; bool has_comment(int p_line); String get_doc_comment(int p_line, bool p_single_line = false); void get_class_doc_comment(int p_line, String &p_brief, String &p_desc, Vector<Pair<String, String>> &p_tutorials, bool p_inner_class); diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 6ddb0d149e..729be237ec 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/io/json.h" #include "core/os/copymem.h" +#include "editor/doc_tools.h" #include "editor/editor_log.h" #include "editor/editor_node.h" @@ -212,7 +213,7 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { void GDScriptLanguageProtocol::initialized(const Variant &p_params) { lsp::GodotCapabilities capabilities; - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { lsp::GodotNativeClassInfo gdclass; gdclass.name = E->get().name; diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index f6643d07f9..60668e7b31 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -34,6 +34,7 @@ #include "../gdscript_parser.h" #include "core/config/project_settings.h" #include "core/object/script_language.h" +#include "editor/doc_tools.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" #include "editor/editor_node.h" @@ -189,7 +190,7 @@ Error GDScriptWorkspace::initialize() { return OK; } - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { const DocData::ClassDoc &class_data = E->value(); lsp::DocumentSymbol class_symbol; diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 288fd41c87..1029c53bbf 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -31,9 +31,9 @@ #ifndef GODOT_LSP_H #define GODOT_LSP_H +#include "core/doc_data.h" #include "core/object/class_db.h" #include "core/templates/list.h" -#include "editor/doc_data.h" namespace lsp { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b4537f531d..63ac0956f4 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2984,7 +2984,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); } -#if TOOLS_ENABLED +#ifdef TOOLS_ENABLED if (!p_script->tool) { p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 4c6e624b8a..f482cc21f0 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -31,6 +31,7 @@ #ifndef CSHARP_SCRIPT_H #define CSHARP_SCRIPT_H +#include "core/doc_data.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/object/script_language.h" diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index ff3122a77f..968f9f29c7 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -185,7 +185,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf return String(); } - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); String bbcode = p_bbcode; diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index eeab518954..6fefcd48a4 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -31,9 +31,10 @@ #ifndef BINDINGS_GENERATOR_H #define BINDINGS_GENERATOR_H +#include "core/doc_data.h" #include "core/object/class_db.h" #include "core/string/string_builder.h" -#include "editor/doc_data.h" +#include "editor/doc_tools.h" #include "editor/editor_help.h" #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index b34f6df113..59bdfb2fc3 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -33,6 +33,7 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/doc_data.h" #include "core/object/script_language.h" #include "core/os/thread.h" diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 875270e74f..54d86d5a9c 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -31,6 +31,7 @@ #include "visual_script_property_selector.h" #include "core/os/keyboard.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "modules/visual_script/visual_script.h" @@ -437,7 +438,7 @@ void VisualScriptPropertySelector::_item_selected() { class_type = base_type; } - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); String text; String at_class = class_type; |