Merge pull request #91617 from vnen/gdscript-only-check-exposed-classes

GDScript: Make check for exposed classes more consistent
This commit is contained in:
Thaddeus Crews 2025-11-25 09:52:18 -06:00
commit 231adb0f0c
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
5 changed files with 18 additions and 17 deletions

View file

@ -6415,7 +6415,7 @@ void GDScriptAnalyzer::resolve_pending_lambda_bodies() {
static_context = previous_static_context;
}
bool GDScriptAnalyzer::class_exists(const StringName &p_class) const {
bool GDScriptAnalyzer::class_exists(const StringName &p_class) {
return ClassDB::class_exists(p_class) && ClassDB::is_class_exposed(p_class);
}

View file

@ -143,7 +143,6 @@ class GDScriptAnalyzer {
void downgrade_node_type_source(GDScriptParser::Node *p_node);
void mark_lambda_use_self();
void resolve_pending_lambda_bodies();
bool class_exists(const StringName &p_class) const;
void reduce_identifier_from_base_set_class(GDScriptParser::IdentifierNode *p_identifier, GDScriptParser::DataType p_identifier_datatype);
Ref<GDScriptParserRef> ensure_cached_external_parser_for_class(const GDScriptParser::ClassNode *p_class, const GDScriptParser::ClassNode *p_from_class, const char *p_context, const GDScriptParser::Node *p_source);
Ref<GDScriptParserRef> find_cached_external_parser_for_class(const GDScriptParser::ClassNode *p_class, const Ref<GDScriptParserRef> &p_dependant_parser);
@ -164,6 +163,7 @@ public:
static bool check_type_compatibility(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion = false, const GDScriptParser::Node *p_source_node = nullptr);
static GDScriptParser::DataType type_from_metatype(const GDScriptParser::DataType &p_meta_type);
static bool class_exists(const StringName &p_class);
GDScriptAnalyzer(GDScriptParser *p_parser);
};

View file

@ -31,6 +31,7 @@
#include "gdscript_compiler.h"
#include "gdscript.h"
#include "gdscript_analyzer.h"
#include "gdscript_byte_codegen.h"
#include "gdscript_cache.h"
#include "gdscript_utility_functions.h"
@ -699,7 +700,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
} else {
class_name = base.type.native_type == StringName() ? base.type.script_type->get_instance_base_type() : base.type.native_type;
}
if (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) {
if (GDScriptAnalyzer::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) {
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
if (_can_use_validate_call(method, arguments)) {
// Exact arguments, use validated call.
@ -2756,7 +2757,7 @@ Error GDScriptCompiler::_prepare_compilation(GDScript *p_script, const GDScriptP
p_script->_is_abstract = p_class->is_abstract;
if (p_script->local_name != StringName()) {
if (ClassDB::class_exists(p_script->local_name) && ClassDB::is_class_exposed(p_script->local_name)) {
if (GDScriptAnalyzer::class_exists(p_script->local_name)) {
_set_error(vformat(R"(The class "%s" shadows a native class)", p_script->local_name), p_class);
return ERR_ALREADY_EXISTS;
}

View file

@ -392,7 +392,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
get_public_constants(&cinfo);
for (const KeyValue<StringName, int> &E : name_idx) {
if (ClassDB::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) {
if (GDScriptAnalyzer::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) {
continue;
}
@ -710,7 +710,7 @@ static String _trim_parent_class(const String &p_class, const String &p_base_cla
Vector<String> names = p_class.split(".", false, 1);
if (names.size() == 2) {
const String &first = names[0];
if (ClassDB::class_exists(p_base_class) && ClassDB::class_exists(first) && ClassDB::is_parent_class(p_base_class, first)) {
if (GDScriptAnalyzer::class_exists(p_base_class) && GDScriptAnalyzer::class_exists(first) && ClassDB::is_parent_class(p_base_class, first)) {
const String &rest = names[1];
return rest;
}
@ -1347,7 +1347,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
} break;
case GDScriptParser::DataType::NATIVE: {
StringName type = base_type.native_type;
if (!ClassDB::class_exists(type)) {
if (!GDScriptAnalyzer::class_exists(type)) {
return;
}
@ -1627,7 +1627,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context
// Native classes and global constants.
for (const KeyValue<StringName, int> &E : GDScriptLanguage::get_singleton()->get_global_map()) {
ScriptLanguage::CodeCompletionOption option;
if (ClassDB::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) {
if (GDScriptAnalyzer::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) {
option = ScriptLanguage::CodeCompletionOption(E.key.operator String(), ScriptLanguage::CODE_COMPLETION_KIND_CLASS);
} else {
option = ScriptLanguage::CodeCompletionOption(E.key.operator String(), ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT);
@ -2510,7 +2510,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
}
// Check ClassDB.
if (ClassDB::class_exists(p_identifier->name) && ClassDB::is_class_exposed(p_identifier->name)) {
if (GDScriptAnalyzer::class_exists(p_identifier->name)) {
r_type.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
r_type.type.kind = GDScriptParser::DataType::NATIVE;
r_type.type.builtin_type = Variant::OBJECT;
@ -2658,7 +2658,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
} break;
case GDScriptParser::DataType::NATIVE: {
StringName class_name = base_type.native_type;
if (!ClassDB::class_exists(class_name)) {
if (!GDScriptAnalyzer::class_exists(class_name)) {
return false;
}
@ -2849,7 +2849,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
}
} break;
case GDScriptParser::DataType::NATIVE: {
if (!ClassDB::class_exists(base_type.native_type)) {
if (!GDScriptAnalyzer::class_exists(base_type.native_type)) {
return false;
}
MethodBind *mb = ClassDB::get_method(base_type.native_type, p_method);
@ -2925,7 +2925,7 @@ static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_co
String class_name = p_enum_hint.get_slicec('.', 0);
String enum_name = p_enum_hint.get_slicec('.', 1);
if (!ClassDB::class_exists(class_name)) {
if (!GDScriptAnalyzer::class_exists(class_name)) {
return;
}
@ -2998,7 +2998,7 @@ static void _list_call_arguments(GDScriptParser::CompletionContext &p_context, c
} break;
case GDScriptParser::DataType::NATIVE: {
StringName class_name = base_type.native_type;
if (!ClassDB::class_exists(class_name)) {
if (!GDScriptAnalyzer::class_exists(class_name)) {
base_type.kind = GDScriptParser::DataType::UNRESOLVED;
break;
}
@ -3720,7 +3720,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
}
StringName class_name = native_type.native_type;
if (!ClassDB::class_exists(class_name)) {
if (!GDScriptAnalyzer::class_exists(class_name)) {
break;
}
@ -4101,7 +4101,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
case GDScriptParser::DataType::NATIVE: {
const StringName &class_name = base_type.native_type;
ERR_FAIL_COND_V(!ClassDB::class_exists(class_name), ERR_BUG);
ERR_FAIL_COND_V(!GDScriptAnalyzer::class_exists(class_name), ERR_BUG);
if (ClassDB::has_method(class_name, p_symbol, true)) {
r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_METHOD;
@ -4295,7 +4295,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
::Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
// Before parsing, try the usual stuff.
if (ClassDB::class_exists(p_symbol)) {
if (GDScriptAnalyzer::class_exists(p_symbol)) {
r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS;
r_result.class_name = p_symbol;
return OK;

View file

@ -4677,7 +4677,7 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
if (ScriptServer::is_global_class(arg_string)) {
native_class = ScriptServer::get_global_class_native_base(arg_string);
}
if (!ClassDB::class_exists(native_class)) {
if (!ClassDB::class_exists(native_class) || !ClassDB::is_class_exposed(native_class)) {
push_error(vformat(R"(Invalid argument %d of annotation "@export_node_path": The class "%s" was not found in the global scope.)", i + 1, arg_string), p_annotation->arguments[i]);
return false;
} else if (!ClassDB::is_parent_class(native_class, SNAME("Node"))) {