summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/gdscript_analyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_analyzer.cpp')
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp37
1 files changed, 24 insertions, 13 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 1161403c0c..38d5ae6b77 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1857,29 +1857,40 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
push_error(vformat(R"*(Invalid call for "range()" function. Expected at most 3 arguments, %d given.)*", call->arguments.size()), call->callee);
} else {
// Now we can optimize it.
- bool all_is_constant = true;
+ bool can_reduce = true;
Vector<Variant> args;
args.resize(call->arguments.size());
for (int i = 0; i < call->arguments.size(); i++) {
GDScriptParser::ExpressionNode *argument = call->arguments[i];
reduce_expression(argument);
- if (!argument->is_constant) {
- all_is_constant = false;
- break;
- }
- if (argument->reduced_value.get_type() != Variant::INT && argument->reduced_value.get_type() != Variant::FLOAT) {
- push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, Variant::get_type_name(argument->reduced_value.get_type())), argument);
- all_is_constant = false;
- break;
+ if (argument->is_constant) {
+ if (argument->reduced_value.get_type() != Variant::INT && argument->reduced_value.get_type() != Variant::FLOAT) {
+ can_reduce = false;
+ push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, Variant::get_type_name(argument->reduced_value.get_type())), argument);
+ }
+ if (can_reduce) {
+ args.write[i] = argument->reduced_value;
+ }
+ } else {
+ can_reduce = false;
+ GDScriptParser::DataType argument_type = argument->get_datatype();
+ if (argument_type.is_variant() || !argument_type.is_hard_type()) {
+ mark_node_unsafe(argument);
+ }
+ if (!argument_type.is_variant() && (argument_type.builtin_type != Variant::INT && argument_type.builtin_type != Variant::FLOAT)) {
+ if (!argument_type.is_hard_type()) {
+ downgrade_node_type_source(argument);
+ } else {
+ push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, argument_type.to_string()), argument);
+ }
+ }
}
-
- args.write[i] = argument->reduced_value;
}
Variant reduced;
- if (all_is_constant) {
+ if (can_reduce) {
switch (args.size()) {
case 1:
reduced = (int32_t)args[0];
@@ -2607,7 +2618,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
result = get_operation_type(p_binary_op->variant_op, left_type, right_type, valid, p_binary_op);
if (!valid) {
push_error(vformat(R"(Invalid operands "%s" and "%s" for "%s" operator.)", left_type.to_string(), right_type.to_string(), Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op);
- } else if (result.type_source != GDScriptParser::DataType::ANNOTATED_EXPLICIT) {
+ } else if (!result.is_hard_type()) {
mark_node_unsafe(p_binary_op);
}
} else {