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
This commit is contained in:
Ignacio Etcheverry 2021-01-09 00:14:25 +01:00
parent 98ccaa1bad
commit fafdc0b0c1
2 changed files with 63 additions and 6 deletions

View file

@ -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

View file

@ -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, "'.");
}