From d72f12a561179719d8a1228221ba13c7c029be17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Sat, 14 Aug 2021 05:44:22 +0200 Subject: [PATCH 1/3] Implement iterator variable typing in GDScript --- modules/gdscript/gdscript_analyzer.cpp | 24 +++++++++++++++---- modules/gdscript/gdscript_parser.cpp | 33 ++++++++++++++++++++++++++ modules/gdscript/gdscript_parser.h | 4 ++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 6b7403d85477..f090e7db2500 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1089,12 +1089,28 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) { } } - if (!list_resolved) { + GDScriptParser::DataType variable_type; + if (list_resolved) { + variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; + variable_type.kind = GDScriptParser::DataType::BUILTIN; + variable_type.builtin_type = Variant::INT; // Can this ever be a float or something else? + p_for->variable->set_datatype(variable_type); + } else { resolve_node(p_for->list); + if (p_for->list->datatype.has_container_element_type()) { + variable_type = p_for->list->datatype.get_container_element_type(); + variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; + } else if (p_for->list->datatype.is_typed_container_type()) { + variable_type = p_for->list->datatype.get_typed_container_type(); + variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; + } else { + // Last resort + // TODO: Must other cases be handled? Must we mark as unsafe? + variable_type.type_source = GDScriptParser::DataType::UNDETECTED; + variable_type.kind = GDScriptParser::DataType::VARIANT; + } } - - // TODO: If list is a typed array, the variable should be an element. - // Also applicable for constant range() (so variable is int or float). + p_for->variable->set_datatype(variable_type); resolve_suite(p_for->loop); p_for->set_datatype(p_for->loop->get_datatype()); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index d21caf4389bf..1cbb4861bcf6 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3540,6 +3540,39 @@ String GDScriptParser::DataType::to_string() const { ERR_FAIL_V_MSG(" Date: Sat, 14 Aug 2021 06:03:10 +0200 Subject: [PATCH 2/3] Fix parameter type resolution in GDScript --- modules/gdscript/gdscript_analyzer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index f090e7db2500..ad0988932ff0 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1398,8 +1398,7 @@ void GDScriptAnalyzer::resolve_parameter(GDScriptParser::ParameterNode *p_parame } if (p_parameter->datatype_specifier != nullptr) { - resolve_datatype(p_parameter->datatype_specifier); - result = p_parameter->datatype_specifier->get_datatype(); + result = resolve_datatype(p_parameter->datatype_specifier); result.is_meta_type = false; if (p_parameter->default_value != nullptr) { From 10c9c2ccd44b7d96e570f668deb2a8531a92bdc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Sat, 14 Aug 2021 17:56:09 +0200 Subject: [PATCH 3/3] Avoid crash after a parsing error in GDScript --- modules/gdscript/gdscript_cache.cpp | 12 +++--------- modules/gdscript/gdscript_cache.h | 1 + 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 07f50d14dcb9..8121053245d1 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -51,7 +51,9 @@ GDScriptParser *GDScriptParserRef::get_parser() const { Error GDScriptParserRef::raise_status(Status p_new_status) { ERR_FAIL_COND_V(parser == nullptr, ERR_INVALID_DATA); - Error result = OK; + if (result != OK) { + return result; + } while (p_new_status > status) { switch (status) { @@ -86,14 +88,6 @@ Error GDScriptParserRef::raise_status(Status p_new_status) { } } if (result != OK) { - if (parser != nullptr) { - memdelete(parser); - parser = nullptr; - } - if (analyzer != nullptr) { - memdelete(analyzer); - analyzer = nullptr; - } return result; } } diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index 943638d29fb9..9fb661d031f9 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -54,6 +54,7 @@ private: GDScriptParser *parser = nullptr; GDScriptAnalyzer *analyzer = nullptr; Status status = EMPTY; + Error result = OK; String path; friend class GDScriptCache;