diff options
Diffstat (limited to 'modules/gdscript/gdscript_parser.h')
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 93 |
1 files changed, 63 insertions, 30 deletions
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 272d21ffce..c09b07282f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,9 +31,9 @@ #ifndef GDSCRIPT_PARSER_H #define GDSCRIPT_PARSER_H -#include "core/io/multiplayer_api.h" #include "core/io/resource.h" -#include "core/object/reference.h" +#include "core/multiplayer/multiplayer.h" +#include "core/object/ref_counted.h" #include "core/object/script_language.h" #include "core/string/string_name.h" #include "core/string/ustring.h" @@ -76,6 +76,7 @@ public: struct GetNodeNode; struct IdentifierNode; struct IfNode; + struct LambdaNode; struct LiteralNode; struct MatchNode; struct MatchBranchNode; @@ -105,8 +106,7 @@ public: NATIVE, SCRIPT, CLASS, // GDScript. - ENUM, // Full enumeration. - ENUM_VALUE, // Value from enumeration. + ENUM, // Enumeration. VARIANT, // Can be any type. UNRESOLVED, }; @@ -132,7 +132,7 @@ public: ClassNode *class_type = nullptr; MethodInfo method_info; // For callable/signals. - Map<StringName, int> enum_values; // For enums. + OrderedHashMap<StringName, int> enum_values; // For enums. _FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; } _FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; } @@ -160,6 +160,10 @@ public: container_element_type = nullptr; } + bool is_typed_container_type() const; + + GDScriptParser::DataType get_typed_container_type() const; + bool operator==(const DataType &p_other) const { if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) { return true; // Can be consireded equal for parsing purposes. @@ -180,8 +184,6 @@ public: return builtin_type == p_other.builtin_type; case NATIVE: case ENUM: - return native_type == p_other.native_type; - case ENUM_VALUE: return native_type == p_other.native_type && enum_type == p_other.enum_type; case SCRIPT: return script_type == p_other.script_type; @@ -198,7 +200,7 @@ public: return !(this->operator==(p_other)); } - DataType &operator=(const DataType &p_other) { + void operator=(const DataType &p_other) { kind = p_other.kind; type_source = p_other.type_source; is_constant = p_other.is_constant; @@ -216,7 +218,6 @@ public: if (p_other.has_container_element_type()) { set_container_element_type(p_other.get_container_element_type()); } - return *this; } DataType() = default; @@ -267,6 +268,7 @@ public: GET_NODE, IDENTIFIER, IF, + LAMBDA, LITERAL, MATCH, MATCH_BRANCH, @@ -292,6 +294,7 @@ public: int leftmost_column = 0, rightmost_column = 0; Node *next = nullptr; List<AnnotationNode *> annotations; + Vector<uint32_t> ignored_warnings; DataType datatype; @@ -368,6 +371,7 @@ public: Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *assignee = nullptr; ExpressionNode *assigned_value = nullptr; + bool use_conversion_assign = false; AssignmentNode() { type = ASSIGNMENT; @@ -726,8 +730,9 @@ public: SuiteNode *body = nullptr; bool is_static = false; bool is_coroutine = false; - MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; + Multiplayer::RPCConfig rpc_config; MethodInfo info; + LambdaNode *source_lambda = nullptr; #ifdef TOOLS_ENABLED Vector<Variant> default_arg_values; String doc_description; @@ -771,6 +776,7 @@ public: VariableNode *variable_source; IdentifierNode *bind_source; }; + FunctionNode *source_function = nullptr; int usages = 0; // Useful for binds/iterator variable. @@ -789,6 +795,21 @@ public: } }; + struct LambdaNode : public ExpressionNode { + FunctionNode *function = nullptr; + FunctionNode *parent_function = nullptr; + Vector<IdentifierNode *> captures; + Map<StringName, int> captures_indices; + + bool has_name() const { + return function && function->identifier; + } + + LambdaNode() { + type = LAMBDA; + } + }; + struct LiteralNode : public ExpressionNode { Variant value; @@ -942,6 +963,7 @@ public: IdentifierNode *bind; }; StringName name; + FunctionNode *source_function = nullptr; int start_line = 0, end_line = 0; int start_column = 0, end_column = 0; @@ -951,10 +973,11 @@ public: String get_name() const; Local() {} - Local(ConstantNode *p_constant) { + Local(ConstantNode *p_constant, FunctionNode *p_source_function) { type = CONSTANT; constant = p_constant; name = p_constant->identifier->name; + source_function = p_source_function; start_line = p_constant->start_line; end_line = p_constant->end_line; @@ -963,10 +986,11 @@ public: leftmost_column = p_constant->leftmost_column; rightmost_column = p_constant->rightmost_column; } - Local(VariableNode *p_variable) { + Local(VariableNode *p_variable, FunctionNode *p_source_function) { type = VARIABLE; variable = p_variable; name = p_variable->identifier->name; + source_function = p_source_function; start_line = p_variable->start_line; end_line = p_variable->end_line; @@ -975,10 +999,11 @@ public: leftmost_column = p_variable->leftmost_column; rightmost_column = p_variable->rightmost_column; } - Local(ParameterNode *p_parameter) { + Local(ParameterNode *p_parameter, FunctionNode *p_source_function) { type = PARAMETER; parameter = p_parameter; name = p_parameter->identifier->name; + source_function = p_source_function; start_line = p_parameter->start_line; end_line = p_parameter->end_line; @@ -987,10 +1012,11 @@ public: leftmost_column = p_parameter->leftmost_column; rightmost_column = p_parameter->rightmost_column; } - Local(IdentifierNode *p_identifier) { + Local(IdentifierNode *p_identifier, FunctionNode *p_source_function) { type = FOR_VARIABLE; bind = p_identifier; name = p_identifier->name; + source_function = p_source_function; start_line = p_identifier->start_line; end_line = p_identifier->end_line; @@ -1015,9 +1041,9 @@ public: bool has_local(const StringName &p_name) const; const Local &get_local(const StringName &p_name) const; template <class T> - void add_local(T *p_local) { + void add_local(T *p_local, FunctionNode *p_source_function) { locals_indices[p_local->identifier->name] = locals.size(); - locals.push_back(Local(p_local)); + locals.push_back(Local(p_local, p_source_function)); } void add_local(const Local &p_local) { locals_indices[p_local.name] = locals.size(); @@ -1080,21 +1106,21 @@ public: PropertyStyle property = PROP_NONE; union { - SuiteNode *setter = nullptr; + FunctionNode *setter = nullptr; IdentifierNode *setter_pointer; }; IdentifierNode *setter_parameter = nullptr; union { - SuiteNode *getter = nullptr; + FunctionNode *getter = nullptr; IdentifierNode *getter_pointer; }; bool exported = false; bool onready = false; PropertyInfo export_info; - MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; int assignments = 0; int usages = 0; + bool use_conversion_assign = false; #ifdef TOOLS_ENABLED String doc_description; #endif // TOOLS_ENABLED @@ -1176,6 +1202,7 @@ private: #ifdef DEBUG_ENABLED List<GDScriptWarning> warnings; Set<String> ignored_warnings; + Set<uint32_t> ignored_warning_codes; Set<int> unsafe_lines; #endif @@ -1191,6 +1218,8 @@ private: CompletionCall completion_call; List<CompletionCall> completion_call_stack; bool passed_cursor = false; + bool in_lambda = false; + bool lambda_ended = false; // Marker for when a lambda ends, to apply an end of statement if needed. typedef bool (GDScriptParser::*AnnotationAction)(const AnnotationNode *p_annotation, Node *p_target); struct AnnotationInfo { @@ -1278,10 +1307,11 @@ private: GDScriptTokenizer::Token advance(); bool match(GDScriptTokenizer::Token::Type p_token_type); - bool check(GDScriptTokenizer::Token::Type p_token_type); + bool check(GDScriptTokenizer::Token::Type p_token_type) const; bool consume(GDScriptTokenizer::Token::Type p_token_type, const String &p_error_message); - bool is_at_end(); - bool is_statement_end(); + bool is_at_end() const; + bool is_statement_end_token() const; + bool is_statement_end() const; void end_statement(const String &p_context); void synchronize(); void push_multiline(bool p_state); @@ -1292,14 +1322,15 @@ private: ClassNode *parse_class(); void parse_class_name(); void parse_extends(); - void parse_class_body(); + void parse_class_body(bool p_is_multiline); template <class T> void parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind); SignalNode *parse_signal(); EnumNode *parse_enum(); ParameterNode *parse_parameter(); FunctionNode *parse_function(); - SuiteNode *parse_suite(const String &p_context, SuiteNode *p_suite = nullptr); + void parse_function_signature(FunctionNode *p_function, SuiteNode *p_body, const String &p_type); + SuiteNode *parse_suite(const String &p_context, SuiteNode *p_suite = nullptr, bool p_for_lambda = false); // Annotations AnnotationNode *parse_annotation(uint32_t p_valid_targets); bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, int p_optional_arguments = 0, bool p_is_vararg = false); @@ -1311,7 +1342,7 @@ private: template <PropertyHint t_hint, Variant::Type t_type> bool export_annotations(const AnnotationNode *p_annotation, Node *p_target); bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target); - template <MultiplayerAPI::RPCMode t_mode> + template <Multiplayer::RPCMode t_mode> bool network_annotations(const AnnotationNode *p_annotation, Node *p_target); // Statements. Node *parse_statement(); @@ -1354,6 +1385,8 @@ private: ExpressionNode *parse_await(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_attribute(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign); + ExpressionNode *parse_lambda(ExpressionNode *p_previous_operand, bool p_can_assign); + ExpressionNode *parse_yield(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_invalid_token(ExpressionNode *p_previous_operand, bool p_can_assign); TypeNode *parse_type(bool p_allow_void = false); #ifdef TOOLS_ENABLED @@ -1369,7 +1402,6 @@ public: ClassNode *get_tree() const { return head; } bool is_tool() const { return _is_tool; } static Variant::Type get_builtin_type(const StringName &p_type); - static StringName get_real_class_name(const StringName &p_source); CompletionContext get_completion_context() const { return completion_context; } CompletionCall get_completion_call() const { return completion_call; } @@ -1401,7 +1433,7 @@ public: void push_line(const String &p_line = String()); void push_text(const String &p_text); - void print_annotation(AnnotationNode *p_annotation); + void print_annotation(const AnnotationNode *p_annotation); void print_array(ArrayNode *p_array); void print_assert(AssertNode *p_assert); void print_assignment(AssignmentNode *p_assignment); @@ -1415,10 +1447,11 @@ public: void print_expression(ExpressionNode *p_expression); void print_enum(EnumNode *p_enum); void print_for(ForNode *p_for); - void print_function(FunctionNode *p_function); + void print_function(FunctionNode *p_function, const String &p_context = "Function"); void print_get_node(GetNodeNode *p_get_node); void print_if(IfNode *p_if, bool p_is_elif = false); void print_identifier(IdentifierNode *p_identifier); + void print_lambda(LambdaNode *p_lambda); void print_literal(LiteralNode *p_literal); void print_match(MatchNode *p_match); void print_match_branch(MatchBranchNode *p_match_branch); |