Refactor bbcode_to_xml
into multiple specific methods
The specific `_append_xml_*` methods implement the logic that generates the proper XML documentation for the given BBCode tag and target and appends it to the output.
This commit is contained in:
parent
84615b4b53
commit
eaddb79ec6
@ -283,7 +283,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
|
|||||||
const String link_tag = tag.substr(0, tag_end);
|
const String link_tag = tag.substr(0, tag_end);
|
||||||
const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" ");
|
const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" ");
|
||||||
|
|
||||||
Vector<String> link_target_parts = link_target.split(".");
|
const Vector<String> link_target_parts = link_target.split(".");
|
||||||
|
|
||||||
if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) {
|
if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) {
|
||||||
ERR_PRINT("Invalid reference format: '" + tag + "'.");
|
ERR_PRINT("Invalid reference format: '" + tag + "'.");
|
||||||
@ -311,260 +311,18 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (link_tag == "method") {
|
if (link_tag == "method") {
|
||||||
if (link_target_parts[0] == name_cache.type_at_GlobalScope) {
|
_append_xml_method(xml_output, target_itype, target_cname, link_target, link_target_parts);
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
OS::get_singleton()->print("Cannot resolve @GlobalScope method reference in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Map what we can
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else if (!target_itype || !target_itype->is_object_type) {
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
if (target_itype) {
|
|
||||||
OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
} else {
|
|
||||||
OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Map what we can
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else {
|
|
||||||
if (target_cname == "_init") {
|
|
||||||
// The _init method is not declared in C#, reference the constructor instead
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append("()\"/>");
|
|
||||||
} else {
|
|
||||||
const MethodInterface *target_imethod = target_itype->find_method_by_name(target_cname);
|
|
||||||
|
|
||||||
if (target_imethod) {
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_imethod->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("Cannot resolve method reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (link_tag == "member") {
|
} else if (link_tag == "member") {
|
||||||
if (link_target.find("/") >= 0) {
|
_append_xml_member(xml_output, target_itype, target_cname, link_target, link_target_parts);
|
||||||
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else if (!target_itype || !target_itype->is_object_type) {
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
if (target_itype) {
|
|
||||||
OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
} else {
|
|
||||||
OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Map what we can
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else {
|
|
||||||
const TypeInterface *current_itype = target_itype;
|
|
||||||
const PropertyInterface *target_iprop = nullptr;
|
|
||||||
|
|
||||||
while (target_iprop == nullptr && current_itype != nullptr) {
|
|
||||||
target_iprop = current_itype->find_property_by_name(target_cname);
|
|
||||||
if (target_iprop == nullptr) {
|
|
||||||
current_itype = _get_type_or_null(TypeReference(current_itype->base_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_iprop) {
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(current_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_iprop->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("Cannot resolve member reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (link_tag == "signal") {
|
} else if (link_tag == "signal") {
|
||||||
if (!target_itype || !target_itype->is_object_type) {
|
_append_xml_signal(xml_output, target_itype, target_cname, link_target, link_target_parts);
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
if (target_itype) {
|
|
||||||
OS::get_singleton()->print("Cannot resolve signal reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
} else {
|
|
||||||
OS::get_singleton()->print("Cannot resolve type from signal reference in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Map what we can
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else {
|
|
||||||
const SignalInterface *target_isignal = target_itype->find_signal_by_name(target_cname);
|
|
||||||
|
|
||||||
if (target_isignal) {
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_isignal->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("Cannot resolve signal reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (link_tag == "enum") {
|
} else if (link_tag == "enum") {
|
||||||
const StringName search_cname = !target_itype ? target_cname : StringName(target_itype->name + "." + (String)target_cname);
|
_append_xml_enum(xml_output, target_itype, target_cname, link_target, link_target_parts);
|
||||||
|
|
||||||
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname);
|
|
||||||
|
|
||||||
if (!enum_match && search_cname != target_cname) {
|
|
||||||
enum_match = enum_types.find(target_cname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enum_match) {
|
|
||||||
const TypeInterface &target_enum_itype = enum_match->value();
|
|
||||||
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("Cannot resolve enum reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
} else if (link_tag == "constant") {
|
} else if (link_tag == "constant") {
|
||||||
if (link_target_parts[0] == name_cache.type_at_GlobalScope) {
|
_append_xml_constant(xml_output, target_itype, target_cname, link_target, link_target_parts);
|
||||||
find_constant_in_global_scope:
|
|
||||||
const String target_name = (String)target_cname;
|
|
||||||
|
|
||||||
// Try to find as a global constant
|
|
||||||
const ConstantInterface *target_iconst = find_constant_by_name(target_name, global_constants);
|
|
||||||
|
|
||||||
if (target_iconst) {
|
|
||||||
// Found global constant
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "." BINDINGS_GLOBAL_SCOPE_CLASS ".");
|
|
||||||
xml_output.append(target_iconst->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
// Try to find as global enum constant
|
|
||||||
const EnumInterface *target_ienum = nullptr;
|
|
||||||
|
|
||||||
for (const EnumInterface &ienum : global_enums) {
|
|
||||||
target_ienum = &ienum;
|
|
||||||
target_iconst = find_constant_by_name(target_name, target_ienum->constants);
|
|
||||||
if (target_iconst) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_iconst) {
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_ienum->cname);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_iconst->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("Cannot resolve global constant reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!target_itype || !target_itype->is_object_type) {
|
|
||||||
// Search in @GlobalScope as a last resort if no class was specified
|
|
||||||
if (link_target_parts.size() == 1) {
|
|
||||||
goto find_constant_in_global_scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
if (target_itype) {
|
|
||||||
OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
} else {
|
|
||||||
OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", link_target.utf8().get_data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Map what we can
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
} else {
|
|
||||||
const String target_name = (String)target_cname;
|
|
||||||
|
|
||||||
// Try to find the constant in the current class
|
|
||||||
const ConstantInterface *target_iconst = find_constant_by_name(target_name, target_itype->constants);
|
|
||||||
|
|
||||||
if (target_iconst) {
|
|
||||||
// Found constant in current class
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_iconst->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
// Try to find as enum constant in the current class
|
|
||||||
const EnumInterface *target_ienum = nullptr;
|
|
||||||
|
|
||||||
for (const EnumInterface &ienum : target_itype->enums) {
|
|
||||||
target_ienum = &ienum;
|
|
||||||
target_iconst = find_constant_by_name(target_name, target_ienum->constants);
|
|
||||||
if (target_iconst) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_iconst) {
|
|
||||||
xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
|
||||||
xml_output.append(target_itype->proxy_name);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_ienum->cname);
|
|
||||||
xml_output.append(".");
|
|
||||||
xml_output.append(target_iconst->proxy_name);
|
|
||||||
xml_output.append("\"/>");
|
|
||||||
} else {
|
|
||||||
// Also search in @GlobalScope as a last resort if no class was specified
|
|
||||||
if (link_target_parts.size() == 1) {
|
|
||||||
goto find_constant_in_global_scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_PRINT("Cannot resolve constant reference in documentation: '" + link_target + "'.");
|
|
||||||
|
|
||||||
xml_output.append("<c>");
|
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (link_tag == "theme_item") {
|
} else if (link_tag == "theme_item") {
|
||||||
// We do not declare theme_items in any way in C#, so there is nothing to reference
|
// We do not declare theme_items in any way in C#, so there is nothing to reference
|
||||||
xml_output.append("<c>");
|
_append_xml_undeclared(xml_output, link_target);
|
||||||
xml_output.append(link_target);
|
|
||||||
xml_output.append("</c>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = brk_end + 1;
|
pos = brk_end + 1;
|
||||||
@ -729,6 +487,240 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
|
|||||||
return xml_output.as_string();
|
return xml_output.as_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
|
||||||
|
if (p_link_target_parts[0] == name_cache.type_at_GlobalScope) {
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
OS::get_singleton()->print("Cannot resolve @GlobalScope method reference in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Map what we can
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else if (!p_target_itype || !p_target_itype->is_object_type) {
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
if (p_target_itype) {
|
||||||
|
OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Map what we can
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else {
|
||||||
|
if (p_target_cname == "_init") {
|
||||||
|
// The _init method is not declared in C#, reference the constructor instead
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append("()\"/>");
|
||||||
|
} else {
|
||||||
|
const MethodInterface *target_imethod = p_target_itype->find_method_by_name(p_target_cname);
|
||||||
|
|
||||||
|
if (target_imethod) {
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_imethod->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve method reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
|
||||||
|
if (p_link_target.find("/") >= 0) {
|
||||||
|
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else if (!p_target_itype || !p_target_itype->is_object_type) {
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
if (p_target_itype) {
|
||||||
|
OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Map what we can
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else {
|
||||||
|
const TypeInterface *current_itype = p_target_itype;
|
||||||
|
const PropertyInterface *target_iprop = nullptr;
|
||||||
|
|
||||||
|
while (target_iprop == nullptr && current_itype != nullptr) {
|
||||||
|
target_iprop = current_itype->find_property_by_name(p_target_cname);
|
||||||
|
if (target_iprop == nullptr) {
|
||||||
|
current_itype = _get_type_or_null(TypeReference(current_itype->base_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_iprop) {
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(current_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_iprop->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve member reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_signal(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
|
||||||
|
if (!p_target_itype || !p_target_itype->is_object_type) {
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
if (p_target_itype) {
|
||||||
|
OS::get_singleton()->print("Cannot resolve signal reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->print("Cannot resolve type from signal reference in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Map what we can
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else {
|
||||||
|
const SignalInterface *target_isignal = p_target_itype->find_signal_by_name(p_target_cname);
|
||||||
|
|
||||||
|
if (target_isignal) {
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_isignal->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve signal reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_enum(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
|
||||||
|
const StringName search_cname = !p_target_itype ? p_target_cname : StringName(p_target_itype->name + "." + (String)p_target_cname);
|
||||||
|
|
||||||
|
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname);
|
||||||
|
|
||||||
|
if (!enum_match && search_cname != p_target_cname) {
|
||||||
|
enum_match = enum_types.find(p_target_cname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enum_match) {
|
||||||
|
const TypeInterface &target_enum_itype = enum_match->value();
|
||||||
|
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve enum reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_constant(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
|
||||||
|
if (p_link_target_parts[0] == name_cache.type_at_GlobalScope) {
|
||||||
|
_append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target);
|
||||||
|
} else if (!p_target_itype || !p_target_itype->is_object_type) {
|
||||||
|
// Search in @GlobalScope as a last resort if no class was specified
|
||||||
|
if (p_link_target_parts.size() == 1) {
|
||||||
|
_append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
if (p_target_itype) {
|
||||||
|
OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", p_link_target.utf8().get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Map what we can
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
} else {
|
||||||
|
// Try to find the constant in the current class
|
||||||
|
const ConstantInterface *target_iconst = find_constant_by_name(p_target_cname, p_target_itype->constants);
|
||||||
|
|
||||||
|
if (target_iconst) {
|
||||||
|
// Found constant in current class
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_iconst->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
// Try to find as enum constant in the current class
|
||||||
|
const EnumInterface *target_ienum = nullptr;
|
||||||
|
|
||||||
|
for (const EnumInterface &ienum : p_target_itype->enums) {
|
||||||
|
target_ienum = &ienum;
|
||||||
|
target_iconst = find_constant_by_name(p_target_cname, target_ienum->constants);
|
||||||
|
if (target_iconst) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_iconst) {
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(p_target_itype->proxy_name);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_ienum->cname);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_iconst->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else if (p_link_target_parts.size() == 1) {
|
||||||
|
// Also search in @GlobalScope as a last resort if no class was specified
|
||||||
|
_append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target);
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve constant reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target) {
|
||||||
|
// Try to find as a global constant
|
||||||
|
const ConstantInterface *target_iconst = find_constant_by_name(p_target_cname, global_constants);
|
||||||
|
|
||||||
|
if (target_iconst) {
|
||||||
|
// Found global constant
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "." BINDINGS_GLOBAL_SCOPE_CLASS ".");
|
||||||
|
p_xml_output.append(target_iconst->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
// Try to find as global enum constant
|
||||||
|
const EnumInterface *target_ienum = nullptr;
|
||||||
|
|
||||||
|
for (const EnumInterface &ienum : global_enums) {
|
||||||
|
target_ienum = &ienum;
|
||||||
|
target_iconst = find_constant_by_name(p_target_cname, target_ienum->constants);
|
||||||
|
if (target_iconst) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_iconst) {
|
||||||
|
p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
|
||||||
|
p_xml_output.append(target_ienum->cname);
|
||||||
|
p_xml_output.append(".");
|
||||||
|
p_xml_output.append(target_iconst->proxy_name);
|
||||||
|
p_xml_output.append("\"/>");
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("Cannot resolve global constant reference in documentation: '" + p_link_target + "'.");
|
||||||
|
_append_xml_undeclared(p_xml_output, p_link_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target) {
|
||||||
|
p_xml_output.append("<c>");
|
||||||
|
p_xml_output.append(p_link_target);
|
||||||
|
p_xml_output.append("</c>");
|
||||||
|
}
|
||||||
|
|
||||||
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
|
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
|
||||||
CRASH_COND(p_ienum.constants.is_empty());
|
CRASH_COND(p_ienum.constants.is_empty());
|
||||||
|
|
||||||
|
@ -658,6 +658,14 @@ class BindingsGenerator {
|
|||||||
|
|
||||||
String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype);
|
String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype);
|
||||||
|
|
||||||
|
void _append_xml_method(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
|
||||||
|
void _append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
|
||||||
|
void _append_xml_signal(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
|
||||||
|
void _append_xml_enum(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
|
||||||
|
void _append_xml_constant(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts);
|
||||||
|
void _append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target);
|
||||||
|
void _append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target);
|
||||||
|
|
||||||
int _determine_enum_prefix(const EnumInterface &p_ienum);
|
int _determine_enum_prefix(const EnumInterface &p_ienum);
|
||||||
void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
|
void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user