From 6783ff69c06a5c6fcb0e22802fedcc1fa32ac25c Mon Sep 17 00:00:00 2001 From: "ocean (they/them)" Date: Fri, 21 Apr 2023 09:32:26 -0400 Subject: [PATCH] Improve and fix GDScript documentation generation & behavior Removes documentation generation (docgen) from the GDScript compiler to its own file. Adds support for GDScript enums and signal parameters and quite a few other assorted fixes and improvements. --- core/doc_data.h | 55 ---- editor/editor_help.cpp | 124 ++++++--- editor/editor_help.h | 4 +- editor/plugins/script_editor_plugin.cpp | 2 +- modules/gdscript/editor/gdscript_docgen.cpp | 271 ++++++++++++++++++++ modules/gdscript/editor/gdscript_docgen.h | 42 +++ modules/gdscript/gdscript.cpp | 177 +------------ modules/gdscript/gdscript.h | 10 +- modules/gdscript/gdscript_compiler.cpp | 74 +----- modules/gdscript/gdscript_parser.cpp | 17 +- modules/gdscript/gdscript_parser.h | 2 +- 11 files changed, 431 insertions(+), 347 deletions(-) create mode 100644 modules/gdscript/editor/gdscript_docgen.cpp create mode 100644 modules/gdscript/editor/gdscript_docgen.h diff --git a/core/doc_data.h b/core/doc_data.h index d064818cd589..4e0db89984cc 100644 --- a/core/doc_data.h +++ b/core/doc_data.h @@ -315,61 +315,6 @@ class DocData { } }; - struct EnumDoc { - String name = "@unnamed_enum"; - bool is_bitfield = false; - String description; - Vector values; - static EnumDoc from_dict(const Dictionary &p_dict) { - EnumDoc doc; - - if (p_dict.has("name")) { - doc.name = p_dict["name"]; - } - - if (p_dict.has("is_bitfield")) { - doc.is_bitfield = p_dict["is_bitfield"]; - } - - if (p_dict.has("description")) { - doc.description = p_dict["description"]; - } - - Array values; - if (p_dict.has("values")) { - values = p_dict["values"]; - } - for (int i = 0; i < values.size(); i++) { - doc.values.push_back(ConstantDoc::from_dict(values[i])); - } - - return doc; - } - static Dictionary to_dict(const EnumDoc &p_doc) { - Dictionary dict; - - if (!p_doc.name.is_empty()) { - dict["name"] = p_doc.name; - } - - dict["is_bitfield"] = p_doc.is_bitfield; - - if (!p_doc.description.is_empty()) { - dict["description"] = p_doc.description; - } - - if (!p_doc.values.is_empty()) { - Array values; - for (int i = 0; i < p_doc.values.size(); i++) { - values.push_back(ConstantDoc::to_dict(p_doc.values[i])); - } - dict["values"] = values; - } - - return dict; - } - }; - struct PropertyDoc { String name; String type; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 839ef69ed370..17d5e7056eda 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -32,6 +32,7 @@ #include "core/core_constants.h" #include "core/input/input.h" +#include "core/object/script_language.h" #include "core/os/keyboard.h" #include "core/version.h" #include "core/version_generated.gen.h" @@ -45,6 +46,8 @@ #define CONTRIBUTE_URL vformat("%s/contributing/documentation/updating_the_class_reference.html", VERSION_DOCS_URL) +// TODO: this is sometimes used directly as doc->something, other times as EditorHelp::get_doc_data(), which is thread-safe. +// Might this be a problem? DocTools *EditorHelp::doc = nullptr; class DocCache : public Resource { @@ -74,6 +77,49 @@ class DocCache : public Resource { void set_classes(const Array &p_classes) { classes = p_classes; } }; +static bool _attempt_doc_load(const String &p_class) { + // Docgen always happens in the outer-most class: it also generates docs for inner classes. + String outer_class = p_class.get_slice(".", 0); + if (!ScriptServer::is_global_class(outer_class)) { + return false; + } + + // ResourceLoader is used in order to have a script-agnostic way to load scripts. + // This forces GDScript to compile the code, which is unnecessary for docgen, but it's a good compromise right now. + Ref