Merge pull request #40690 from ThakeeNathees/arithmetic-assign-type-check-bug-fix

GDScript arithmetic assignment type check bug fix
This commit is contained in:
George Marques 2020-08-03 09:26:09 -03:00 committed by GitHub
commit 9adf6d3441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 53 additions and 5 deletions

View File

@ -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()) {