Merge pull request #31221 from neikeq/err-explain-to-msg-mono

Replace 'ERR_EXPLAIN' with 'ERR_FAIL_*_MSG' in 'modules/mono'
This commit is contained in:
Rémi Verschelde 2019-08-09 12:40:05 +02:00 committed by GitHub
commit 3ea33c0e45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 200 additions and 294 deletions

View File

@ -115,7 +115,7 @@ void CSharpLanguage::init() {
gdmono->initialize();
#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
// 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();
@ -123,7 +123,7 @@ void CSharpLanguage::init() {
#endif
#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
gdmono->initialize_load_assemblies();
@ -1036,6 +1036,7 @@ void CSharpLanguage::_load_scripts_metadata() {
String old_json;
Error ferr = read_all_file_utf8(scripts_metadata_path, old_json);
ERR_FAIL_COND(ferr != OK);
Variant old_dict_var;
@ -1043,7 +1044,7 @@ void CSharpLanguage::_load_scripts_metadata() {
int err_line;
Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line);
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;
}
@ -1053,7 +1054,7 @@ void CSharpLanguage::_load_scripts_metadata() {
print_verbose("Successfully loaded scripts metadata");
} else {
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.
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
if (ctor == NULL) {
ERR_PRINTS("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);
}
ERR_FAIL_NULL_V_MSG(ctor, NULL,
"Cannot create script instance because the class does not define a parameterless constructor: '" + script->get_path() + "'.");
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
@ -1792,8 +1789,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
owner = NULL;
ERR_EXPLAIN("Failed to allocate memory for the object");
ERR_FAIL_V(NULL);
ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
}
// 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());
if (!tmp_object) {
ERR_PRINT("Failed to allocate temporary MonoObject");
ERR_PRINT("Failed to allocate temporary MonoObject.");
return false;
}
@ -2241,12 +2237,8 @@ bool CSharpScript::_update_exports() {
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
if (ctor == NULL) {
ERR_PRINTS("Cannot construct temporary MonoObject because the class does not define a parameterless constructor: " + get_path());
ERR_EXPLAIN("Constructor not found");
ERR_FAIL_V(NULL);
}
ERR_FAIL_NULL_V_MSG(ctor, NULL,
"Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
MonoException *ctor_exc = NULL;
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]);
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;
}
@ -2427,7 +2419,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->is_static()) {
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;
}
@ -2450,12 +2442,12 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) {
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;
}
if (!property->has_setter()) {
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;
}
}
@ -2474,16 +2466,15 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
String hint_string;
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;
}
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
if (hint_res == -1) {
ERR_EXPLAIN("Error while trying to determine information about the exported member: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
ERR_FAIL_V(false);
}
ERR_FAIL_COND_V_MSG(hint_res == -1, false,
"Error while trying to determine information about the exported member: '" +
MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
if (hint_res == 0) {
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);
if (val_obj == NULL) {
ERR_EXPLAIN("Failed to get '" + enum_field_name + "' constant enum value");
ERR_FAIL_V(-1);
}
ERR_FAIL_NULL_V_MSG(val_obj, -1, "Failed to get '" + enum_field_name + "' constant enum value.");
bool r_error;
uint64_t val = GDMonoUtils::unbox_enum_value(val_obj, enum_basetype, r_error);
if (r_error) {
ERR_EXPLAIN("Failed to unbox '" + enum_field_name + "' constant enum value");
ERR_FAIL_V(-1);
}
ERR_FAIL_COND_V_MSG(r_error, -1, "Failed to unbox '" + enum_field_name + "' constant enum value.");
if (val != (unsigned int)i) {
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;
String elem_hint_string;
if (elem_variant_type == Variant::NIL) {
ERR_EXPLAIN("Unknown array element type");
ERR_FAIL_V(-1);
}
ERR_FAIL_COND_V_MSG(elem_variant_type == Variant::NIL, -1, "Unknown array element type.");
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_EXPLAIN("Error while trying to determine information about the array element type");
ERR_FAIL_V(-1);
}
ERR_FAIL_COND_V_MSG(hint_res == -1, -1, "Error while trying to determine information about the array element type.");
// Format: type/hint: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",
ProjectSettings::get_singleton()->globalize_path(get_path()));
} 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 (GDMono::get_singleton()->get_project_assembly() == NULL) {
// The project assembly is not loaded
ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path());
ERR_FAIL_V(NULL);
ERR_FAIL_V_MSG(NULL, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'.");
} else {
// 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(NULL);
ERR_FAIL_V_MSG(NULL, "Cannot instance script because the class '" + name + "' could not be found. Script: '" + get_path() + "'.");
}
}
@ -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.
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
if (ctor == NULL) {
if (p_argcount == 0) {
String path = get_path();
ERR_PRINTS("Cannot create script instance. The class '" + script_class->get_full_name() +
"' does not define a parameterless constructor." + (path.empty() ? String() : ". Path: " + path));
}
ERR_FAIL_COND_V_MSG(p_argcount == 0, NULL,
"Cannot create script instance. The class '" + script_class->get_full_name() +
"' does not define a parameterless constructor." +
(get_path().empty() ? String() : " Path: '" + get_path() + "'."));
ERR_EXPLAIN("Constructor not found");
ERR_FAIL_V(NULL);
ERR_FAIL_V_MSG(NULL, "Constructor not found.");
}
Ref<Reference> ref;
@ -2878,8 +2853,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
p_owner->set_script_instance(NULL);
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
ERR_EXPLAIN("Failed to allocate memory for the object");
ERR_FAIL_V(NULL);
ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
}
// Tie managed to unmanaged
@ -2950,8 +2924,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
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() + "'");
}
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(NULL);
ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + native_name +
"', 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 ferr = read_all_file_utf8(p_path, source);
if (ferr != OK) {
if (ferr == ERR_INVALID_DATA) {
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.");
}
ERR_FAIL_V(ferr);
}
ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ferr == ERR_INVALID_DATA ?
"Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
" Please ensure that scripts are saved in valid UTF-8 unicode." :
"Failed to read file: '" + p_path + "'.");
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@ -3277,8 +3251,7 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
#ifdef DEBUG_ENABLED
// User is responsible for thread attach/detach
ERR_EXPLAIN("Thread is not attached");
CRASH_COND(mono_domain_get() == NULL);
CRASH_COND_MSG(mono_domain_get() == NULL, "Thread is not attached.");
#endif
#endif
@ -3345,8 +3318,7 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
"Compile",
ProjectSettings::get_singleton()->globalize_path(p_path));
} else {
ERR_PRINTS("Failed to create C# project");
ERR_PRINTS("Cannot add " + p_path + " to the C# project");
ERR_PRINTS("C# project could not be created; cannot add file: '" + p_path + "'.");
}
}
#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(".");
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(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("\"/>");
} 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(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("\"/>");
} 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(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("\"/>");
} 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(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("\"/>");
} 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(tag);
@ -812,7 +812,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
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(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);
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;
}
@ -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);
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;
}
@ -1112,7 +1112,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// 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
// 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
// be renamed to avoid the name collision (and we must print a warning about it).
// - 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("\n");
} 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;
}
}
@ -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()) {
const PropertyInterface &iprop = E->get();
Error prop_err = _generate_cs_property(itype, iprop, output);
if (prop_err != OK) {
ERR_EXPLAIN("Failed to generate property '" + iprop.cname.operator String() +
"' for class '" + itype.name + "'");
ERR_FAIL_V(prop_err);
}
ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err,
"Failed to generate property '" + iprop.cname.operator String() +
"' for class '" + itype.name + "'.");
}
}
@ -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()) {
const MethodInterface &imethod = E->get();
Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output);
if (method_err != OK) {
ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
ERR_FAIL_V(method_err);
}
ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
"Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
}
if (itype.is_singleton) {
@ -1626,7 +1622,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (p_imethod.is_deprecated) {
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(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) {
bool dir_exists = DirAccess::exists(p_output_dir);
ERR_EXPLAIN("The output directory does not exist.");
ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
ERR_FAIL_COND_V_MSG(!dir_exists, ERR_FILE_BAD_PATH, "The output directory does not exist.");
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()) {
const MethodInterface &imethod = E->get();
Error method_err = _generate_glue_method(itype, imethod, output);
if (method_err != OK) {
ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
ERR_FAIL_V(method_err);
}
ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
"Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
}
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);
ERR_EXPLAIN("Cannot open file: " + p_path);
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
ERR_FAIL_COND_V_MSG(!file, ERR_FILE_CANT_WRITE, "Cannot open file: '" + p_path + "'.");
file->store_string(p_content.as_string());
file->close();
@ -2091,7 +2083,7 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol
if (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);
@ -2175,13 +2167,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
}
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();
continue;
}
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();
continue;
}
@ -2240,7 +2232,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the property and its enclosing type from sharing the same 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 += "_";
@ -2298,28 +2290,26 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.is_vararg = m && m->is_vararg();
if (!m && !imethod.is_virtual) {
if (virtual_method_list.find(method_info)) {
// A virtual method without the virtual flag. This is a special case.
ERR_FAIL_COND_MSG(!virtual_method_list.find(method_info),
"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)
imethod.requires_object_call = true;
// A virtual method without the virtual flag. This is a special case.
// The method Object.free is registered as a virtual method, but without the virtual flag.
// This is because this method is not supposed to be overridden, but called.
// We assume the return type is void.
imethod.return_type.cname = name_cache.type_void;
// There is no method bind, so let's fallback to Godot's object.Call(string, params)
imethod.requires_object_call = true;
// Actually, more methods like this may be added in the future,
// which could actually will return something different.
// Let's put this to notify us if that ever happens.
if (itype.cname != name_cache.type_Object || imethod.name != "free") {
ERR_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
"We only expected Object.free, but found " +
itype.name + "." + imethod.name);
}
} else {
ERR_EXPLAIN("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
ERR_FAIL();
// The method Object.free is registered as a virtual method, but without the virtual flag.
// This is because this method is not supposed to be overridden, but called.
// 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,
// which could actually will return something different.
// Let's put this to notify us if that ever happens.
if (itype.cname != name_cache.type_Object || imethod.name != "free") {
ERR_PRINTS("Notification: New unexpected virtual non-overridable method found."
" 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) {
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;
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 */
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);
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 + "'.");
/* clang-format on */
ERR_FAIL();
}
@ -2394,7 +2384,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the method and its enclosing type from sharing the same 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 += "_";
@ -2880,8 +2870,7 @@ void BindingsGenerator::_populate_global_constants() {
if (global_constants_count > 0) {
Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope");
ERR_EXPLAIN("Could not find `@GlobalScope` in DocData");
CRASH_COND(!match);
CRASH_COND_MSG(!match, "Could not find '@GlobalScope' in DocData.");
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'.
if (ienum.cname == name_cache.enum_Error) {
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_'
@ -3024,7 +3013,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
glue_dir_path = path_elem->get();
elem = elem->next();
} 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;
@ -3035,7 +3024,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cs_dir_path = path_elem->get();
elem = elem->next();
} else {
ERR_PRINTS(generate_cs_glue_option + ": No output directory specified");
ERR_PRINTS(generate_cs_glue_option + ": No output directory specified.");
}
--options_left;
@ -3046,7 +3035,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cpp_dir_path = path_elem->get();
elem = elem->next();
} else {
ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified");
ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified.");
}
--options_left;
@ -3061,20 +3050,20 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
if (glue_dir_path.length()) {
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)
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 (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 (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

View File

@ -147,7 +147,7 @@ class BindingsGenerator {
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,
* 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.

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);
GDMonoAssembly *tools_project_editor_assembly = NULL;
GDMonoAssembly *tools_project_editor_asm = NULL;
if (!GDMono::get_singleton()->load_assembly("GodotTools.ProjectEditor", &tools_project_editor_assembly)) {
ERR_EXPLAIN("Failed to load assembly: 'GodotTools.ProjectEditor'");
ERR_FAIL_V(false);
}
bool assembly_loaded = GDMono::get_singleton()->load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_asm);
ERR_FAIL_COND_V_MSG(!assembly_loaded, false, "Failed to load assembly: '" TOOLS_PROJECT_EDITOR_ASM_NAME "'.");
return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_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_EXPLAIN("Cannot load assembly (refonly): " + ref_name);
ERR_FAIL_V(ERR_CANT_RESOLVE);
}
ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
r_dependencies[ref_name] = ref_assembly->get_path();
Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
if (err != OK) {
ERR_EXPLAIN("Cannot load one of the dependencies for the assembly: " + ref_name);
ERR_FAIL_V(err);
}
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
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,
p_project_dll_src_path, &scripts_assembly, /* refonly: */ true);
ERR_EXPLAIN("Cannot load assembly (refonly): " + p_project_dll_name);
ERR_FAIL_COND_V(!load_success, ERR_CANT_RESOLVE);
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + p_project_dll_name + "'.");
Vector<String> search_dirs;
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;
return TK_ERROR;
} else if (code[idx] == begin_str) {
if (verbatim && code[idx + 1] == '"') { // `""` is verbatim string's `\"`
idx += 2; // skip next `"` as well
if (verbatim && code[idx + 1] == '"') { // '""' is verbatim string's '\"'
idx += 2; // skip next '"' as well
continue;
}
@ -590,7 +590,7 @@ Error ScriptClassParser::parse(const String &p_code) {
name = String(value);
} else if (tk == TK_CURLY_BRACKET_OPEN) {
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;
return ERR_PARSE_ERROR;
}
@ -657,12 +657,12 @@ Error ScriptClassParser::parse_file(const String &p_filepath) {
String source;
Error ferr = read_all_file_utf8(p_filepath, source);
if (ferr != OK) {
if (ferr == ERR_INVALID_DATA) {
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.");
}
ERR_FAIL_V(ferr);
}
ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ferr == ERR_INVALID_DATA ?
"File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded."
" Please ensure that scripts are saved in valid UTF-8 unicode." :
"Failed to read file: '" + p_filepath + "'.");
return parse(source);
}

View File

@ -167,7 +167,7 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
int line;
Error err = VariantParser::parse(&ss, ret, errs, line);
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);
ret = err_str;
}
@ -193,8 +193,7 @@ MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_object
PoolByteArray barr;
int len;
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(err != OK, NULL);
ERR_FAIL_COND_V_MSG(err != OK, NULL, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
barr.resize(len);
{

View File

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

View File

@ -265,7 +265,7 @@ void GDMono::initialize() {
#ifdef WINDOWS_ENABLED
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
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
}
@ -318,9 +318,7 @@ void GDMono::initialize() {
#endif
root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319");
ERR_EXPLAIN("Mono: Failed to initialize runtime");
ERR_FAIL_NULL(root_domain);
ERR_FAIL_NULL_MSG(root_domain, "Mono: Failed to initialize runtime.");
GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread());
@ -331,11 +329,11 @@ void GDMono::initialize() {
print_verbose("Mono: Runtime initialized");
// mscorlib assembly MUST be present at initialization
ERR_EXPLAIN("Mono: Failed to load mscorlib assembly");
ERR_FAIL_COND(!_load_corlib_assembly());
bool corlib_loaded = _load_corlib_assembly();
ERR_FAIL_COND_MSG(!corlib_loaded, "Mono: Failed to load mscorlib assembly.");
ERR_EXPLAIN("Mono: Failed to load scripts domain");
ERR_FAIL_COND(_load_scripts_domain() != OK);
Error domain_load_err = _load_scripts_domain();
ERR_FAIL_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
#ifdef DEBUG_ENABLED
bool debugger_attached = _wait_for_debugger_msecs(500);
@ -351,8 +349,7 @@ void GDMono::initialize() {
void GDMono::initialize_load_assemblies() {
#ifndef MONO_GLUE_ENABLED
ERR_EXPLAIN("Mono: This binary was built with `mono_glue=no`; cannot load assemblies");
CRASH_NOW();
CRASH_NOW_MSG("Mono: This binary was built with 'mono_glue=no'; cannot load assemblies.");
#endif
// Load assemblies. The API and tools assemblies are required,
@ -361,10 +358,8 @@ void GDMono::initialize_load_assemblies() {
_load_api_assemblies();
#if defined(TOOLS_ENABLED)
if (!_load_tools_assemblies()) {
ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies");
CRASH_NOW();
}
bool tool_assemblies_loaded = _load_tools_assemblies();
CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
#endif
// 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
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
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 // MONO_GLUE_ENABLED
@ -579,7 +574,7 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
memdelete(da);
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;
}
}
@ -593,16 +588,16 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
String xml_file = assembly_name + ".xml";
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";
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);
if (err != OK) {
ERR_PRINTS("Failed to copy " + assembly_file);
ERR_PRINTS("Failed to copy '" + assembly_file + "'.");
return false;
}
@ -617,11 +612,11 @@ String GDMono::update_api_assemblies_from_prebuilt() {
#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \
(m_out_of_sync ? \
String("The assembly is invalidated") : \
String("The assembly was not found")) + \
String("The assembly is invalidated ") : \
String("The assembly was not found ")) + \
(m_prebuilt_exists ? \
String(" and the prebuilt assemblies are missing") : \
String(" and we failed to copy the prebuilt assemblies")))
String("and the prebuilt assemblies are missing.") : \
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;
@ -755,29 +750,19 @@ void GDMono::_load_api_assemblies() {
// update them from the prebuilt assemblies directory before trying to load them.
// Shouldn't happen. The project manager loads the prebuilt API assemblies
if (Main::is_project_manager()) {
ERR_EXPLAIN("Failed to load one of the prebuilt API assemblies");
CRASH_NOW();
}
CRASH_COND_MSG(Main::is_project_manager(), "Failed to load one of the prebuilt API assemblies.");
// 1. Unload the scripts domain
if (_unload_scripts_domain() != OK) {
ERR_EXPLAIN("Mono: Failed to unload scripts domain");
CRASH_NOW();
}
Error domain_unload_err = _unload_scripts_domain();
CRASH_COND_MSG(domain_unload_err != OK, "Mono: Failed to unload scripts domain.");
// 2. Update the API assemblies
String update_error = update_api_assemblies_from_prebuilt();
if (!update_error.empty()) {
ERR_EXPLAIN(update_error);
CRASH_NOW();
}
CRASH_COND_MSG(!update_error.empty(), update_error);
// 3. Load the scripts domain again
if (_load_scripts_domain() != OK) {
ERR_EXPLAIN("Mono: Failed to load scripts domain");
CRASH_NOW();
}
Error domain_load_err = _load_scripts_domain();
CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
// 4. Try loading the updated assemblies
if (!_try_load_api_assemblies()) {
@ -785,24 +770,22 @@ void GDMono::_load_api_assemblies() {
if (_are_api_assemblies_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) {
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) {
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();
} else {
ERR_EXPLAIN("Failed to load one of the API assemblies");
CRASH_NOW();
CRASH_NOW_MSG("Failed to load one of the API assemblies.");
}
}
#else
ERR_EXPLAIN("Failed to load one of the API assemblies");
CRASH_NOW();
CRASH_NOW_MSG("Failed to load one of the API assemblies.");
#endif
}
}
@ -813,8 +796,8 @@ bool GDMono::_load_tools_assemblies() {
if (tools_assembly && tools_project_editor_assembly)
return true;
bool success = load_assembly(TOOLS_ASSEMBLY_NAME, &tools_assembly) &&
load_assembly(TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME, &tools_project_editor_assembly);
bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
return success;
}
@ -851,7 +834,7 @@ void GDMono::_install_trace_listener() {
(DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener");
install_func((MonoObject **)&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);
}
#endif
@ -865,8 +848,7 @@ Error GDMono::_load_scripts_domain() {
scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain");
ERR_EXPLAIN("Mono: Could not create scripts app domain");
ERR_FAIL_NULL_V(scripts_domain, ERR_CANT_CREATE);
ERR_FAIL_NULL_V_MSG(scripts_domain, ERR_CANT_CREATE, "Mono: Could not create scripts app domain.");
mono_domain_set(scripts_domain, true);
@ -885,7 +867,7 @@ Error GDMono::_unload_scripts_domain() {
finalizing_scripts_domain = true;
if (!mono_domain_finalize(scripts_domain, 2000)) {
ERR_PRINT("Mono: Domain finalization timeout");
ERR_PRINT("Mono: Domain finalization timeout.");
}
finalizing_scripts_domain = false;
@ -911,7 +893,7 @@ Error GDMono::_unload_scripts_domain() {
mono_domain_try_unload(domain, (MonoObject **)&exc);
if (exc) {
ERR_PRINT("Exception thrown when unloading scripts domain");
ERR_PRINT("Exception thrown when unloading scripts domain.");
GDMonoUtils::debug_unhandled_exception(exc);
return FAILED;
}
@ -925,20 +907,14 @@ Error GDMono::reload_scripts_domain() {
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
if (scripts_domain) {
Error err = _unload_scripts_domain();
if (err != OK) {
ERR_PRINT("Mono: Failed to unload scripts domain");
return err;
}
Error domain_unload_err = _unload_scripts_domain();
ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain.");
}
CSharpLanguage::get_singleton()->_on_scripts_domain_unloaded();
Error err = _load_scripts_domain();
if (err != OK) {
ERR_PRINT("Mono: Failed to load scripts domain");
return err;
}
Error domain_load_err = _load_scripts_domain();
ERR_FAIL_COND_V_MSG(domain_load_err != OK, domain_load_err, "Mono: Failed to load scripts domain.");
// Load assemblies. The API and tools assemblies are required,
// the application is aborted if these assemblies cannot be loaded.
@ -946,10 +922,8 @@ Error GDMono::reload_scripts_domain() {
_load_api_assemblies();
#if defined(TOOLS_ENABLED)
if (!_load_tools_assemblies()) {
ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies");
CRASH_NOW();
}
bool tools_assemblies_loaded = _load_tools_assemblies();
CRASH_COND_MSG(!tools_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
#endif
// 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);
print_verbose("Mono: Unloading domain `" + domain_name + "`...");
print_verbose("Mono: Unloading domain '" + domain_name + "'...");
if (mono_domain_get() == p_domain)
mono_domain_set(root_domain, true);
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());
@ -988,7 +962,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
mono_domain_try_unload(p_domain, (MonoObject **)&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);
return FAILED;
}
@ -1105,7 +1079,7 @@ GDMono::~GDMono() {
if (scripts_domain) {
Error err = _unload_scripts_domain();
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.
// 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).
// 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).
// 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
// 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`
// 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'
// 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.
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
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 `" +
method->get_full_name_no_class() + "`. In class `" + namespace_name + "." + class_name + "`.");
WARN_PRINTS("Method '" + fullname + "' is hidden by Godot API method. Should be '" +
method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'.");
#endif
continue;
}
@ -184,8 +184,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
if (m && m->get_name() != name) {
// found
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() +
"`. In class `" + namespace_name + "." + class_name + "`.");
WARN_PRINTS("Method '" + fullname + "' should be '" + m->get_full_name_no_class() +
"'. In class '" + namespace_name + "." + class_name + "'.");
break;
}

View File

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

View File

@ -48,7 +48,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *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
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) {
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
f->flush();
f->close();
@ -90,8 +90,7 @@ bool GDMonoLog::_try_create_logs_dir(const String &p_logs_dir) {
DirAccessRef diraccess = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
ERR_FAIL_COND_V(!diraccess, false);
Error logs_mkdir_err = diraccess->make_dir_recursive(p_logs_dir);
ERR_EXPLAIN("Failed to create mono logs directory");
ERR_FAIL_COND_V(logs_mkdir_err != OK, false);
ERR_FAIL_COND_V_MSG(logs_mkdir_err != OK, false, "Failed to create mono logs directory.");
}
return true;
@ -131,7 +130,7 @@ void GDMonoLog::initialize() {
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) {
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();
}
@ -160,7 +159,7 @@ void GDMonoLog::initialize() {
log_file = FileAccess::open(log_file_path, FileAccess::WRITE);
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);
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);
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);
}
default: {
ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
ERR_FAIL_V(NULL);
ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
}
}
}
@ -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))
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(NULL);
ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
case MONO_TYPE_CLASS: {
@ -695,9 +693,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
} break;
}
ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" +
p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
ERR_FAIL_V(NULL);
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) + ".");
}
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))
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(Variant());
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
} break;
case MONO_TYPE_CLASS: {
@ -908,9 +904,8 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
} break;
}
ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding));
ERR_FAIL_V(Variant());
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) + ".");
}
MonoArray *Array_to_mono_array(const Array &p_array) {

View File

@ -52,14 +52,11 @@ namespace GDMonoUtils {
MonoCache mono_cache;
#define CACHE_AND_CHECK(m_var, m_val) \
{ \
CRASH_COND(m_var != NULL); \
m_var = m_val; \
if (!m_var) { \
ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
ERR_FAIL(); \
} \
#define CACHE_AND_CHECK(m_var, m_val) \
{ \
CRASH_COND(m_var != NULL); \
m_var = m_val; \
ERR_FAIL_COND_MSG(!m_var, "Mono Cache: Member " #m_var " is null."); \
}
#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) {
if (!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_V(NULL);
}
bool parent_is_object_class = ClassDB::is_parent_class(p_object->get_class_name(), p_native);
ERR_FAIL_COND_V_MSG(!parent_is_object_class, 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());
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) {
#ifdef DEBUG_ENABLED
if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) {
ERR_EXPLAIN("Resumed after await, but class instance is gone");
ERR_FAIL_V(Variant());
}
ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(),
"Resumed after await, but class instance is gone.");
#endif
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++) {
int read_pos = i + j;
if (read_pos >= len) {
ERR_PRINT("read_pos >= len");
return -1;
};
ERR_FAIL_COND_V(read_pos >= len, -1);
switch (j) {
case 0: