summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Etcheverry <ignalfonsore@gmail.com>2021-01-09 00:14:25 +0100
committerIgnacio Etcheverry <ignalfonsore@gmail.com>2021-01-09 00:18:03 +0100
commitfafdc0b0c10b45b972947650d67c3f9a1d786be0 (patch)
treea0e49491e1aa6f8875e6621e3921b49704bf8de1
parent98ccaa1bad97bdb83b2afd6a4df6f7a392745592 (diff)
Add ClassDB tests to look for core API deps on editor API
The ClassDB tests will detect when the core API has dependencies on the editor API, which is not allowed. This should prevent or warn early about issues like #44856
-rw-r--r--modules/mono/editor/bindings_generator.cpp26
-rw-r--r--tests/test_class_db.h43
2 files changed, 63 insertions, 6 deletions
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 59ce617990..0f2c6b3504 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1479,6 +1479,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG,
"Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(prop_itype->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Property '" + p_itype.name + "." + String(p_iprop.cname) + "' has type '" + prop_itype->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) {
String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
@@ -1575,6 +1581,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG,
"Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(return_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Method '" + p_itype.name + "." + p_imethod.name + "' has return type '" + return_type->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
String method_bind_field = "__method_bind_" + itos(p_method_bind_count);
String arguments_sig;
@@ -1593,6 +1605,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
"Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (iarg.default_argument.size()) {
CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type),
"Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
@@ -1806,7 +1824,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
- "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'.");
+ "Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'.");
+
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
// Add the current arguments to the signature
diff --git a/tests/test_class_db.h b/tests/test_class_db.h
index b1440b83ef..9ef4569c14 100644
--- a/tests/test_class_db.h
+++ b/tests/test_class_db.h
@@ -340,7 +340,14 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
if (prop_class) {
TEST_COND(prop_class->is_singleton,
"Property type is a singleton: '", p_class.name, ".", String(p_prop.name), "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(prop_class->api_type == ClassDB::API_EDITOR,
+ "Property '", p_class.name, ".", p_prop.name, "' has type '", prop_class->name,
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(prop_type_ref),
"Property type '", prop_type_ref.name, "' not found: '", p_class.name, ".", String(p_prop.name), "'.");
}
@@ -370,10 +377,22 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
}
void validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) {
- const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
- if (return_class) {
- TEST_COND(return_class->is_singleton,
- "Method return type is a singleton: '", p_class.name, ".", p_method.name, "'.");
+ if (p_method.return_type.name != StringName()) {
+ const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
+ if (return_class) {
+ TEST_COND(return_class->is_singleton,
+ "Method return type is a singleton: '", p_class.name, ".", p_method.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(return_class->api_type == ClassDB::API_EDITOR,
+ "Method '", p_class.name, ".", p_method.name, "' has return type '", return_class->name,
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+ } else {
+ // Look for types that don't inherit Object
+ TEST_FAIL_COND(!p_context.has_type(p_method.return_type),
+ "Method return type '", p_method.return_type.name, "' not found: '", p_class.name, ".", p_method.name, "'.");
+ }
}
for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) {
@@ -383,7 +402,14 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons
if (arg_class) {
TEST_COND(arg_class->is_singleton,
"Argument type is a singleton: '", arg.name, "' of method '", p_class.name, ".", p_method.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
+ "Argument '", arg.name, "' of method '", p_class.name, ".", p_method.name, "' has type '",
+ arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(arg.type),
"Argument type '", arg.type.name, "' not found: '", arg.name, "' of method", p_class.name, ".", p_method.name, "'.");
}
@@ -407,8 +433,15 @@ void validate_signal(const Context &p_context, const ExposedClass &p_class, cons
const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
if (arg_class) {
TEST_COND(arg_class->is_singleton,
- "Argument class is a singleton: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'.");
+ "Argument class is a singleton: '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
+ "Argument '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "' has type '",
+ arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(arg.type),
"Argument type '", arg.type.name, "' not found: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'.");
}