GDScript: Add static typing for for loop variable
This commit is contained in:
@ -2001,13 +2001,16 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
|
||||
}
|
||||
|
||||
GDScriptParser::DataType variable_type;
|
||||
String list_visible_type = "<unresolved type>";
|
||||
if (list_resolved) {
|
||||
variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
|
||||
variable_type.kind = GDScriptParser::DataType::BUILTIN;
|
||||
variable_type.builtin_type = Variant::INT;
|
||||
list_visible_type = "Array[int]"; // NOTE: `range()` has `Array` return type.
|
||||
} else if (p_for->list) {
|
||||
resolve_node(p_for->list, false);
|
||||
GDScriptParser::DataType list_type = p_for->list->get_datatype();
|
||||
list_visible_type = list_type.to_string();
|
||||
if (!list_type.is_hard_type()) {
|
||||
mark_node_unsafe(p_for->list);
|
||||
}
|
||||
@ -2051,8 +2054,37 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
|
||||
push_error(vformat(R"(Unable to iterate on value of type "%s".)", list_type.to_string()), p_for->list);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_for->variable) {
|
||||
p_for->variable->set_datatype(variable_type);
|
||||
if (p_for->datatype_specifier) {
|
||||
GDScriptParser::DataType specified_type = type_from_metatype(resolve_datatype(p_for->datatype_specifier));
|
||||
if (!specified_type.is_variant()) {
|
||||
if (variable_type.is_variant() || !variable_type.is_hard_type()) {
|
||||
mark_node_unsafe(p_for->variable);
|
||||
p_for->use_conversion_assign = true;
|
||||
} else if (!is_type_compatible(specified_type, variable_type, true, p_for->variable)) {
|
||||
if (is_type_compatible(variable_type, specified_type)) {
|
||||
mark_node_unsafe(p_for->variable);
|
||||
p_for->use_conversion_assign = true;
|
||||
} else {
|
||||
push_error(vformat(R"(Unable to iterate on value of type "%s" with variable of type "%s".)", list_visible_type, specified_type.to_string()), p_for->datatype_specifier);
|
||||
}
|
||||
} else if (!is_type_compatible(specified_type, variable_type)) {
|
||||
p_for->use_conversion_assign = true;
|
||||
#ifdef DEBUG_ENABLED
|
||||
} else {
|
||||
parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
} else {
|
||||
parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
|
||||
#endif
|
||||
}
|
||||
p_for->variable->set_datatype(specified_type);
|
||||
} else {
|
||||
p_for->variable->set_datatype(variable_type);
|
||||
}
|
||||
}
|
||||
|
||||
resolve_suite(p_for->loop);
|
||||
|
||||
Reference in New Issue
Block a user