GDScript: Anonymous lambda names include name of variable assigned to
This commit is contained in:
parent
9006086fa6
commit
6757f27dec
3 changed files with 35 additions and 5 deletions
|
@ -2258,6 +2258,9 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
|
||||||
if (p_func) {
|
if (p_func) {
|
||||||
if (p_func->identifier) {
|
if (p_func->identifier) {
|
||||||
func_name = p_func->identifier->name;
|
func_name = p_func->identifier->name;
|
||||||
|
} else if (p_func->source_lambda && p_func->source_lambda->parent_variable) {
|
||||||
|
GDScriptParser::AssignableNode *parent_variable = p_func->source_lambda->parent_variable;
|
||||||
|
func_name = vformat("<anonymous lambda(%s)>", parent_variable->identifier->name);
|
||||||
} else {
|
} else {
|
||||||
func_name = "<anonymous lambda>";
|
func_name = "<anonymous lambda>";
|
||||||
}
|
}
|
||||||
|
|
|
@ -812,9 +812,8 @@ bool GDScriptParser::has_class(const GDScriptParser::ClassNode *p_class) const {
|
||||||
GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {
|
GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {
|
||||||
ClassNode *n_class = alloc_node<ClassNode>();
|
ClassNode *n_class = alloc_node<ClassNode>();
|
||||||
|
|
||||||
ClassNode *previous_class = current_class;
|
n_class->outer = current_class;
|
||||||
current_class = n_class;
|
ScopedSet scoped_set_current_class(current_class, n_class);
|
||||||
n_class->outer = previous_class;
|
|
||||||
|
|
||||||
if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for the class name after "class".)")) {
|
if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for the class name after "class".)")) {
|
||||||
n_class->identifier = parse_identifier();
|
n_class->identifier = parse_identifier();
|
||||||
|
@ -838,7 +837,6 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {
|
||||||
bool multiline = match(GDScriptTokenizer::Token::NEWLINE);
|
bool multiline = match(GDScriptTokenizer::Token::NEWLINE);
|
||||||
|
|
||||||
if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {
|
if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {
|
||||||
current_class = previous_class;
|
|
||||||
complete_extents(n_class);
|
complete_extents(n_class);
|
||||||
return n_class;
|
return n_class;
|
||||||
}
|
}
|
||||||
|
@ -858,7 +856,6 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {
|
||||||
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)");
|
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)");
|
||||||
}
|
}
|
||||||
|
|
||||||
current_class = previous_class;
|
|
||||||
return n_class;
|
return n_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,6 +978,8 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)(b
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptParser::parse_class_body(bool p_is_multiline) {
|
void GDScriptParser::parse_class_body(bool p_is_multiline) {
|
||||||
|
ScopedSet scoped_set_current_variable(current_variable, nullptr);
|
||||||
|
|
||||||
bool class_end = false;
|
bool class_end = false;
|
||||||
bool next_is_static = false;
|
bool next_is_static = false;
|
||||||
while (!class_end && !is_at_end()) {
|
while (!class_end && !is_at_end()) {
|
||||||
|
@ -1079,6 +1078,8 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static) {
|
||||||
GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static, bool p_allow_property) {
|
GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static, bool p_allow_property) {
|
||||||
VariableNode *variable = alloc_node<VariableNode>();
|
VariableNode *variable = alloc_node<VariableNode>();
|
||||||
|
|
||||||
|
ScopedSet scoped_set_current_variable(current_variable, variable);
|
||||||
|
|
||||||
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected variable name after "var".)")) {
|
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected variable name after "var".)")) {
|
||||||
complete_extents(variable);
|
complete_extents(variable);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1315,6 +1316,8 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
|
||||||
GDScriptParser::ConstantNode *GDScriptParser::parse_constant(bool p_is_static) {
|
GDScriptParser::ConstantNode *GDScriptParser::parse_constant(bool p_is_static) {
|
||||||
ConstantNode *constant = alloc_node<ConstantNode>();
|
ConstantNode *constant = alloc_node<ConstantNode>();
|
||||||
|
|
||||||
|
ScopedSet scoped_set_current_variable(current_variable, constant);
|
||||||
|
|
||||||
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected constant name after "const".)")) {
|
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected constant name after "const".)")) {
|
||||||
complete_extents(constant);
|
complete_extents(constant);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1358,6 +1361,9 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterNode *parameter = alloc_node<ParameterNode>();
|
ParameterNode *parameter = alloc_node<ParameterNode>();
|
||||||
|
|
||||||
|
ScopedSet scoped_set_current_variable(current_variable, parameter);
|
||||||
|
|
||||||
parameter->identifier = parse_identifier();
|
parameter->identifier = parse_identifier();
|
||||||
|
|
||||||
if (match(GDScriptTokenizer::Token::COLON)) {
|
if (match(GDScriptTokenizer::Token::COLON)) {
|
||||||
|
@ -1705,6 +1711,8 @@ bool GDScriptParser::register_annotation(const MethodInfo &p_info, uint32_t p_ta
|
||||||
}
|
}
|
||||||
|
|
||||||
GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context, SuiteNode *p_suite, bool p_for_lambda) {
|
GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context, SuiteNode *p_suite, bool p_for_lambda) {
|
||||||
|
ScopedSet scoped_set_current_variable(current_variable, nullptr);
|
||||||
|
|
||||||
SuiteNode *suite = p_suite != nullptr ? p_suite : alloc_node<SuiteNode>();
|
SuiteNode *suite = p_suite != nullptr ? p_suite : alloc_node<SuiteNode>();
|
||||||
suite->parent_block = current_suite;
|
suite->parent_block = current_suite;
|
||||||
suite->parent_function = current_function;
|
suite->parent_function = current_function;
|
||||||
|
@ -3410,6 +3418,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p
|
||||||
LambdaNode *lambda = alloc_node<LambdaNode>();
|
LambdaNode *lambda = alloc_node<LambdaNode>();
|
||||||
lambda->parent_function = current_function;
|
lambda->parent_function = current_function;
|
||||||
lambda->parent_lambda = current_lambda;
|
lambda->parent_lambda = current_lambda;
|
||||||
|
lambda->parent_variable = current_variable;
|
||||||
|
|
||||||
FunctionNode *function = alloc_node<FunctionNode>();
|
FunctionNode *function = alloc_node<FunctionNode>();
|
||||||
function->source_lambda = lambda;
|
function->source_lambda = lambda;
|
||||||
|
|
|
@ -931,6 +931,7 @@ public:
|
||||||
FunctionNode *function = nullptr;
|
FunctionNode *function = nullptr;
|
||||||
FunctionNode *parent_function = nullptr;
|
FunctionNode *parent_function = nullptr;
|
||||||
LambdaNode *parent_lambda = nullptr;
|
LambdaNode *parent_lambda = nullptr;
|
||||||
|
AssignableNode *parent_variable = nullptr;
|
||||||
Vector<IdentifierNode *> captures;
|
Vector<IdentifierNode *> captures;
|
||||||
HashMap<StringName, int> captures_indices;
|
HashMap<StringName, int> captures_indices;
|
||||||
bool use_self = false;
|
bool use_self = false;
|
||||||
|
@ -1325,6 +1326,22 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename T>
|
||||||
|
class ScopedSet {
|
||||||
|
T *var;
|
||||||
|
T old_value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename TNew>
|
||||||
|
ScopedSet(T &p_var, const TNew &p_new_value) :
|
||||||
|
var(&p_var), old_value(p_var) {
|
||||||
|
p_var = p_new_value;
|
||||||
|
}
|
||||||
|
~ScopedSet() {
|
||||||
|
*var = old_value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
friend class GDScriptAnalyzer;
|
friend class GDScriptAnalyzer;
|
||||||
friend class GDScriptParserRef;
|
friend class GDScriptParserRef;
|
||||||
|
|
||||||
|
@ -1365,6 +1382,7 @@ private:
|
||||||
FunctionNode *current_function = nullptr;
|
FunctionNode *current_function = nullptr;
|
||||||
LambdaNode *current_lambda = nullptr;
|
LambdaNode *current_lambda = nullptr;
|
||||||
SuiteNode *current_suite = nullptr;
|
SuiteNode *current_suite = nullptr;
|
||||||
|
AssignableNode *current_variable = nullptr;
|
||||||
|
|
||||||
CompletionContext completion_context;
|
CompletionContext completion_context;
|
||||||
CompletionCall completion_call;
|
CompletionCall completion_call;
|
||||||
|
|
Loading…
Reference in a new issue