diff options
author | rune-scape <spartacrafter@gmail.com> | 2024-10-21 15:24:53 -0700 |
---|---|---|
committer | rune-scape <spartacrafter@gmail.com> | 2024-10-22 02:13:16 -0700 |
commit | eb8b9898c9839aed04a248072baae666f3943a40 (patch) | |
tree | d16630e8573d282f154f6a8075623a1dae0aea32 | |
parent | 44fa552343722bb048e2d7c6d3661174a95a8a3c (diff) | |
download | redot-engine-eb8b9898c9839aed04a248072baae666f3943a40.tar.gz |
GDScript: Fix cached parser error when using typed Dictionaries
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 12 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 4 |
2 files changed, 12 insertions, 4 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 4a3a3a4b61..5313f25816 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -940,8 +940,8 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class, Finally finally([&]() { ensure_cached_external_parser_for_class(member.get_datatype().class_type, p_class, "Trying to resolve datatype of class member", p_source); GDScriptParser::DataType member_type = member.get_datatype(); - if (member_type.has_container_element_type(0)) { - ensure_cached_external_parser_for_class(member_type.get_container_element_type(0).class_type, p_class, "Trying to resolve datatype of class member", p_source); + for (int i = 0; i < member_type.get_container_element_type_count(); ++i) { + ensure_cached_external_parser_for_class(member_type.get_container_element_type(i).class_type, p_class, "Trying to resolve datatype of class member", p_source); } }); @@ -3816,6 +3816,12 @@ GDScriptParser::DataType GDScriptAnalyzer::make_global_class_meta_type(const Str } Ref<GDScriptParserRef> GDScriptAnalyzer::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) { + // Delicate piece of code that intentionally doesn't use the GDScript cache or `get_depended_parser_for`. + // Search dependencies for the parser that owns `p_class` and make a cache entry for it. + // Required for how we store pointers to classes owned by other parser trees and need to call `resolve_class_member` and such on the same parser tree. + // Since https://github.com/godotengine/godot/pull/94871 there can technically be multiple parsers for the same script in the same parser tree. + // Even if unlikely, getting the wrong parser could lead to strange undefined behavior without errors. + if (p_class == nullptr) { return nullptr; } @@ -3832,8 +3838,6 @@ Ref<GDScriptParserRef> GDScriptAnalyzer::ensure_cached_external_parser_for_class p_from_class = parser->head; } - String script_path = p_class->get_datatype().script_path; - Ref<GDScriptParserRef> parser_ref; for (const GDScriptParser::ClassNode *look_class = p_from_class; look_class != nullptr; look_class = look_class->base_type.class_type) { if (parser->has_class(look_class)) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 7f64ae902b..2ec33831a2 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -165,6 +165,10 @@ public: container_element_types.write[p_index] = DataType(p_type); } + _FORCE_INLINE_ int get_container_element_type_count() const { + return container_element_types.size(); + } + _FORCE_INLINE_ DataType get_container_element_type(int p_index) const { ERR_FAIL_INDEX_V(p_index, container_element_types.size(), get_variant_type()); return container_element_types[p_index]; |