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.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 38f9163f70..38d5ae6b77 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -657,6 +657,10 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
} else if (ProjectSettings::get_singleton()->has_autoload(first) && ProjectSettings::get_singleton()->get_autoload(first).is_singleton) {
const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(first);
Ref<GDScriptParserRef> ref = get_parser_for(autoload.path);
+ if (ref.is_null()) {
+ push_error(vformat(R"(The referenced autoload "%s" (from "%s") could not be loaded.)", first, autoload.path), p_type);
+ return bad_type;
+ }
if (ref->raise_status(GDScriptParserRef::INHERITANCE_SOLVED) != OK) {
push_error(vformat(R"(Could not parse singleton "%s" from "%s".)", first, autoload.path), p_type);
return bad_type;
@@ -727,7 +731,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
}
}
if (!result.is_set()) {
- push_error(vformat(R"("%s" was not found in the current scope.)", first), p_type);
+ push_error(vformat(R"(Could not find type "%s" in the current scope.)", first), p_type);
return bad_type;
}
@@ -1534,6 +1538,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
// Check if the function signature matches the parent. If not it's an error since it breaks polymorphism.
// Not for the constructor which can vary in signature.
GDScriptParser::DataType base_type = parser->current_class->base_type;
+ base_type.is_meta_type = false;
GDScriptParser::DataType parent_return_type;
List<GDScriptParser::DataType> parameters_types;
int default_par_count = 0;
@@ -1852,33 +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++) {
- reduce_expression(call->arguments[i]);
-
- if (!call->arguments[i]->is_constant) {
- all_is_constant = false;
- } else if (all_is_constant) {
- args.write[i] = call->arguments[i]->reduced_value;
- }
+ GDScriptParser::ExpressionNode *argument = call->arguments[i];
+ reduce_expression(argument);
- GDScriptParser::DataType arg_type = call->arguments[i]->get_datatype();
- if (!arg_type.is_variant()) {
- if (arg_type.kind != GDScriptParser::DataType::BUILTIN) {
- all_is_constant = false;
- push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, arg_type.to_string()), call->arguments[i]);
- } else if (arg_type.builtin_type != Variant::INT && arg_type.builtin_type != Variant::FLOAT) {
- all_is_constant = false;
- push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, arg_type.to_string()), call->arguments[i]);
+ 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);
+ }
}
}
}
Variant reduced;
- if (all_is_constant) {
+ if (can_reduce) {
switch (args.size()) {
case 1:
reduced = (int32_t)args[0];
@@ -2606,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 {