summaryrefslogtreecommitdiff
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.cpp38
1 files changed, 14 insertions, 24 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index eb660ef09f..8a07d509a1 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1195,10 +1195,6 @@ void GDScriptAnalyzer::resolve_node(GDScriptParser::Node *p_node, bool p_is_root
case GDScriptParser::Node::FOR:
resolve_for(static_cast<GDScriptParser::ForNode *>(p_node));
break;
- case GDScriptParser::Node::FUNCTION:
- resolve_function_signature(static_cast<GDScriptParser::FunctionNode *>(p_node));
- resolve_function_body(static_cast<GDScriptParser::FunctionNode *>(p_node));
- break;
case GDScriptParser::Node::IF:
resolve_if(static_cast<GDScriptParser::IfNode *>(p_node));
break;
@@ -1258,6 +1254,7 @@ void GDScriptAnalyzer::resolve_node(GDScriptParser::Node *p_node, bool p_is_root
case GDScriptParser::Node::BREAKPOINT:
case GDScriptParser::Node::CONTINUE:
case GDScriptParser::Node::ENUM:
+ case GDScriptParser::Node::FUNCTION:
case GDScriptParser::Node::PASS:
case GDScriptParser::Node::SIGNAL:
// Nothing to do.
@@ -1269,13 +1266,15 @@ void GDScriptAnalyzer::resolve_annotation(GDScriptParser::AnnotationNode *p_anno
// TODO: Add second validation function for annotations, so they can use checked types.
}
-void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *p_function, const GDScriptParser::Node *p_source) {
+void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *p_function, const GDScriptParser::Node *p_source, bool p_is_lambda) {
if (p_source == nullptr) {
p_source = p_function;
}
+ StringName function_name = p_function->identifier != nullptr ? p_function->identifier->name : StringName();
+
if (p_function->get_datatype().is_resolving()) {
- push_error(vformat(R"(Could not resolve function "%s": Cyclic reference.)", p_function->identifier->name), p_source);
+ push_error(vformat(R"(Could not resolve function "%s": Cyclic reference.)", function_name), p_source);
return;
}
@@ -1301,7 +1300,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
resolve_parameter(p_function->parameters[i]);
#ifdef DEBUG_ENABLED
if (p_function->parameters[i]->usages == 0 && !String(p_function->parameters[i]->identifier->name).begins_with("_")) {
- parser->push_warning(p_function->parameters[i]->identifier, GDScriptWarning::UNUSED_PARAMETER, p_function->identifier->name, p_function->parameters[i]->identifier->name);
+ parser->push_warning(p_function->parameters[i]->identifier, GDScriptWarning::UNUSED_PARAMETER, function_name, p_function->parameters[i]->identifier->name);
}
is_shadowing(p_function->parameters[i]->identifier, "function parameter");
#endif // DEBUG_ENABLED
@@ -1318,7 +1317,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
#endif // TOOLS_ENABLED
}
- if (p_function->identifier->name == GDScriptLanguage::get_singleton()->strings._init) {
+ if (!p_is_lambda && function_name == GDScriptLanguage::get_singleton()->strings._init) {
// Constructor.
GDScriptParser::DataType return_type = parser->current_class->get_datatype();
return_type.is_meta_type = false;
@@ -1350,7 +1349,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
int default_par_count = 0;
bool is_static = false;
bool is_vararg = false;
- if (get_function_signature(p_function, false, base_type, p_function->identifier->name, parent_return_type, parameters_types, default_par_count, is_static, is_vararg)) {
+ if (!p_is_lambda && get_function_signature(p_function, false, base_type, function_name, parent_return_type, parameters_types, default_par_count, is_static, is_vararg)) {
bool valid = p_function->is_static == is_static;
valid = valid && parent_return_type == p_function->get_datatype();
@@ -1365,7 +1364,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
if (!valid) {
// Compute parent signature as a string to show in the error message.
- String parent_signature = p_function->identifier->name.operator String() + "(";
+ String parent_signature = function_name.operator String() + "(";
int j = 0;
for (const GDScriptParser::DataType &par_type : parameters_types) {
if (j > 0) {
@@ -1404,7 +1403,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
parser->current_function = previous_function;
}
-void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_function) {
+void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_function, bool p_is_lambda) {
if (p_function->resolved_body) {
return;
}
@@ -1422,7 +1421,7 @@ void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_fun
return_type.type_source = GDScriptParser::DataType::INFERRED;
p_function->set_datatype(p_function->body->get_datatype());
} else if (p_function->get_datatype().is_hard_type() && (p_function->get_datatype().kind != GDScriptParser::DataType::BUILTIN || p_function->get_datatype().builtin_type != Variant::NIL)) {
- if (!p_function->body->has_return && p_function->identifier->name != GDScriptLanguage::get_singleton()->strings._init) {
+ if (!p_function->body->has_return && (p_is_lambda || p_function->identifier->name != GDScriptLanguage::get_singleton()->strings._init)) {
push_error(R"(Not all code paths return a value.)", p_function);
}
}
@@ -3297,16 +3296,10 @@ void GDScriptAnalyzer::reduce_lambda(GDScriptParser::LambdaNode *p_lambda) {
return;
}
- GDScriptParser::FunctionNode *previous_function = parser->current_function;
- parser->current_function = p_lambda->function;
-
lambda_stack.push_back(p_lambda);
-
- for (int i = 0; i < p_lambda->function->parameters.size(); i++) {
- resolve_parameter(p_lambda->function->parameters[i]);
- }
-
- resolve_suite(p_lambda->function->body);
+ resolve_function_signature(p_lambda->function, p_lambda, true);
+ resolve_function_body(p_lambda->function, true);
+ lambda_stack.pop_back();
int captures_amount = p_lambda->captures.size();
if (captures_amount > 0) {
@@ -3331,9 +3324,6 @@ void GDScriptAnalyzer::reduce_lambda(GDScriptParser::LambdaNode *p_lambda) {
p_lambda->function->parameters_indices[capture->name] = i;
}
}
-
- lambda_stack.pop_back();
- parser->current_function = previous_function;
}
void GDScriptAnalyzer::reduce_literal(GDScriptParser::LiteralNode *p_literal) {