diff options
author | George Marques <george@gmarqu.es> | 2020-08-18 15:12:51 -0300 |
---|---|---|
committer | George Marques <george@gmarqu.es> | 2020-08-18 15:12:51 -0300 |
commit | 99d4ea8c792833b5bebc03cf19eea3330c79537d (patch) | |
tree | a934f5dbbf0870e679a456c3ac50db89ed8e771b /modules/gdscript | |
parent | 8bc9b3a2ae7e15828825c81960c9c422aaddcf36 (diff) |
GDScript: Allow supertype objects to be assigned to a subtype variable
It allows `get_node()` to be used with typed variables
This is marked as unsafe to warn the user.
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 881c40a4c6..3a04777bd5 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -498,7 +498,13 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas if (member.variable->initializer != nullptr) { if (!is_type_compatible(datatype, member.variable->initializer->get_datatype(), true)) { - push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer); + // Try reverse test since it can be a masked subtype. + if (!is_type_compatible(member.variable->initializer->get_datatype(), datatype, true)) { + push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer); + } else { + // TODO: Add warning. + mark_node_unsafe(member.variable->initializer); + } } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { #ifdef DEBUG_ENABLED parser->push_warning(member.variable->initializer, GDScriptWarning::NARROWING_CONVERSION); @@ -994,7 +1000,13 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable if (p_variable->initializer != nullptr) { if (!is_type_compatible(type, p_variable->initializer->get_datatype(), true)) { - push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", p_variable->initializer->get_datatype().to_string(), type.to_string()), p_variable->initializer); + // Try reverse test since it can be a masked subtype. + if (!is_type_compatible(p_variable->initializer->get_datatype(), type, true)) { + push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", p_variable->initializer->get_datatype().to_string(), type.to_string()), p_variable->initializer); + } else { + // TODO: Add warning. + mark_node_unsafe(p_variable->initializer); + } #ifdef DEBUG_ENABLED } else if (type.builtin_type == Variant::INT && p_variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { parser->push_warning(p_variable->initializer, GDScriptWarning::NARROWING_CONVERSION); @@ -1385,9 +1397,16 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig compatible = is_type_compatible(p_assignment->assignee->get_datatype(), op_type, true); if (!compatible) { if (p_assignment->assignee->get_datatype().is_hard_type()) { - push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", p_assignment->assigned_value->get_datatype().to_string(), p_assignment->assignee->get_datatype().to_string()), p_assignment->assigned_value); + // Try reverse test since it can be a masked subtype. + if (!is_type_compatible(op_type, p_assignment->assignee->get_datatype(), true)) { + push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", p_assignment->assigned_value->get_datatype().to_string(), p_assignment->assignee->get_datatype().to_string()), p_assignment->assigned_value); + } else { + // TODO: Add warning. + mark_node_unsafe(p_assignment); + } } else { // TODO: Warning in this case. + mark_node_unsafe(p_assignment); } } } else { |