Browse Source

Merge pull request #93942 from MikeSchulze/73525

Fix GDScript analyzer error when instantiating EditorPlugins.
Rémi Verschelde 1 year ago
parent
commit
fe5d567917
3 changed files with 17 additions and 1 deletions
  1. 15 0
      core/object/class_db.cpp
  2. 1 0
      core/object/class_db.h
  3. 1 1
      modules/gdscript/gdscript_analyzer.cpp

+ 15 - 0
core/object/class_db.cpp

@@ -683,6 +683,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;
 

+ 1 - 0
core/object/class_db.h

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

+ 1 - 1
modules/gdscript/gdscript_analyzer.cpp

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