mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
GDScript: Make check for exposed classes more consistent
Some places were already checking if classes from ClassDB were exposed, while others didn't. This makes the check more consistent to avoid disparities which can lead to crashes.
This commit is contained in:
parent
22a28e07cc
commit
501c5b0900
5 changed files with 18 additions and 17 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"))) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue