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->identifier) {
|
||||
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 {
|
||||
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) {
|
||||
ClassNode *n_class = alloc_node<ClassNode>();
|
||||
|
||||
ClassNode *previous_class = current_class;
|
||||
current_class = n_class;
|
||||
n_class->outer = previous_class;
|
||||
n_class->outer = current_class;
|
||||
ScopedSet scoped_set_current_class(current_class, n_class);
|
||||
|
||||
if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for the class name after "class".)")) {
|
||||
n_class->identifier = parse_identifier();
|
||||
|
@ -838,7 +837,6 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {
|
|||
bool multiline = match(GDScriptTokenizer::Token::NEWLINE);
|
||||
|
||||
if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {
|
||||
current_class = previous_class;
|
||||
complete_extents(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.)");
|
||||
}
|
||||
|
||||
current_class = previous_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) {
|
||||
ScopedSet scoped_set_current_variable(current_variable, nullptr);
|
||||
|
||||
bool class_end = false;
|
||||
bool next_is_static = false;
|
||||
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) {
|
||||
VariableNode *variable = alloc_node<VariableNode>();
|
||||
|
||||
ScopedSet scoped_set_current_variable(current_variable, variable);
|
||||
|
||||
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected variable name after "var".)")) {
|
||||
complete_extents(variable);
|
||||
return nullptr;
|
||||
|
@ -1315,6 +1316,8 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
|
|||
GDScriptParser::ConstantNode *GDScriptParser::parse_constant(bool p_is_static) {
|
||||
ConstantNode *constant = alloc_node<ConstantNode>();
|
||||
|
||||
ScopedSet scoped_set_current_variable(current_variable, constant);
|
||||
|
||||
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected constant name after "const".)")) {
|
||||
complete_extents(constant);
|
||||
return nullptr;
|
||||
|
@ -1358,6 +1361,9 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
|
|||
}
|
||||
|
||||
ParameterNode *parameter = alloc_node<ParameterNode>();
|
||||
|
||||
ScopedSet scoped_set_current_variable(current_variable, parameter);
|
||||
|
||||
parameter->identifier = parse_identifier();
|
||||
|
||||
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) {
|
||||
ScopedSet scoped_set_current_variable(current_variable, nullptr);
|
||||
|
||||
SuiteNode *suite = p_suite != nullptr ? p_suite : alloc_node<SuiteNode>();
|
||||
suite->parent_block = current_suite;
|
||||
suite->parent_function = current_function;
|
||||
|
@ -3410,6 +3418,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p
|
|||
LambdaNode *lambda = alloc_node<LambdaNode>();
|
||||
lambda->parent_function = current_function;
|
||||
lambda->parent_lambda = current_lambda;
|
||||
lambda->parent_variable = current_variable;
|
||||
|
||||
FunctionNode *function = alloc_node<FunctionNode>();
|
||||
function->source_lambda = lambda;
|
||||
|
|
|
@ -931,6 +931,7 @@ public:
|
|||
FunctionNode *function = nullptr;
|
||||
FunctionNode *parent_function = nullptr;
|
||||
LambdaNode *parent_lambda = nullptr;
|
||||
AssignableNode *parent_variable = nullptr;
|
||||
Vector<IdentifierNode *> captures;
|
||||
HashMap<StringName, int> captures_indices;
|
||||
bool use_self = false;
|
||||
|
@ -1325,6 +1326,22 @@ public:
|
|||
};
|
||||
|
||||
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 GDScriptParserRef;
|
||||
|
||||
|
@ -1365,6 +1382,7 @@ private:
|
|||
FunctionNode *current_function = nullptr;
|
||||
LambdaNode *current_lambda = nullptr;
|
||||
SuiteNode *current_suite = nullptr;
|
||||
AssignableNode *current_variable = nullptr;
|
||||
|
||||
CompletionContext completion_context;
|
||||
CompletionCall completion_call;
|
||||
|
|
Loading…
Reference in a new issue