diff options
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index f3b2bca3c6..531666bec5 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1369,12 +1369,60 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig push_error("Cannot assign a new value to a constant.", p_assignment->assignee); } - if (!is_type_compatible(p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), true)) { - 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); - } else { - // TODO: Warning in this case. + Variant::Operator vop = Variant::Operator::OP_EQUAL; + switch (p_assignment->operation) { + case GDScriptParser::AssignmentNode::OP_NONE: + vop = Variant::Operator::OP_EQUAL; + break; + case GDScriptParser::AssignmentNode::OP_ADDITION: + vop = Variant::Operator::OP_ADD; + break; + case GDScriptParser::AssignmentNode::OP_SUBTRACTION: + vop = Variant::Operator::OP_SUBTRACT; + break; + case GDScriptParser::AssignmentNode::OP_MULTIPLICATION: + vop = Variant::Operator::OP_MULTIPLY; + break; + case GDScriptParser::AssignmentNode::OP_DIVISION: + vop = Variant::Operator::OP_DIVIDE; + break; + case GDScriptParser::AssignmentNode::OP_MODULO: + vop = Variant::Operator::OP_MODULE; + break; + case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_LEFT: + vop = Variant::Operator::OP_SHIFT_LEFT; + break; + case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_RIGHT: + vop = Variant::Operator::OP_SHIFT_RIGHT; + break; + case GDScriptParser::AssignmentNode::OP_BIT_AND: + vop = Variant::Operator::OP_BIT_AND; + break; + case GDScriptParser::AssignmentNode::OP_BIT_OR: + vop = Variant::Operator::OP_BIT_OR; + break; + case GDScriptParser::AssignmentNode::OP_BIT_XOR: + vop = Variant::Operator::OP_BIT_XOR; + break; + } + + bool compatible = true; + GDScriptParser::DataType op_type = p_assignment->assigned_value->get_datatype(); + if (vop != Variant::OP_EQUAL) { + op_type = get_operation_type(vop, p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), compatible); + } + + if (compatible) { + 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); + } else { + // TODO: Warning in this case. + } } + } else { + push_error(vformat(R"(Invalid operands "%s" and "%s" for assignment operator.)", p_assignment->assignee->get_datatype().to_string(), p_assignment->assigned_value->get_datatype().to_string()), p_assignment); } if (p_assignment->assignee->get_datatype().has_no_type() || p_assignment->assigned_value->get_datatype().is_variant()) { |