Fix gdscript analyzer error when instantiating EditorPlugins.

Editor code is not instantiable outside of the editor
(1d14c054a1/core/object/class_db.cpp (L369)).
This is fine for editor plugins and the like, but the GDScript analyzer
balks at it, causing F5 runs to fail: #73525.

Instead, we really just want to know if the type is abstract - so add
a new ClassDB method to check that and nothing else.

Update core/object/class_db.cpp

Apply code review comments

Co-Authored-By: Bryce <1522777+baptr@users.noreply.github.com>
This commit is contained in:
baptr 2023-02-26 19:42:55 -08:00 committed by Nullpointer
parent e6448ca0aa
commit 810fcc7431
3 changed files with 17 additions and 1 deletions

View file

@ -671,6 +671,21 @@ bool ClassDB::can_instantiate(const StringName &p_class) {
return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance));
}
bool ClassDB::is_abstract(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
if (!ti) {
if (!ScriptServer::is_global_class(p_class)) {
ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'.");
}
String path = ScriptServer::get_global_class_path(p_class);
Ref<Script> scr = ResourceLoader::load(path);
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
}
return ti->creation_func == nullptr && (!ti->gdextension || ti->gdextension->create_instance == nullptr);
}
bool ClassDB::is_virtual(const StringName &p_class) {
OBJTYPE_RLOCK;

View file

@ -287,6 +287,7 @@ public:
static bool class_exists(const StringName &p_class);
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
static bool can_instantiate(const StringName &p_class);
static bool is_abstract(const StringName &p_class);
static bool is_virtual(const StringName &p_class);
static Object *instantiate(const StringName &p_class);
static Object *instantiate_no_placeholders(const StringName &p_class);

View file

@ -5180,7 +5180,7 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
if (!class_exists(base_native)) {
push_error(vformat("Native class %s used in script doesn't exist or isn't exposed.", base_native), p_source);
return false;
} else if (p_is_constructor && !ClassDB::can_instantiate(base_native)) {
} else if (p_is_constructor && ClassDB::is_abstract(base_native)) {
if (p_base_type.kind == GDScriptParser::DataType::CLASS) {
push_error(vformat(R"(Class "%s" cannot be constructed as it is based on abstract native class "%s".)", p_base_type.class_type->fqcn.get_file(), base_native), p_source);
} else if (p_base_type.kind == GDScriptParser::DataType::SCRIPT) {