Replace 'ERR_EXPLAIN' with 'ERR_FAIL_*_MSG' in 'modules/mono'

And 'CRASH_*_MSG' as well.

Also make error messages puntuation and quotation more consistent.
This commit is contained in:
Ignacio Etcheverry 2019-08-09 03:39:45 +02:00
parent fe3cd51755
commit c55ce204b3
18 changed files with 200 additions and 294 deletions

View file

@ -115,7 +115,7 @@ void CSharpLanguage::init() {
gdmono->initialize(); gdmono->initialize();
#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) #if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
// Generate bindings here, before loading assemblies. `initialize_load_assemblies` aborts // Generate bindings here, before loading assemblies. 'initialize_load_assemblies' aborts
// the applications if the api assemblies or the main tools assembly is missing, but this // the applications if the api assemblies or the main tools assembly is missing, but this
// is not a problem for BindingsGenerator as it only needs the tools project editor assembly. // is not a problem for BindingsGenerator as it only needs the tools project editor assembly.
List<String> cmdline_args = OS::get_singleton()->get_cmdline_args(); List<String> cmdline_args = OS::get_singleton()->get_cmdline_args();
@ -123,7 +123,7 @@ void CSharpLanguage::init() {
#endif #endif
#ifndef MONO_GLUE_ENABLED #ifndef MONO_GLUE_ENABLED
print_line("Run this binary with `--generate-mono-glue path/to/modules/mono/glue`"); print_line("Run this binary with '--generate-mono-glue path/to/modules/mono/glue'");
#endif #endif
gdmono->initialize_load_assemblies(); gdmono->initialize_load_assemblies();
@ -1036,6 +1036,7 @@ void CSharpLanguage::_load_scripts_metadata() {
String old_json; String old_json;
Error ferr = read_all_file_utf8(scripts_metadata_path, old_json); Error ferr = read_all_file_utf8(scripts_metadata_path, old_json);
ERR_FAIL_COND(ferr != OK); ERR_FAIL_COND(ferr != OK);
Variant old_dict_var; Variant old_dict_var;
@ -1043,7 +1044,7 @@ void CSharpLanguage::_load_scripts_metadata() {
int err_line; int err_line;
Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line); Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line);
if (json_err != OK) { if (json_err != OK) {
ERR_PRINTS("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ")"); ERR_PRINTS("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ").");
return; return;
} }
@ -1053,7 +1054,7 @@ void CSharpLanguage::_load_scripts_metadata() {
print_verbose("Successfully loaded scripts metadata"); print_verbose("Successfully loaded scripts metadata");
} else { } else {
if (!Engine::get_singleton()->is_editor_hint()) { if (!Engine::get_singleton()->is_editor_hint()) {
ERR_PRINT("Missing scripts metadata file"); ERR_PRINT("Missing scripts metadata file.");
} }
} }
} }
@ -1768,12 +1769,8 @@ MonoObject *CSharpInstance::_internal_new_managed() {
// Search the constructor first, to fail with an error if it's not found before allocating anything else. // Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0); GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
if (ctor == NULL) { ERR_FAIL_NULL_V_MSG(ctor, NULL,
ERR_PRINTS("Cannot create script instance because the class does not define a parameterless constructor: " + script->get_path()); "Cannot create script instance because the class does not define a parameterless constructor: '" + script->get_path() + "'.");
ERR_EXPLAIN("Constructor not found");
ERR_FAIL_V(NULL);
}
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle); CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
@ -1792,8 +1789,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
owner = NULL; owner = NULL;
ERR_EXPLAIN("Failed to allocate memory for the object"); ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
ERR_FAIL_V(NULL);
} }
// Tie managed to unmanaged // Tie managed to unmanaged
@ -2233,7 +2229,7 @@ bool CSharpScript::_update_exports() {
MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr()); MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
if (!tmp_object) { if (!tmp_object) {
ERR_PRINT("Failed to allocate temporary MonoObject"); ERR_PRINT("Failed to allocate temporary MonoObject.");
return false; return false;
} }
@ -2241,12 +2237,8 @@ bool CSharpScript::_update_exports() {
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0); GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
if (ctor == NULL) { ERR_FAIL_NULL_V_MSG(ctor, NULL,
ERR_PRINTS("Cannot construct temporary MonoObject because the class does not define a parameterless constructor: " + get_path()); "Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
ERR_EXPLAIN("Constructor not found");
ERR_FAIL_V(NULL);
}
MonoException *ctor_exc = NULL; MonoException *ctor_exc = NULL;
ctor->invoke(tmp_object, NULL, &ctor_exc); ctor->invoke(tmp_object, NULL, &ctor_exc);
@ -2399,7 +2391,7 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve
arg.type = GDMonoMarshal::managed_to_variant_type(types[i]); arg.type = GDMonoMarshal::managed_to_variant_type(types[i]);
if (arg.type == Variant::NIL) { if (arg.type == Variant::NIL) {
ERR_PRINTS("Unknown type of signal parameter: " + arg.name + " in " + p_class->get_full_name()); ERR_PRINTS("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'.");
return false; return false;
} }
@ -2427,7 +2419,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->is_static()) { if (p_member->is_static()) {
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
ERR_PRINTS("Cannot export member because it is static: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); ERR_PRINTS("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false; return false;
} }
@ -2450,12 +2442,12 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member); GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) { if (!property->has_getter()) {
if (exported) if (exported)
ERR_PRINTS("Read-only property cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); ERR_PRINTS("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false; return false;
} }
if (!property->has_setter()) { if (!property->has_setter()) {
if (exported) if (exported)
ERR_PRINTS("Write-only property (without getter) cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); ERR_PRINTS("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false; return false;
} }
} }
@ -2474,16 +2466,15 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
String hint_string; String hint_string;
if (variant_type == Variant::NIL) { if (variant_type == Variant::NIL) {
ERR_PRINTS("Unknown exported member type: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); ERR_PRINTS("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false; return false;
} }
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string); int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
if (hint_res == -1) { ERR_FAIL_COND_V_MSG(hint_res == -1, false,
ERR_EXPLAIN("Error while trying to determine information about the exported member: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); "Error while trying to determine information about the exported member: '" +
ERR_FAIL_V(false); MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
}
if (hint_res == 0) { if (hint_res == 0) {
hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr)); hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
@ -2532,17 +2523,11 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
MonoObject *val_obj = mono_field_get_value_object(mono_domain_get(), field, NULL); MonoObject *val_obj = mono_field_get_value_object(mono_domain_get(), field, NULL);
if (val_obj == NULL) { ERR_FAIL_NULL_V_MSG(val_obj, -1, "Failed to get '" + enum_field_name + "' constant enum value.");
ERR_EXPLAIN("Failed to get '" + enum_field_name + "' constant enum value");
ERR_FAIL_V(-1);
}
bool r_error; bool r_error;
uint64_t val = GDMonoUtils::unbox_enum_value(val_obj, enum_basetype, r_error); uint64_t val = GDMonoUtils::unbox_enum_value(val_obj, enum_basetype, r_error);
if (r_error) { ERR_FAIL_COND_V_MSG(r_error, -1, "Failed to unbox '" + enum_field_name + "' constant enum value.");
ERR_EXPLAIN("Failed to unbox '" + enum_field_name + "' constant enum value");
ERR_FAIL_V(-1);
}
if (val != (unsigned int)i) { if (val != (unsigned int)i) {
uses_default_values = false; uses_default_values = false;
@ -2577,17 +2562,11 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
PropertyHint elem_hint = PROPERTY_HINT_NONE; PropertyHint elem_hint = PROPERTY_HINT_NONE;
String elem_hint_string; String elem_hint_string;
if (elem_variant_type == Variant::NIL) { ERR_FAIL_COND_V_MSG(elem_variant_type == Variant::NIL, -1, "Unknown array element type.");
ERR_EXPLAIN("Unknown array element type");
ERR_FAIL_V(-1);
}
int hint_res = _try_get_member_export_hint(p_member, elem_type, elem_variant_type, /* allow_generics: */ false, elem_hint, elem_hint_string); int hint_res = _try_get_member_export_hint(p_member, elem_type, elem_variant_type, /* allow_generics: */ false, elem_hint, elem_hint_string);
if (hint_res == -1) { ERR_FAIL_COND_V_MSG(hint_res == -1, -1, "Error while trying to determine information about the array element type.");
ERR_EXPLAIN("Error while trying to determine information about the array element type");
ERR_FAIL_V(-1);
}
// Format: type/hint:hint_string // Format: type/hint:hint_string
r_hint_string = itos(elem_variant_type) + "/" + itos(elem_hint) + ":" + elem_hint_string; r_hint_string = itos(elem_variant_type) + "/" + itos(elem_hint) + ":" + elem_hint_string;
@ -2775,7 +2754,7 @@ bool CSharpScript::can_instance() const {
"Compile", "Compile",
ProjectSettings::get_singleton()->globalize_path(get_path())); ProjectSettings::get_singleton()->globalize_path(get_path()));
} else { } else {
ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created."); ERR_PRINTS("C# project could not be created; cannot add file: '" + get_path() + "'.");
} }
} }
} }
@ -2793,12 +2772,10 @@ bool CSharpScript::can_instance() const {
if (extra_cond && !script_class) { if (extra_cond && !script_class) {
if (GDMono::get_singleton()->get_project_assembly() == NULL) { if (GDMono::get_singleton()->get_project_assembly() == NULL) {
// The project assembly is not loaded // The project assembly is not loaded
ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path()); ERR_FAIL_V_MSG(NULL, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'.");
ERR_FAIL_V(NULL);
} else { } else {
// The project assembly is loaded, but the class could not found // The project assembly is loaded, but the class could not found
ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path()); ERR_FAIL_V_MSG(NULL, "Cannot instance script because the class '" + name + "' could not be found. Script: '" + get_path() + "'.");
ERR_FAIL_V(NULL);
} }
} }
@ -2820,14 +2797,12 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Search the constructor first, to fail with an error if it's not found before allocating anything else. // Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount); GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
if (ctor == NULL) { if (ctor == NULL) {
if (p_argcount == 0) { ERR_FAIL_COND_V_MSG(p_argcount == 0, NULL,
String path = get_path(); "Cannot create script instance. The class '" + script_class->get_full_name() +
ERR_PRINTS("Cannot create script instance. The class '" + script_class->get_full_name() + "' does not define a parameterless constructor." +
"' does not define a parameterless constructor." + (path.empty() ? String() : ". Path: " + path)); (get_path().empty() ? String() : " Path: '" + get_path() + "'."));
}
ERR_EXPLAIN("Constructor not found"); ERR_FAIL_V_MSG(NULL, "Constructor not found.");
ERR_FAIL_V(NULL);
} }
Ref<Reference> ref; Ref<Reference> ref;
@ -2878,8 +2853,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
p_owner->set_script_instance(NULL); p_owner->set_script_instance(NULL);
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
ERR_EXPLAIN("Failed to allocate memory for the object"); ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
ERR_FAIL_V(NULL);
} }
// Tie managed to unmanaged // Tie managed to unmanaged
@ -2950,8 +2924,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
if (ScriptDebugger::get_singleton()) { if (ScriptDebugger::get_singleton()) {
CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"); CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
} }
ERR_EXPLAIN("Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"); ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + native_name +
ERR_FAIL_V(NULL); "', so it can't be instanced in object of type: '" + p_this->get_class() + "'.");
} }
} }
@ -3203,12 +3177,12 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
Error CSharpScript::load_source_code(const String &p_path) { Error CSharpScript::load_source_code(const String &p_path) {
Error ferr = read_all_file_utf8(p_path, source); Error ferr = read_all_file_utf8(p_path, source);
if (ferr != OK) {
if (ferr == ERR_INVALID_DATA) { ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode."); ferr == ERR_INVALID_DATA ?
} "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
ERR_FAIL_V(ferr); " Please ensure that scripts are saved in valid UTF-8 unicode." :
} "Failed to read file: '" + p_path + "'.");
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
source_changed_cache = true; source_changed_cache = true;
@ -3277,8 +3251,7 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
// User is responsible for thread attach/detach // User is responsible for thread attach/detach
ERR_EXPLAIN("Thread is not attached"); CRASH_COND_MSG(mono_domain_get() == NULL, "Thread is not attached.");
CRASH_COND(mono_domain_get() == NULL);
#endif #endif
#endif #endif
@ -3345,8 +3318,7 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
"Compile", "Compile",
ProjectSettings::get_singleton()->globalize_path(p_path)); ProjectSettings::get_singleton()->globalize_path(p_path));
} else { } else {
ERR_PRINTS("Failed to create C# project"); ERR_PRINTS("C# project could not be created; cannot add file: '" + p_path + "'.");
ERR_PRINTS("Cannot add " + p_path + " to the C# project");
} }
} }
#endif #endif

View file

@ -279,7 +279,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
Vector<String> link_target_parts = link_target.split("."); 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_PRINTS("Invalid reference format: " + tag); ERR_PRINTS("Invalid reference format: '" + tag + "'.");
xml_output.append("<c>"); xml_output.append("<c>");
xml_output.append(tag); xml_output.append(tag);
@ -375,7 +375,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any
xml_output.append("\"/>"); xml_output.append("\"/>");
} else { } else {
ERR_PRINTS("Cannot resolve enum reference in documentation: " + link_target); ERR_PRINTS("Cannot resolve enum reference in documentation: '" + link_target + "'.");
xml_output.append("<c>"); xml_output.append("<c>");
xml_output.append(link_target); xml_output.append(link_target);
@ -424,7 +424,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_iconst->proxy_name); xml_output.append(target_iconst->proxy_name);
xml_output.append("\"/>"); xml_output.append("\"/>");
} else { } else {
ERR_PRINTS("Cannot resolve global constant reference in documentation: " + link_target); ERR_PRINTS("Cannot resolve global constant reference in documentation: '" + link_target + "'.");
xml_output.append("<c>"); xml_output.append("<c>");
xml_output.append(link_target); xml_output.append(link_target);
@ -464,7 +464,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_iconst->proxy_name); xml_output.append(target_iconst->proxy_name);
xml_output.append("\"/>"); xml_output.append("\"/>");
} else { } else {
ERR_PRINTS("Cannot resolve constant reference in documentation: " + link_target); ERR_PRINTS("Cannot resolve constant reference in documentation: '" + link_target + "'.");
xml_output.append("<c>"); xml_output.append("<c>");
xml_output.append(link_target); xml_output.append(link_target);
@ -534,7 +534,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_itype->proxy_name); xml_output.append(target_itype->proxy_name);
xml_output.append("\"/>"); xml_output.append("\"/>");
} else { } else {
ERR_PRINTS("Cannot resolve type reference in documentation: " + tag); ERR_PRINTS("Cannot resolve type reference in documentation: '" + tag + "'.");
xml_output.append("<c>"); xml_output.append("<c>");
xml_output.append(tag); xml_output.append(tag);
@ -812,7 +812,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
CRASH_COND(enum_class_name != "Variant"); // Hard-coded... CRASH_COND(enum_class_name != "Variant"); // Hard-coded...
_log("Declaring global enum `%s` inside static class `%s`\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data()); _log("Declaring global enum '%s' inside static class '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data());
p_output.append("\n" INDENT1 "public static partial class "); p_output.append("\n" INDENT1 "public static partial class ");
p_output.append(enum_class_name); p_output.append(enum_class_name);
@ -1083,7 +1083,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
proj_err = generate_cs_core_project(core_proj_dir, core_compile_items); proj_err = generate_cs_core_project(core_proj_dir, core_compile_items);
if (proj_err != OK) { if (proj_err != OK) {
ERR_PRINT("Generation of the Core API C# project failed"); ERR_PRINT("Generation of the Core API C# project failed.");
return proj_err; return proj_err;
} }
@ -1094,7 +1094,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
proj_err = generate_cs_editor_project(editor_proj_dir, editor_compile_items); proj_err = generate_cs_editor_project(editor_proj_dir, editor_compile_items);
if (proj_err != OK) { if (proj_err != OK) {
ERR_PRINT("Generation of the Editor API C# project failed"); ERR_PRINT("Generation of the Editor API C# project failed.");
return proj_err; return proj_err;
} }
@ -1112,7 +1112,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// FIXME: There are some members that hide other inherited members. // FIXME: There are some members that hide other inherited members.
// - In the case of both members being the same kind, the new one must be declared // - In the case of both members being the same kind, the new one must be declared
// explicitly as `new` to avoid the warning (and we must print a message about it). // explicitly as 'new' to avoid the warning (and we must print a message about it).
// - In the case of both members being of a different kind, then the new one must // - In the case of both members being of a different kind, then the new one must
// be renamed to avoid the name collision (and we must print a warning about it). // be renamed to avoid the name collision (and we must print a warning about it).
// - Csc warning e.g.: // - Csc warning e.g.:
@ -1186,7 +1186,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(obj_types[itype.base_name].proxy_name); output.append(obj_types[itype.base_name].proxy_name);
output.append("\n"); output.append("\n");
} else { } else {
ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class " + itype.name); ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class '" + itype.name + "'.");
return ERR_INVALID_DATA; return ERR_INVALID_DATA;
} }
} }
@ -1273,11 +1273,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) { for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) {
const PropertyInterface &iprop = E->get(); const PropertyInterface &iprop = E->get();
Error prop_err = _generate_cs_property(itype, iprop, output); Error prop_err = _generate_cs_property(itype, iprop, output);
if (prop_err != OK) { ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err,
ERR_EXPLAIN("Failed to generate property '" + iprop.cname.operator String() + "Failed to generate property '" + iprop.cname.operator String() +
"' for class '" + itype.name + "'"); "' for class '" + itype.name + "'.");
ERR_FAIL_V(prop_err);
}
} }
} }
@ -1340,10 +1338,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) { for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get(); const MethodInterface &imethod = E->get();
Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output); Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output);
if (method_err != OK) { ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'"); "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
ERR_FAIL_V(method_err);
}
} }
if (itype.is_singleton) { if (itype.is_singleton) {
@ -1626,7 +1622,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (p_imethod.is_deprecated) { if (p_imethod.is_deprecated) {
if (p_imethod.deprecation_message.empty()) if (p_imethod.deprecation_message.empty())
WARN_PRINTS("An empty deprecation message is discouraged. Method: " + p_imethod.proxy_name); WARN_PRINTS("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'.");
p_output.append(MEMBER_BEGIN "[Obsolete(\""); p_output.append(MEMBER_BEGIN "[Obsolete(\"");
p_output.append(p_imethod.deprecation_message); p_output.append(p_imethod.deprecation_message);
@ -1708,8 +1704,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
Error BindingsGenerator::generate_glue(const String &p_output_dir) { Error BindingsGenerator::generate_glue(const String &p_output_dir) {
bool dir_exists = DirAccess::exists(p_output_dir); bool dir_exists = DirAccess::exists(p_output_dir);
ERR_EXPLAIN("The output directory does not exist."); ERR_FAIL_COND_V_MSG(!dir_exists, ERR_FILE_BAD_PATH, "The output directory does not exist.");
ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
StringBuilder output; StringBuilder output;
@ -1742,10 +1737,8 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) { for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get(); const MethodInterface &imethod = E->get();
Error method_err = _generate_glue_method(itype, imethod, output); Error method_err = _generate_glue_method(itype, imethod, output);
if (method_err != OK) { ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'"); "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
ERR_FAIL_V(method_err);
}
} }
if (itype.is_singleton) { if (itype.is_singleton) {
@ -1879,8 +1872,7 @@ Error BindingsGenerator::_save_file(const String &p_path, const StringBuilder &p
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE); FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
ERR_EXPLAIN("Cannot open file: " + p_path); ERR_FAIL_COND_V_MSG(!file, ERR_FILE_CANT_WRITE, "Cannot open file: '" + p_path + "'.");
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
file->store_string(p_content.as_string()); file->store_string(p_content.as_string());
file->close(); file->close();
@ -2091,7 +2083,7 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol
if (found) if (found)
return found; return found;
ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_typeref.cname.operator String()); ERR_PRINTS(String() + "Type not found. Creating placeholder: '" + p_typeref.cname.operator String() + "'.");
const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname); const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname);
@ -2175,13 +2167,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
} }
if (!ClassDB::is_class_exposed(type_cname)) { if (!ClassDB::is_class_exposed(type_cname)) {
_log("Ignoring type `%s` because it's not exposed\n", String(type_cname).utf8().get_data()); _log("Ignoring type '%s' because it's not exposed\n", String(type_cname).utf8().get_data());
class_list.pop_front(); class_list.pop_front();
continue; continue;
} }
if (!ClassDB::is_class_enabled(type_cname)) { if (!ClassDB::is_class_enabled(type_cname)) {
_log("Ignoring type `%s` because it's not enabled\n", String(type_cname).utf8().get_data()); _log("Ignoring type '%s' because it's not enabled\n", String(type_cname).utf8().get_data());
class_list.pop_front(); class_list.pop_front();
continue; continue;
} }
@ -2240,7 +2232,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the property and its enclosing type from sharing the same name // Prevent the property and its enclosing type from sharing the same name
if (iprop.proxy_name == itype.proxy_name) { if (iprop.proxy_name == itype.proxy_name) {
_log("Name of property `%s` is ambiguous with the name of its enclosing class `%s`. Renaming property to `%s_`\n", _log("Name of property '%s' is ambiguous with the name of its enclosing class '%s'. Renaming property to '%s_'\n",
iprop.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), iprop.proxy_name.utf8().get_data()); iprop.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), iprop.proxy_name.utf8().get_data());
iprop.proxy_name += "_"; iprop.proxy_name += "_";
@ -2298,28 +2290,26 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.is_vararg = m && m->is_vararg(); imethod.is_vararg = m && m->is_vararg();
if (!m && !imethod.is_virtual) { if (!m && !imethod.is_virtual) {
if (virtual_method_list.find(method_info)) { ERR_FAIL_COND_MSG(!virtual_method_list.find(method_info),
// A virtual method without the virtual flag. This is a special case. "Missing MethodBind for non-virtual method: '" + itype.name + "." + imethod.name + "'.");
// There is no method bind, so let's fallback to Godot's object.Call(string, params) // A virtual method without the virtual flag. This is a special case.
imethod.requires_object_call = true;
// The method Object.free is registered as a virtual method, but without the virtual flag. // There is no method bind, so let's fallback to Godot's object.Call(string, params)
// This is because this method is not supposed to be overridden, but called. imethod.requires_object_call = true;
// We assume the return type is void.
imethod.return_type.cname = name_cache.type_void;
// Actually, more methods like this may be added in the future, // The method Object.free is registered as a virtual method, but without the virtual flag.
// which could actually will return something different. // This is because this method is not supposed to be overridden, but called.
// Let's put this to notify us if that ever happens. // We assume the return type is void.
if (itype.cname != name_cache.type_Object || imethod.name != "free") { imethod.return_type.cname = name_cache.type_void;
ERR_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
"We only expected Object.free, but found " + // Actually, more methods like this may be added in the future,
itype.name + "." + imethod.name); // which could actually will return something different.
} // Let's put this to notify us if that ever happens.
} else { if (itype.cname != name_cache.type_Object || imethod.name != "free") {
ERR_EXPLAIN("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name); ERR_PRINTS("Notification: New unexpected virtual non-overridable method found."
ERR_FAIL(); " We only expected Object.free, but found '" +
itype.name + "." + imethod.name + "'.");
} }
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
imethod.return_type.cname = return_info.class_name; imethod.return_type.cname = return_info.class_name;
@ -2328,8 +2318,8 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.return_type.cname = return_info.class_name; imethod.return_type.cname = return_info.class_name;
if (!imethod.is_virtual && ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference) && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE) { if (!imethod.is_virtual && ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference) && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE) {
/* clang-format off */ /* clang-format off */
ERR_PRINTS("Return type is reference but hint is not " _STR(PROPERTY_HINT_RESOURCE_TYPE) "." ERR_PRINTS("Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'."
" Are you returning a reference type by pointer? Method: " + itype.name + "." + imethod.name); " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'.");
/* clang-format on */ /* clang-format on */
ERR_FAIL(); ERR_FAIL();
} }
@ -2394,7 +2384,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the method and its enclosing type from sharing the same name // Prevent the method and its enclosing type from sharing the same name
if (imethod.proxy_name == itype.proxy_name) { if (imethod.proxy_name == itype.proxy_name) {
_log("Name of method `%s` is ambiguous with the name of its enclosing class `%s`. Renaming method to `%s_`\n", _log("Name of method '%s' is ambiguous with the name of its enclosing class '%s'. Renaming method to '%s_'\n",
imethod.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), imethod.proxy_name.utf8().get_data()); imethod.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), imethod.proxy_name.utf8().get_data());
imethod.proxy_name += "_"; imethod.proxy_name += "_";
@ -2880,8 +2870,7 @@ void BindingsGenerator::_populate_global_constants() {
if (global_constants_count > 0) { if (global_constants_count > 0) {
Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope"); Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope");
ERR_EXPLAIN("Could not find `@GlobalScope` in DocData"); CRASH_COND_MSG(!match, "Could not find '@GlobalScope' in DocData.");
CRASH_COND(!match);
const DocData::ClassDoc &global_scope_doc = match->value(); const DocData::ClassDoc &global_scope_doc = match->value();
@ -2935,7 +2924,7 @@ void BindingsGenerator::_populate_global_constants() {
// HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'. // HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'.
if (ienum.cname == name_cache.enum_Error) { if (ienum.cname == name_cache.enum_Error) {
if (prefix_length > 0) { // Just in case it ever changes if (prefix_length > 0) { // Just in case it ever changes
ERR_PRINTS("Prefix for enum 'Error' is not empty"); ERR_PRINTS("Prefix for enum '" _STR(Error) "' is not empty.");
} }
prefix_length = 1; // 'ERR_' prefix_length = 1; // 'ERR_'
@ -3024,7 +3013,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
glue_dir_path = path_elem->get(); glue_dir_path = path_elem->get();
elem = elem->next(); elem = elem->next();
} else { } else {
ERR_PRINTS(generate_all_glue_option + ": No output directory specified (expected path to {GODOT_ROOT}/modules/mono/glue)"); ERR_PRINTS(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue').");
} }
--options_left; --options_left;
@ -3035,7 +3024,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cs_dir_path = path_elem->get(); cs_dir_path = path_elem->get();
elem = elem->next(); elem = elem->next();
} else { } else {
ERR_PRINTS(generate_cs_glue_option + ": No output directory specified"); ERR_PRINTS(generate_cs_glue_option + ": No output directory specified.");
} }
--options_left; --options_left;
@ -3046,7 +3035,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cpp_dir_path = path_elem->get(); cpp_dir_path = path_elem->get();
elem = elem->next(); elem = elem->next();
} else { } else {
ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified"); ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified.");
} }
--options_left; --options_left;
@ -3061,20 +3050,20 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
if (glue_dir_path.length()) { if (glue_dir_path.length()) {
if (bindings_generator.generate_glue(glue_dir_path) != OK) if (bindings_generator.generate_glue(glue_dir_path) != OK)
ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C++ glue"); ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C++ glue.");
if (bindings_generator.generate_cs_api(glue_dir_path.plus_file("Managed/Generated")) != OK) if (bindings_generator.generate_cs_api(glue_dir_path.plus_file("Managed/Generated")) != OK)
ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C# API"); ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C# API.");
} }
if (cs_dir_path.length()) { if (cs_dir_path.length()) {
if (bindings_generator.generate_cs_api(cs_dir_path) != OK) if (bindings_generator.generate_cs_api(cs_dir_path) != OK)
ERR_PRINTS(generate_cs_glue_option + ": Failed to generate the C# API"); ERR_PRINTS(generate_cs_glue_option + ": Failed to generate the C# API.");
} }
if (cpp_dir_path.length()) { if (cpp_dir_path.length()) {
if (bindings_generator.generate_glue(cpp_dir_path) != OK) if (bindings_generator.generate_glue(cpp_dir_path) != OK)
ERR_PRINTS(generate_cpp_glue_option + ": Failed to generate the C++ glue"); ERR_PRINTS(generate_cpp_glue_option + ": Failed to generate the C++ glue.");
} }
// Exit once done // Exit once done

View file

@ -147,7 +147,7 @@ class BindingsGenerator {
bool requires_object_call; bool requires_object_call;
/** /**
* Determines if the method visibility is `internal` (visible only to files in the same assembly). * Determines if the method visibility is 'internal' (visible only to files in the same assembly).
* Currently, we only use this for methods that are not meant to be exposed, * Currently, we only use this for methods that are not meant to be exposed,
* but are required by properties as getters or setters. * but are required by properties as getters or setters.
* Methods that are not meant to be exposed are those that begin with underscore and are not virtual. * Methods that are not meant to be exposed are those that begin with underscore and are not virtual.

View file

@ -81,16 +81,14 @@ bool generate_api_solution(const String &p_solution_dir, const String &p_core_pr
_GDMONO_SCOPE_DOMAIN_(temp_domain); _GDMONO_SCOPE_DOMAIN_(temp_domain);
GDMonoAssembly *tools_project_editor_assembly = NULL; GDMonoAssembly *tools_project_editor_asm = NULL;
if (!GDMono::get_singleton()->load_assembly("GodotTools.ProjectEditor", &tools_project_editor_assembly)) { bool assembly_loaded = GDMono::get_singleton()->load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_asm);
ERR_EXPLAIN("Failed to load assembly: 'GodotTools.ProjectEditor'"); ERR_FAIL_COND_V_MSG(!assembly_loaded, false, "Failed to load assembly: '" TOOLS_PROJECT_EDITOR_ASM_NAME "'.");
ERR_FAIL_V(false);
}
return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items, return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items,
p_editor_proj_dir, p_editor_compile_items, p_editor_proj_dir, p_editor_compile_items,
tools_project_editor_assembly); tools_project_editor_asm);
} }
} }

View file

@ -85,18 +85,12 @@ Error GodotSharpExport::get_assembly_dependencies(GDMonoAssembly *p_assembly, co
} }
} }
if (!ref_assembly) { ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
ERR_EXPLAIN("Cannot load assembly (refonly): " + ref_name);
ERR_FAIL_V(ERR_CANT_RESOLVE);
}
r_dependencies[ref_name] = ref_assembly->get_path(); r_dependencies[ref_name] = ref_assembly->get_path();
Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
if (err != OK) { ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
ERR_EXPLAIN("Cannot load one of the dependencies for the assembly: " + ref_name);
ERR_FAIL_V(err);
}
} }
return OK; return OK;
@ -113,8 +107,7 @@ Error GodotSharpExport::get_exported_assembly_dependencies(const String &p_proje
bool load_success = GDMono::get_singleton()->load_assembly_from(p_project_dll_name, bool load_success = GDMono::get_singleton()->load_assembly_from(p_project_dll_name,
p_project_dll_src_path, &scripts_assembly, /* refonly: */ true); p_project_dll_src_path, &scripts_assembly, /* refonly: */ true);
ERR_EXPLAIN("Cannot load assembly (refonly): " + p_project_dll_name); ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + p_project_dll_name + "'.");
ERR_FAIL_COND_V(!load_success, ERR_CANT_RESOLVE);
Vector<String> search_dirs; Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_lib_dir); GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_lib_dir);

View file

@ -162,8 +162,8 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
error = true; error = true;
return TK_ERROR; return TK_ERROR;
} else if (code[idx] == begin_str) { } else if (code[idx] == begin_str) {
if (verbatim && code[idx + 1] == '"') { // `""` is verbatim string's `\"` if (verbatim && code[idx + 1] == '"') { // '""' is verbatim string's '\"'
idx += 2; // skip next `"` as well idx += 2; // skip next '"' as well
continue; continue;
} }
@ -590,7 +590,7 @@ Error ScriptClassParser::parse(const String &p_code) {
name = String(value); name = String(value);
} else if (tk == TK_CURLY_BRACKET_OPEN) { } else if (tk == TK_CURLY_BRACKET_OPEN) {
if (name.empty()) { if (name.empty()) {
error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword `struct`, found " + get_token_name(TK_CURLY_BRACKET_OPEN); error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword 'struct', found " + get_token_name(TK_CURLY_BRACKET_OPEN);
error = true; error = true;
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
@ -657,12 +657,12 @@ Error ScriptClassParser::parse_file(const String &p_filepath) {
String source; String source;
Error ferr = read_all_file_utf8(p_filepath, source); Error ferr = read_all_file_utf8(p_filepath, source);
if (ferr != OK) {
if (ferr == ERR_INVALID_DATA) { ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ERR_EXPLAIN("File '" + p_filepath + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode."); ferr == ERR_INVALID_DATA ?
} "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded."
ERR_FAIL_V(ferr); " Please ensure that scripts are saved in valid UTF-8 unicode." :
} "Failed to read file: '" + p_filepath + "'.");
return parse(source); return parse(source);
} }

View file

@ -167,7 +167,7 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
int line; int line;
Error err = VariantParser::parse(&ss, ret, errs, line); Error err = VariantParser::parse(&ss, ret, errs, line);
if (err != OK) { if (err != OK) {
String err_str = "Parse error at line " + itos(line) + ": " + errs; String err_str = "Parse error at line " + itos(line) + ": " + errs + ".";
ERR_PRINTS(err_str); ERR_PRINTS(err_str);
ret = err_str; ret = err_str;
} }
@ -193,8 +193,7 @@ MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_object
PoolByteArray barr; PoolByteArray barr;
int len; int len;
Error err = encode_variant(var, NULL, len, p_full_objects); Error err = encode_variant(var, NULL, len, p_full_objects);
ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID)."); ERR_FAIL_COND_V_MSG(err != OK, NULL, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
ERR_FAIL_COND_V(err != OK, NULL);
barr.resize(len); barr.resize(len);
{ {

View file

@ -39,8 +39,8 @@
#define API_SOLUTION_NAME "GodotSharp" #define API_SOLUTION_NAME "GodotSharp"
#define CORE_API_ASSEMBLY_NAME "GodotSharp" #define CORE_API_ASSEMBLY_NAME "GodotSharp"
#define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor" #define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor"
#define TOOLS_ASSEMBLY_NAME "GodotTools" #define TOOLS_ASM_NAME "GodotTools"
#define TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME "GodotTools.ProjectEditor" #define TOOLS_PROJECT_EDITOR_ASM_NAME "GodotTools.ProjectEditor"
#define BINDINGS_CLASS_NATIVECALLS "NativeCalls" #define BINDINGS_CLASS_NATIVECALLS "NativeCalls"
#define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls" #define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls"

View file

@ -265,7 +265,7 @@ void GDMono::initialize() {
#ifdef WINDOWS_ENABLED #ifdef WINDOWS_ENABLED
if (assembly_rootdir.empty() || config_dir.empty()) { if (assembly_rootdir.empty() || config_dir.empty()) {
ERR_PRINT("Cannot find Mono in the registry"); ERR_PRINT("Cannot find Mono in the registry.");
// Assertion: if they are not set, then they weren't found in the registry // Assertion: if they are not set, then they weren't found in the registry
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0); CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
} }
@ -318,9 +318,7 @@ void GDMono::initialize() {
#endif #endif
root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319"); root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319");
ERR_FAIL_NULL_MSG(root_domain, "Mono: Failed to initialize runtime.");
ERR_EXPLAIN("Mono: Failed to initialize runtime");
ERR_FAIL_NULL(root_domain);
GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread()); GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread());
@ -331,11 +329,11 @@ void GDMono::initialize() {
print_verbose("Mono: Runtime initialized"); print_verbose("Mono: Runtime initialized");
// mscorlib assembly MUST be present at initialization // mscorlib assembly MUST be present at initialization
ERR_EXPLAIN("Mono: Failed to load mscorlib assembly"); bool corlib_loaded = _load_corlib_assembly();
ERR_FAIL_COND(!_load_corlib_assembly()); ERR_FAIL_COND_MSG(!corlib_loaded, "Mono: Failed to load mscorlib assembly.");
ERR_EXPLAIN("Mono: Failed to load scripts domain"); Error domain_load_err = _load_scripts_domain();
ERR_FAIL_COND(_load_scripts_domain() != OK); ERR_FAIL_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
bool debugger_attached = _wait_for_debugger_msecs(500); bool debugger_attached = _wait_for_debugger_msecs(500);
@ -351,8 +349,7 @@ void GDMono::initialize() {
void GDMono::initialize_load_assemblies() { void GDMono::initialize_load_assemblies() {
#ifndef MONO_GLUE_ENABLED #ifndef MONO_GLUE_ENABLED
ERR_EXPLAIN("Mono: This binary was built with `mono_glue=no`; cannot load assemblies"); CRASH_NOW_MSG("Mono: This binary was built with 'mono_glue=no'; cannot load assemblies.");
CRASH_NOW();
#endif #endif
// Load assemblies. The API and tools assemblies are required, // Load assemblies. The API and tools assemblies are required,
@ -361,10 +358,8 @@ void GDMono::initialize_load_assemblies() {
_load_api_assemblies(); _load_api_assemblies();
#if defined(TOOLS_ENABLED) #if defined(TOOLS_ENABLED)
if (!_load_tools_assemblies()) { bool tool_assemblies_loaded = _load_tools_assemblies();
ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies"); CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
CRASH_NOW();
}
#endif #endif
// Load the project's main assembly. This doesn't necessarily need to succeed. // Load the project's main assembly. This doesn't necessarily need to succeed.
@ -428,12 +423,12 @@ void GDMono::_initialize_and_check_api_hashes() {
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) { if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) {
ERR_PRINT("Mono: Core API hash mismatch!"); ERR_PRINT("Mono: Core API hash mismatch.");
} }
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (get_api_editor_hash() != GodotSharpBindings::get_editor_api_hash()) { if (get_api_editor_hash() != GodotSharpBindings::get_editor_api_hash()) {
ERR_PRINT("Mono: Editor API hash mismatch!"); ERR_PRINT("Mono: Editor API hash mismatch.");
} }
#endif // TOOLS_ENABLED #endif // TOOLS_ENABLED
#endif // MONO_GLUE_ENABLED #endif // MONO_GLUE_ENABLED
@ -579,7 +574,7 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
memdelete(da); memdelete(da);
if (err != OK) { if (err != OK) {
ERR_PRINTS("Failed to create destination directory for the API assemblies. Error: " + itos(err)); ERR_PRINTS("Failed to create destination directory for the API assemblies. Error: " + itos(err) + ".");
return false; return false;
} }
} }
@ -593,16 +588,16 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
String xml_file = assembly_name + ".xml"; String xml_file = assembly_name + ".xml";
if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK)
WARN_PRINTS("Failed to copy " + xml_file); WARN_PRINTS("Failed to copy '" + xml_file + "'.");
String pdb_file = assembly_name + ".pdb"; String pdb_file = assembly_name + ".pdb";
if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK)
WARN_PRINTS("Failed to copy " + pdb_file); WARN_PRINTS("Failed to copy '" + pdb_file + "'.");
Error err = da->copy(assembly_src, assembly_dst); Error err = da->copy(assembly_src, assembly_dst);
if (err != OK) { if (err != OK) {
ERR_PRINTS("Failed to copy " + assembly_file); ERR_PRINTS("Failed to copy '" + assembly_file + "'.");
return false; return false;
} }
@ -617,11 +612,11 @@ String GDMono::update_api_assemblies_from_prebuilt() {
#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ #define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \ ( \
(m_out_of_sync ? \ (m_out_of_sync ? \
String("The assembly is invalidated") : \ String("The assembly is invalidated ") : \
String("The assembly was not found")) + \ String("The assembly was not found ")) + \
(m_prebuilt_exists ? \ (m_prebuilt_exists ? \
String(" and the prebuilt assemblies are missing") : \ String("and the prebuilt assemblies are missing.") : \
String(" and we failed to copy the prebuilt assemblies"))) String("and we failed to copy the prebuilt assemblies.")))
bool api_assembly_out_of_sync = core_api_assembly_out_of_sync || editor_api_assembly_out_of_sync; bool api_assembly_out_of_sync = core_api_assembly_out_of_sync || editor_api_assembly_out_of_sync;
@ -755,29 +750,19 @@ void GDMono::_load_api_assemblies() {
// update them from the prebuilt assemblies directory before trying to load them. // update them from the prebuilt assemblies directory before trying to load them.
// Shouldn't happen. The project manager loads the prebuilt API assemblies // Shouldn't happen. The project manager loads the prebuilt API assemblies
if (Main::is_project_manager()) { CRASH_COND_MSG(Main::is_project_manager(), "Failed to load one of the prebuilt API assemblies.");
ERR_EXPLAIN("Failed to load one of the prebuilt API assemblies");
CRASH_NOW();
}
// 1. Unload the scripts domain // 1. Unload the scripts domain
if (_unload_scripts_domain() != OK) { Error domain_unload_err = _unload_scripts_domain();
ERR_EXPLAIN("Mono: Failed to unload scripts domain"); CRASH_COND_MSG(domain_unload_err != OK, "Mono: Failed to unload scripts domain.");
CRASH_NOW();
}
// 2. Update the API assemblies // 2. Update the API assemblies
String update_error = update_api_assemblies_from_prebuilt(); String update_error = update_api_assemblies_from_prebuilt();
if (!update_error.empty()) { CRASH_COND_MSG(!update_error.empty(), update_error);
ERR_EXPLAIN(update_error);
CRASH_NOW();
}
// 3. Load the scripts domain again // 3. Load the scripts domain again
if (_load_scripts_domain() != OK) { Error domain_load_err = _load_scripts_domain();
ERR_EXPLAIN("Mono: Failed to load scripts domain"); CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
CRASH_NOW();
}
// 4. Try loading the updated assemblies // 4. Try loading the updated assemblies
if (!_try_load_api_assemblies()) { if (!_try_load_api_assemblies()) {
@ -785,24 +770,22 @@ void GDMono::_load_api_assemblies() {
if (_are_api_assemblies_out_of_sync()) { if (_are_api_assemblies_out_of_sync()) {
if (core_api_assembly_out_of_sync) { if (core_api_assembly_out_of_sync) {
ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync"); ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync.");
} else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) {
ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed"); ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed.");
} }
if (editor_api_assembly_out_of_sync) { if (editor_api_assembly_out_of_sync) {
ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync"); ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync.");
} }
CRASH_NOW(); CRASH_NOW();
} else { } else {
ERR_EXPLAIN("Failed to load one of the API assemblies"); CRASH_NOW_MSG("Failed to load one of the API assemblies.");
CRASH_NOW();
} }
} }
#else #else
ERR_EXPLAIN("Failed to load one of the API assemblies"); CRASH_NOW_MSG("Failed to load one of the API assemblies.");
CRASH_NOW();
#endif #endif
} }
} }
@ -813,8 +796,8 @@ bool GDMono::_load_tools_assemblies() {
if (tools_assembly && tools_project_editor_assembly) if (tools_assembly && tools_project_editor_assembly)
return true; return true;
bool success = load_assembly(TOOLS_ASSEMBLY_NAME, &tools_assembly) && bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
load_assembly(TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME, &tools_project_editor_assembly); load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
return success; return success;
} }
@ -851,7 +834,7 @@ void GDMono::_install_trace_listener() {
(DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener"); (DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener");
install_func((MonoObject **)&exc); install_func((MonoObject **)&exc);
if (exc) { if (exc) {
ERR_PRINT("Failed to install System.Diagnostics.Trace listener"); ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener.");
GDMonoUtils::debug_print_unhandled_exception(exc); GDMonoUtils::debug_print_unhandled_exception(exc);
} }
#endif #endif
@ -865,8 +848,7 @@ Error GDMono::_load_scripts_domain() {
scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain"); scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain");
ERR_EXPLAIN("Mono: Could not create scripts app domain"); ERR_FAIL_NULL_V_MSG(scripts_domain, ERR_CANT_CREATE, "Mono: Could not create scripts app domain.");
ERR_FAIL_NULL_V(scripts_domain, ERR_CANT_CREATE);
mono_domain_set(scripts_domain, true); mono_domain_set(scripts_domain, true);
@ -885,7 +867,7 @@ Error GDMono::_unload_scripts_domain() {
finalizing_scripts_domain = true; finalizing_scripts_domain = true;
if (!mono_domain_finalize(scripts_domain, 2000)) { if (!mono_domain_finalize(scripts_domain, 2000)) {
ERR_PRINT("Mono: Domain finalization timeout"); ERR_PRINT("Mono: Domain finalization timeout.");
} }
finalizing_scripts_domain = false; finalizing_scripts_domain = false;
@ -911,7 +893,7 @@ Error GDMono::_unload_scripts_domain() {
mono_domain_try_unload(domain, (MonoObject **)&exc); mono_domain_try_unload(domain, (MonoObject **)&exc);
if (exc) { if (exc) {
ERR_PRINT("Exception thrown when unloading scripts domain"); ERR_PRINT("Exception thrown when unloading scripts domain.");
GDMonoUtils::debug_unhandled_exception(exc); GDMonoUtils::debug_unhandled_exception(exc);
return FAILED; return FAILED;
} }
@ -925,20 +907,14 @@ Error GDMono::reload_scripts_domain() {
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG); ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
if (scripts_domain) { if (scripts_domain) {
Error err = _unload_scripts_domain(); Error domain_unload_err = _unload_scripts_domain();
if (err != OK) { ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain.");
ERR_PRINT("Mono: Failed to unload scripts domain");
return err;
}
} }
CSharpLanguage::get_singleton()->_on_scripts_domain_unloaded(); CSharpLanguage::get_singleton()->_on_scripts_domain_unloaded();
Error err = _load_scripts_domain(); Error domain_load_err = _load_scripts_domain();
if (err != OK) { ERR_FAIL_COND_V_MSG(domain_load_err != OK, domain_load_err, "Mono: Failed to load scripts domain.");
ERR_PRINT("Mono: Failed to load scripts domain");
return err;
}
// Load assemblies. The API and tools assemblies are required, // Load assemblies. The API and tools assemblies are required,
// the application is aborted if these assemblies cannot be loaded. // the application is aborted if these assemblies cannot be loaded.
@ -946,10 +922,8 @@ Error GDMono::reload_scripts_domain() {
_load_api_assemblies(); _load_api_assemblies();
#if defined(TOOLS_ENABLED) #if defined(TOOLS_ENABLED)
if (!_load_tools_assemblies()) { bool tools_assemblies_loaded = _load_tools_assemblies();
ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies"); CRASH_COND_MSG(!tools_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
CRASH_NOW();
}
#endif #endif
// Load the project's main assembly. Here, during hot-reloading, we do // Load the project's main assembly. Here, during hot-reloading, we do
@ -971,13 +945,13 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
String domain_name = mono_domain_get_friendly_name(p_domain); String domain_name = mono_domain_get_friendly_name(p_domain);
print_verbose("Mono: Unloading domain `" + domain_name + "`..."); print_verbose("Mono: Unloading domain '" + domain_name + "'...");
if (mono_domain_get() == p_domain) if (mono_domain_get() == p_domain)
mono_domain_set(root_domain, true); mono_domain_set(root_domain, true);
if (!mono_domain_finalize(p_domain, 2000)) { if (!mono_domain_finalize(p_domain, 2000)) {
ERR_PRINT("Mono: Domain finalization timeout"); ERR_PRINT("Mono: Domain finalization timeout.");
} }
mono_gc_collect(mono_gc_max_generation()); mono_gc_collect(mono_gc_max_generation());
@ -988,7 +962,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
mono_domain_try_unload(p_domain, (MonoObject **)&exc); mono_domain_try_unload(p_domain, (MonoObject **)&exc);
if (exc) { if (exc) {
ERR_PRINTS("Exception thrown when unloading domain `" + domain_name + "`"); ERR_PRINTS("Exception thrown when unloading domain '" + domain_name + "'.");
GDMonoUtils::debug_print_unhandled_exception(exc); GDMonoUtils::debug_print_unhandled_exception(exc);
return FAILED; return FAILED;
} }
@ -1105,7 +1079,7 @@ GDMono::~GDMono() {
if (scripts_domain) { if (scripts_domain) {
Error err = _unload_scripts_domain(); Error err = _unload_scripts_domain();
if (err != OK) { if (err != OK) {
ERR_PRINT("Mono: Failed to unload scripts domain"); ERR_PRINT("Mono: Failed to unload scripts domain.");
} }
} }

View file

@ -151,14 +151,14 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, vo
} }
{ {
// If we find the assembly here, we load it with `mono_assembly_load_from_full`, // If we find the assembly here, we load it with 'mono_assembly_load_from_full',
// which in turn invokes load hooks before returning the MonoAssembly to us. // which in turn invokes load hooks before returning the MonoAssembly to us.
// One of the load hooks is `load_aot_module`. This hook can end up calling preload hooks // One of the load hooks is 'load_aot_module'. This hook can end up calling preload hooks
// again for the same assembly in certain in certain circumstances (the `do_load_image` part). // again for the same assembly in certain in certain circumstances (the 'do_load_image' part).
// If this is the case and we return NULL due to the no_search condition below, // If this is the case and we return NULL due to the no_search condition below,
// it will result in an internal crash later on. Therefore we need to return the assembly we didn't // it will result in an internal crash later on. Therefore we need to return the assembly we didn't
// get yet from `mono_assembly_load_from_full`. Luckily we have the image, which already got it. // get yet from 'mono_assembly_load_from_full'. Luckily we have the image, which already got it.
// This must be done here. If done in search hooks, it would cause `mono_assembly_load_from_full` // This must be done here. If done in search hooks, it would cause 'mono_assembly_load_from_full'
// to think another MonoAssembly for this assembly was already loaded, making it delete its own, // to think another MonoAssembly for this assembly was already loaded, making it delete its own,
// when in fact both pointers were the same... This hooks thing is confusing. // when in fact both pointers were the same... This hooks thing is confusing.
if (image_corlib_loading) { if (image_corlib_loading) {

View file

@ -165,8 +165,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")"; String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")";
WARN_PRINTS("Method `" + fullname + "` is hidden by Godot API method. Should be `" + WARN_PRINTS("Method '" + fullname + "' is hidden by Godot API method. Should be '" +
method->get_full_name_no_class() + "`. In class `" + namespace_name + "." + class_name + "`."); method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'.");
#endif #endif
continue; continue;
} }
@ -184,8 +184,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
if (m && m->get_name() != name) { if (m && m->get_name() != name) {
// found // found
String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")"; String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")";
WARN_PRINTS("Method `" + fullname + "` should be `" + m->get_full_name_no_class() + WARN_PRINTS("Method '" + fullname + "' should be '" + m->get_full_name_no_class() +
"`. In class `" + namespace_name + "." + class_name + "`."); "'. In class '" + namespace_name + "." + class_name + "'.");
break; break;
} }

View file

@ -219,16 +219,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break; break;
} }
default: { default: {
ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type."); ERR_FAIL_MSG("Attempted to convert Variant to a managed enum value of unmarshallable base type.");
ERR_FAIL();
} }
} }
break; break;
} }
ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name()); ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + tclass->get_name() + "'.");
ERR_FAIL();
} break; } break;
case MONO_TYPE_ARRAY: case MONO_TYPE_ARRAY:
@ -275,8 +273,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break; break;
} }
ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
ERR_FAIL();
} break; } break;
case MONO_TYPE_CLASS: { case MONO_TYPE_CLASS: {
@ -351,8 +348,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
} }
} }
ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name()); ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
ERR_FAIL();
} break; } break;
case MONO_TYPE_OBJECT: { case MONO_TYPE_OBJECT: {
@ -508,7 +504,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
} break; } break;
default: { default: {
ERR_PRINTS(String() + "Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding)); ERR_PRINTS("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + ".");
} break; } break;
} }

View file

@ -48,7 +48,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
CRASH_COND(!unmanaged); CRASH_COND(!unmanaged);
// All mono objects created from the managed world (e.g.: `new Player()`) // All mono objects created from the managed world (e.g.: 'new Player()')
// need to have a CSharpScript in order for their methods to be callable from the unmanaged side // need to have a CSharpScript in order for their methods to be callable from the unmanaged side
Reference *ref = Object::cast_to<Reference>(unmanaged); Reference *ref = Object::cast_to<Reference>(unmanaged);

View file

@ -72,7 +72,7 @@ static void mono_log_callback(const char *log_domain, const char *log_level, con
} }
if (fatal) { if (fatal) {
ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: " + GDMonoLog::get_singleton()->get_log_file_path() + "\n"); ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->get_log_file_path() + "'.");
// Make sure to flush before aborting // Make sure to flush before aborting
f->flush(); f->flush();
f->close(); f->close();
@ -90,8 +90,7 @@ bool GDMonoLog::_try_create_logs_dir(const String &p_logs_dir) {
DirAccessRef diraccess = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); DirAccessRef diraccess = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
ERR_FAIL_COND_V(!diraccess, false); ERR_FAIL_COND_V(!diraccess, false);
Error logs_mkdir_err = diraccess->make_dir_recursive(p_logs_dir); Error logs_mkdir_err = diraccess->make_dir_recursive(p_logs_dir);
ERR_EXPLAIN("Failed to create mono logs directory"); ERR_FAIL_COND_V_MSG(logs_mkdir_err != OK, false, "Failed to create mono logs directory.");
ERR_FAIL_COND_V(logs_mkdir_err != OK, false);
} }
return true; return true;
@ -131,7 +130,7 @@ void GDMonoLog::initialize() {
CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8(); CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8();
if (log_level.length() != 0 && log_level_get_id(log_level.get_data()) == -1) { if (log_level.length() != 0 && log_level_get_id(log_level.get_data()) == -1) {
ERR_PRINTS(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): " + log_level.get_data()); ERR_PRINTS(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): '" + log_level.get_data() + "'.");
log_level = CharString(); log_level = CharString();
} }
@ -160,7 +159,7 @@ void GDMonoLog::initialize() {
log_file = FileAccess::open(log_file_path, FileAccess::WRITE); log_file = FileAccess::open(log_file_path, FileAccess::WRITE);
if (!log_file) { if (!log_file) {
ERR_PRINT("Mono: Cannot create log file"); ERR_PRINT("Mono: Cannot create log file.");
} }
} }

View file

@ -276,7 +276,7 @@ String mono_to_utf8_string(MonoString *p_mono_string) {
char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error); char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
if (!mono_error_ok(&error)) { if (!mono_error_ok(&error)) {
ERR_PRINTS(String("Failed to convert MonoString* to UTF-8: ") + mono_error_get_message(&error)); ERR_PRINTS(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'.");
mono_error_cleanup(&error); mono_error_cleanup(&error);
return String(); return String();
} }
@ -474,8 +474,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return BOX_ENUM(enum_baseclass, val); return BOX_ENUM(enum_baseclass, val);
} }
default: { default: {
ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type."); ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
ERR_FAIL_V(NULL);
} }
} }
} }
@ -509,8 +508,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (array_type->eklass == CACHED_CLASS_RAW(Color)) if (array_type->eklass == CACHED_CLASS_RAW(Color))
return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray()); return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed array of unmarshallable element type.");
ERR_FAIL_V(NULL);
} break; } break;
case MONO_TYPE_CLASS: { case MONO_TYPE_CLASS: {
@ -695,9 +693,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
} break; } break;
} }
ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" + ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to an unmarshallable managed type. Name: '" +
p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding)); p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + ".");
ERR_FAIL_V(NULL);
} }
Variant mono_object_to_variant(MonoObject *p_obj) { Variant mono_object_to_variant(MonoObject *p_obj) {
@ -809,8 +806,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
if (array_type->eklass == CACHED_CLASS_RAW(Color)) if (array_type->eklass == CACHED_CLASS_RAW(Color))
return mono_array_to_PoolColorArray((MonoArray *)p_obj); return mono_array_to_PoolColorArray((MonoArray *)p_obj);
ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant."); ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
ERR_FAIL_V(Variant());
} break; } break;
case MONO_TYPE_CLASS: { case MONO_TYPE_CLASS: {
@ -908,9 +904,8 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
} break; } break;
} }
ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" + ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" +
type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding)); type.type_class->get_name() + "' Encoding: " + itos(type.type_encoding) + ".");
ERR_FAIL_V(Variant());
} }
MonoArray *Array_to_mono_array(const Array &p_array) { MonoArray *Array_to_mono_array(const Array &p_array) {

View file

@ -52,14 +52,11 @@ namespace GDMonoUtils {
MonoCache mono_cache; MonoCache mono_cache;
#define CACHE_AND_CHECK(m_var, m_val) \ #define CACHE_AND_CHECK(m_var, m_val) \
{ \ { \
CRASH_COND(m_var != NULL); \ CRASH_COND(m_var != NULL); \
m_var = m_val; \ m_var = m_val; \
if (!m_var) { \ ERR_FAIL_COND_MSG(!m_var, "Mono Cache: Member " #m_var " is null."); \
ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
ERR_FAIL(); \
} \
} }
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val) #define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val)
@ -453,10 +450,9 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) {
} }
MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) { MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) {
if (!ClassDB::is_parent_class(p_object->get_class_name(), p_native)) { bool parent_is_object_class = ClassDB::is_parent_class(p_object->get_class_name(), p_native);
ERR_EXPLAIN("Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'"); ERR_FAIL_COND_V_MSG(!parent_is_object_class, NULL,
ERR_FAIL_V(NULL); "Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'.");
}
MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
ERR_FAIL_NULL_V(mono_object, NULL); ERR_FAIL_NULL_V(mono_object, NULL);

View file

@ -67,10 +67,8 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) { ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(),
ERR_EXPLAIN("Resumed after await, but class instance is gone"); "Resumed after await, but class instance is gone.");
ERR_FAIL_V(Variant());
}
#endif #endif
if (p_argcount < 1) { if (p_argcount < 1) {

View file

@ -55,10 +55,7 @@ int sfind(const String &p_text, int p_from) {
for (int j = 0; j < src_len; j++) { for (int j = 0; j < src_len; j++) {
int read_pos = i + j; int read_pos = i + j;
if (read_pos >= len) { ERR_FAIL_COND_V(read_pos >= len, -1);
ERR_PRINT("read_pos >= len");
return -1;
};
switch (j) { switch (j) {
case 0: case 0: