diff options
author | Pedro J. Estébanez <pedrojrulez@gmail.com> | 2021-08-14 05:44:22 +0200 |
---|---|---|
committer | Pedro J. Estébanez <pedrojrulez@gmail.com> | 2021-09-11 11:35:25 +0200 |
commit | d72f12a561179719d8a1228221ba13c7c029be17 (patch) | |
tree | 47f0486083e82e10f6efd0772a6d850961d2c407 /modules/gdscript | |
parent | 0a001afec53aa4caed7820b34db4d7d15686e24d (diff) |
Implement iterator variable typing in GDScript
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 24 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 33 | ||||
-rw-r--r-- | 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 6b7403d854..f090e7db25 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 d21caf4389..1cbb4861bc 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("<unresolved type", "Kind set outside the enum range."); } +static Variant::Type _variant_type_to_typed_array_element_type(Variant::Type p_type) { + switch (p_type) { + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + return Variant::INT; + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + return Variant::FLOAT; + case Variant::PACKED_STRING_ARRAY: + return Variant::STRING; + case Variant::PACKED_VECTOR2_ARRAY: + return Variant::VECTOR2; + case Variant::PACKED_VECTOR3_ARRAY: + return Variant::VECTOR3; + case Variant::PACKED_COLOR_ARRAY: + return Variant::COLOR; + default: + return Variant::NIL; + } +} + +bool GDScriptParser::DataType::is_typed_container_type() const { + return kind == GDScriptParser::DataType::BUILTIN && _variant_type_to_typed_array_element_type(builtin_type) != Variant::NIL; +} + +GDScriptParser::DataType GDScriptParser::DataType::get_typed_container_type() const { + GDScriptParser::DataType type; + type.kind = GDScriptParser::DataType::BUILTIN; + type.builtin_type = _variant_type_to_typed_array_element_type(builtin_type); + return type; +} + /*---------- PRETTY PRINT FOR DEBUG ----------*/ #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 0bce8d7ddd..ed5300eb59 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -161,6 +161,10 @@ public: container_element_type = nullptr; } + bool is_typed_container_type() const; + + GDScriptParser::DataType get_typed_container_type() const; + bool operator==(const DataType &p_other) const { if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) { return true; // Can be consireded equal for parsing purposes. |