| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688 | /**************************************************************************//*  gdscript_parser.h                                                     *//**************************************************************************//*                         This file is part of:                          *//*                             GODOT ENGINE                               *//*                        https://godotengine.org                         *//**************************************************************************//* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). *//* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  *//*                                                                        *//* Permission is hereby granted, free of charge, to any person obtaining  *//* a copy of this software and associated documentation files (the        *//* "Software"), to deal in the Software without restriction, including    *//* without limitation the rights to use, copy, modify, merge, publish,    *//* distribute, sublicense, and/or sell copies of the Software, and to     *//* permit persons to whom the Software is furnished to do so, subject to  *//* the following conditions:                                              *//*                                                                        *//* The above copyright notice and this permission notice shall be         *//* included in all copies or substantial portions of the Software.        *//*                                                                        *//* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        *//* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     *//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *//* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   *//* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   *//* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      *//* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 *//**************************************************************************/#pragma once#include "gdscript_cache.h"#include "gdscript_tokenizer.h"#ifdef DEBUG_ENABLED#include "gdscript_warning.h"#endif#include "core/io/resource.h"#include "core/object/ref_counted.h"#include "core/object/script_language.h"#include "core/string/string_name.h"#include "core/string/ustring.h"#include "core/templates/hash_map.h"#include "core/templates/list.h"#include "core/templates/vector.h"#include "core/variant/variant.h"#ifdef DEBUG_ENABLED#include "core/string/string_builder.h"#endifclass GDScriptParser {	struct AnnotationInfo;public:	// Forward-declare all parser nodes, to avoid ordering issues.	struct AnnotationNode;	struct ArrayNode;	struct AssertNode;	struct AssignableNode;	struct AssignmentNode;	struct AwaitNode;	struct BinaryOpNode;	struct BreakNode;	struct BreakpointNode;	struct CallNode;	struct CastNode;	struct ClassNode;	struct ConstantNode;	struct ContinueNode;	struct DictionaryNode;	struct EnumNode;	struct ExpressionNode;	struct ForNode;	struct FunctionNode;	struct GetNodeNode;	struct IdentifierNode;	struct IfNode;	struct LambdaNode;	struct LiteralNode;	struct MatchNode;	struct MatchBranchNode;	struct ParameterNode;	struct PassNode;	struct PatternNode;	struct PreloadNode;	struct ReturnNode;	struct SelfNode;	struct SignalNode;	struct SubscriptNode;	struct SuiteNode;	struct TernaryOpNode;	struct TypeNode;	struct TypeTestNode;	struct UnaryOpNode;	struct VariableNode;	struct WhileNode;	class DataType {	public:		Vector<DataType> container_element_types;		enum Kind {			BUILTIN,			NATIVE,			SCRIPT,			CLASS, // GDScript.			ENUM, // Enumeration.			VARIANT, // Can be any type.			RESOLVING, // Currently resolving.			UNRESOLVED,		};		Kind kind = UNRESOLVED;		enum TypeSource {			UNDETECTED, // Can be any type.			INFERRED, // Has inferred type, but still dynamic.			ANNOTATED_EXPLICIT, // Has a specific type annotated.			ANNOTATED_INFERRED, // Has a static type but comes from the assigned value.		};		TypeSource type_source = UNDETECTED;		bool is_constant = false;		bool is_read_only = false;		bool is_meta_type = false;		bool is_pseudo_type = false; // For global names that can't be used standalone.		bool is_coroutine = false; // For function calls.		Variant::Type builtin_type = Variant::NIL;		StringName native_type;		StringName enum_type; // Enum name or the value name in an enum.		Ref<Script> script_type;		String script_path;		ClassNode *class_type = nullptr;		MethodInfo method_info; // For callable/signals.		HashMap<StringName, int64_t> enum_values; // For enums.		_FORCE_INLINE_ bool is_set() const { return kind != RESOLVING && kind != UNRESOLVED; }		_FORCE_INLINE_ bool is_resolving() const { return kind == RESOLVING; }		_FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }		_FORCE_INLINE_ bool is_variant() const { return kind == VARIANT || kind == RESOLVING || kind == UNRESOLVED; }		_FORCE_INLINE_ bool is_hard_type() const { return type_source > INFERRED; }		String to_string() const;		_FORCE_INLINE_ String to_string_strict() const { return is_hard_type() ? to_string() : "Variant"; }		PropertyInfo to_property_info(const String &p_name) const;		_FORCE_INLINE_ static DataType get_variant_type() { // Default DataType for container elements.			DataType datatype;			datatype.kind = VARIANT;			datatype.type_source = INFERRED;			return datatype;		}		_FORCE_INLINE_ void set_container_element_type(int p_index, const DataType &p_type) {			ERR_FAIL_COND(p_index < 0);			while (p_index >= container_element_types.size()) {				container_element_types.push_back(get_variant_type());			}			container_element_types.write[p_index] = DataType(p_type);		}		_FORCE_INLINE_ int get_container_element_type_count() const {			return container_element_types.size();		}		_FORCE_INLINE_ DataType get_container_element_type(int p_index) const {			ERR_FAIL_INDEX_V(p_index, container_element_types.size(), get_variant_type());			return container_element_types[p_index];		}		_FORCE_INLINE_ DataType get_container_element_type_or_variant(int p_index) const {			if (p_index < 0 || p_index >= container_element_types.size()) {				return get_variant_type();			}			return container_element_types[p_index];		}		_FORCE_INLINE_ bool has_container_element_type(int p_index) const {			return p_index >= 0 && p_index < container_element_types.size();		}		_FORCE_INLINE_ bool has_container_element_types() const {			return !container_element_types.is_empty();		}		bool is_typed_container_type() const;		GDScriptParser::DataType get_typed_container_type() const;		bool can_reference(const DataType &p_other) const;		bool operator==(const DataType &p_other) const {			if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) {				return true; // Can be considered equal for parsing purposes.			}			if (type_source == INFERRED || p_other.type_source == INFERRED) {				return true; // Can be considered equal for parsing purposes.			}			if (kind != p_other.kind) {				return false;			}			switch (kind) {				case VARIANT:					return true; // All variants are the same.				case BUILTIN:					return builtin_type == p_other.builtin_type;				case NATIVE:				case ENUM: // Enums use native_type to identify the enum and its base class.					return native_type == p_other.native_type;				case SCRIPT:					return script_type == p_other.script_type;				case CLASS:					return class_type == p_other.class_type || class_type->fqcn == p_other.class_type->fqcn;				case RESOLVING:				case UNRESOLVED:					break;			}			return false;		}		bool operator!=(const DataType &p_other) const {			return !(*this == p_other);		}		void operator=(const DataType &p_other) {			kind = p_other.kind;			type_source = p_other.type_source;			is_read_only = p_other.is_read_only;			is_constant = p_other.is_constant;			is_meta_type = p_other.is_meta_type;			is_pseudo_type = p_other.is_pseudo_type;			is_coroutine = p_other.is_coroutine;			builtin_type = p_other.builtin_type;			native_type = p_other.native_type;			enum_type = p_other.enum_type;			script_type = p_other.script_type;			script_path = p_other.script_path;			class_type = p_other.class_type;			method_info = p_other.method_info;			enum_values = p_other.enum_values;			container_element_types = p_other.container_element_types;		}		DataType() = default;		DataType(const DataType &p_other) {			*this = p_other;		}		~DataType() {}	};	struct ParserError {		// TODO: Do I really need a "type"?		// enum Type {		//     NO_ERROR,		//     EMPTY_FILE,		//     CLASS_NAME_USED_TWICE,		//     EXTENDS_USED_TWICE,		//     EXPECTED_END_STATEMENT,		// };		// Type type = NO_ERROR;		String message;		int line = 0, column = 0;	};#ifdef TOOLS_ENABLED	struct ClassDocData {		String brief;		String description;		Vector<Pair<String, String>> tutorials;		bool is_deprecated = false;		String deprecated_message;		bool is_experimental = false;		String experimental_message;	};	struct MemberDocData {		String description;		bool is_deprecated = false;		String deprecated_message;		bool is_experimental = false;		String experimental_message;	};#endif // TOOLS_ENABLED	struct Node {		enum Type {			NONE,			ANNOTATION,			ARRAY,			ASSERT,			ASSIGNMENT,			AWAIT,			BINARY_OPERATOR,			BREAK,			BREAKPOINT,			CALL,			CAST,			CLASS,			CONSTANT,			CONTINUE,			DICTIONARY,			ENUM,			FOR,			FUNCTION,			GET_NODE,			IDENTIFIER,			IF,			LAMBDA,			LITERAL,			MATCH,			MATCH_BRANCH,			PARAMETER,			PASS,			PATTERN,			PRELOAD,			RETURN,			SELF,			SIGNAL,			SUBSCRIPT,			SUITE,			TERNARY_OPERATOR,			TYPE,			TYPE_TEST,			UNARY_OPERATOR,			VARIABLE,			WHILE,		};		Type type = NONE;		int start_line = 0, end_line = 0;		int start_column = 0, end_column = 0;		Node *next = nullptr;		List<AnnotationNode *> annotations;		DataType datatype;		virtual DataType get_datatype() const { return datatype; }		virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }		virtual bool is_expression() const { return false; }		virtual ~Node() {}	};	struct ExpressionNode : public Node {		// Base type for all expression kinds.		bool reduced = false;		bool is_constant = false;		Variant reduced_value;		virtual bool is_expression() const override { return true; }		virtual ~ExpressionNode() {}	protected:		ExpressionNode() {}	};	struct AnnotationNode : public Node {		StringName name;		Vector<ExpressionNode *> arguments;		Vector<Variant> resolved_arguments;		/** Information of the annotation. Might be null for unknown annotations. */		AnnotationInfo *info = nullptr;		PropertyInfo export_info;		bool is_resolved = false;		bool is_applied = false;		bool apply(GDScriptParser *p_this, Node *p_target, ClassNode *p_class);		bool applies_to(uint32_t p_target_kinds) const;		AnnotationNode() {			type = ANNOTATION;		}	};	struct ArrayNode : public ExpressionNode {		Vector<ExpressionNode *> elements;		ArrayNode() {			type = ARRAY;		}	};	struct AssertNode : public Node {		ExpressionNode *condition = nullptr;		ExpressionNode *message = nullptr;		AssertNode() {			type = ASSERT;		}	};	struct AssignableNode : public Node {		IdentifierNode *identifier = nullptr;		ExpressionNode *initializer = nullptr;		TypeNode *datatype_specifier = nullptr;		bool infer_datatype = false;		bool use_conversion_assign = false;		int usages = 0;		virtual ~AssignableNode() {}	protected:		AssignableNode() {}	};	struct AssignmentNode : public ExpressionNode {		// Assignment is not really an expression but it's easier to parse as if it were.		enum Operation {			OP_NONE,			OP_ADDITION,			OP_SUBTRACTION,			OP_MULTIPLICATION,			OP_DIVISION,			OP_MODULO,			OP_POWER,			OP_BIT_SHIFT_LEFT,			OP_BIT_SHIFT_RIGHT,			OP_BIT_AND,			OP_BIT_OR,			OP_BIT_XOR,		};		Operation operation = OP_NONE;		Variant::Operator variant_op = Variant::OP_MAX;		ExpressionNode *assignee = nullptr;		ExpressionNode *assigned_value = nullptr;		bool use_conversion_assign = false;		AssignmentNode() {			type = ASSIGNMENT;		}	};	struct AwaitNode : public ExpressionNode {		ExpressionNode *to_await = nullptr;		AwaitNode() {			type = AWAIT;		}	};	struct BinaryOpNode : public ExpressionNode {		enum OpType {			OP_ADDITION,			OP_SUBTRACTION,			OP_MULTIPLICATION,			OP_DIVISION,			OP_MODULO,			OP_POWER,			OP_BIT_LEFT_SHIFT,			OP_BIT_RIGHT_SHIFT,			OP_BIT_AND,			OP_BIT_OR,			OP_BIT_XOR,			OP_LOGIC_AND,			OP_LOGIC_OR,			OP_CONTENT_TEST,			OP_COMP_EQUAL,			OP_COMP_NOT_EQUAL,			OP_COMP_LESS,			OP_COMP_LESS_EQUAL,			OP_COMP_GREATER,			OP_COMP_GREATER_EQUAL,		};		OpType operation = OpType::OP_ADDITION;		Variant::Operator variant_op = Variant::OP_MAX;		ExpressionNode *left_operand = nullptr;		ExpressionNode *right_operand = nullptr;		BinaryOpNode() {			type = BINARY_OPERATOR;		}	};	struct BreakNode : public Node {		BreakNode() {			type = BREAK;		}	};	struct BreakpointNode : public Node {		BreakpointNode() {			type = BREAKPOINT;		}	};	struct CallNode : public ExpressionNode {		ExpressionNode *callee = nullptr;		Vector<ExpressionNode *> arguments;		StringName function_name;		bool is_super = false;		bool is_static = false;		CallNode() {			type = CALL;		}		Type get_callee_type() const {			if (callee == nullptr) {				return Type::NONE;			} else {				return callee->type;			}		}	};	struct CastNode : public ExpressionNode {		ExpressionNode *operand = nullptr;		TypeNode *cast_type = nullptr;		CastNode() {			type = CAST;		}	};	struct EnumNode : public Node {		struct Value {			IdentifierNode *identifier = nullptr;			ExpressionNode *custom_value = nullptr;			EnumNode *parent_enum = nullptr;			int index = -1;			bool resolved = false;			int64_t value = 0;			int line = 0;			int start_column = 0;			int end_column = 0;#ifdef TOOLS_ENABLED			MemberDocData doc_data;#endif // TOOLS_ENABLED		};		IdentifierNode *identifier = nullptr;		Vector<Value> values;		Variant dictionary;#ifdef TOOLS_ENABLED		MemberDocData doc_data;#endif // TOOLS_ENABLED		EnumNode() {			type = ENUM;		}	};	struct ClassNode : public Node {		struct Member {			enum Type {				UNDEFINED,				CLASS,				CONSTANT,				FUNCTION,				SIGNAL,				VARIABLE,				ENUM,				ENUM_VALUE, // For unnamed enums.				GROUP, // For member grouping.			};			Type type = UNDEFINED;			union {				ClassNode *m_class = nullptr;				ConstantNode *constant;				FunctionNode *function;				SignalNode *signal;				VariableNode *variable;				EnumNode *m_enum;				AnnotationNode *annotation;			};			EnumNode::Value enum_value;			String get_name() const {				switch (type) {					case UNDEFINED:						return "<undefined member>";					case CLASS:						// All class-type members have an id.						return m_class->identifier->name;					case CONSTANT:						return constant->identifier->name;					case FUNCTION:						return function->identifier->name;					case SIGNAL:						return signal->identifier->name;					case VARIABLE:						return variable->identifier->name;					case ENUM:						// All enum-type members have an id.						return m_enum->identifier->name;					case ENUM_VALUE:						return enum_value.identifier->name;					case GROUP:						return annotation->export_info.name;				}				return "";			}			String get_type_name() const {				switch (type) {					case UNDEFINED:						return "???";					case CLASS:						return "class";					case CONSTANT:						return "constant";					case FUNCTION:						return "function";					case SIGNAL:						return "signal";					case VARIABLE:						return "variable";					case ENUM:						return "enum";					case ENUM_VALUE:						return "enum value";					case GROUP:						return "group";				}				return "";			}			int get_line() const {				switch (type) {					case CLASS:						return m_class->start_line;					case CONSTANT:						return constant->start_line;					case FUNCTION:						return function->start_line;					case VARIABLE:						return variable->start_line;					case ENUM_VALUE:						return enum_value.line;					case ENUM:						return m_enum->start_line;					case SIGNAL:						return signal->start_line;					case GROUP:						return annotation->start_line;					case UNDEFINED:						ERR_FAIL_V_MSG(-1, "Reaching undefined member type.");				}				ERR_FAIL_V_MSG(-1, "Reaching unhandled type.");			}			DataType get_datatype() const {				switch (type) {					case CLASS:						return m_class->get_datatype();					case CONSTANT:						return constant->get_datatype();					case FUNCTION:						return function->get_datatype();					case VARIABLE:						return variable->get_datatype();					case ENUM:						return m_enum->get_datatype();					case ENUM_VALUE:						return enum_value.identifier->get_datatype();					case SIGNAL:						return signal->get_datatype();					case GROUP:						return DataType();					case UNDEFINED:						return DataType();				}				ERR_FAIL_V_MSG(DataType(), "Reaching unhandled type.");			}			Node *get_source_node() const {				switch (type) {					case CLASS:						return m_class;					case CONSTANT:						return constant;					case FUNCTION:						return function;					case VARIABLE:						return variable;					case ENUM:						return m_enum;					case ENUM_VALUE:						return enum_value.identifier;					case SIGNAL:						return signal;					case GROUP:						return annotation;					case UNDEFINED:						return nullptr;				}				ERR_FAIL_V_MSG(nullptr, "Reaching unhandled type.");			}			Member() {}			Member(ClassNode *p_class) {				type = CLASS;				m_class = p_class;			}			Member(ConstantNode *p_constant) {				type = CONSTANT;				constant = p_constant;			}			Member(VariableNode *p_variable) {				type = VARIABLE;				variable = p_variable;			}			Member(SignalNode *p_signal) {				type = SIGNAL;				signal = p_signal;			}			Member(FunctionNode *p_function) {				type = FUNCTION;				function = p_function;			}			Member(EnumNode *p_enum) {				type = ENUM;				m_enum = p_enum;			}			Member(const EnumNode::Value &p_enum_value) {				type = ENUM_VALUE;				enum_value = p_enum_value;			}			Member(AnnotationNode *p_annotation) {				type = GROUP;				annotation = p_annotation;			}		};		IdentifierNode *identifier = nullptr;		String icon_path;		String simplified_icon_path;		Vector<Member> members;		HashMap<StringName, int> members_indices;		ClassNode *outer = nullptr;		bool extends_used = false;		bool onready_used = false;		bool is_abstract = false;		bool has_static_data = false;		bool annotated_static_unload = false;		String extends_path;		Vector<IdentifierNode *> extends; // List for indexing: extends A.B.C		DataType base_type;		String fqcn; // Fully-qualified class name. Identifies uniquely any class in the project.#ifdef TOOLS_ENABLED		ClassDocData doc_data;		// EnumValue docs are parsed after itself, so we need a method to add/modify the doc property later.		void set_enum_value_doc_data(const StringName &p_name, const MemberDocData &p_doc_data) {			ERR_FAIL_INDEX(members_indices[p_name], members.size());			members.write[members_indices[p_name]].enum_value.doc_data = p_doc_data;		}#endif // TOOLS_ENABLED		bool resolved_interface = false;		bool resolved_body = false;		StringName get_global_name() const {			return (outer == nullptr && identifier != nullptr) ? identifier->name : StringName();		}		Member get_member(const StringName &p_name) const {			return members[members_indices[p_name]];		}		bool has_member(const StringName &p_name) const {			return members_indices.has(p_name);		}		bool has_function(const StringName &p_name) const {			return has_member(p_name) && members[members_indices[p_name]].type == Member::FUNCTION;		}		template <typename T>		void add_member(T *p_member_node) {			members_indices[p_member_node->identifier->name] = members.size();			members.push_back(Member(p_member_node));		}		void add_member(const EnumNode::Value &p_enum_value) {			members_indices[p_enum_value.identifier->name] = members.size();			members.push_back(Member(p_enum_value));		}		void add_member_group(AnnotationNode *p_annotation_node) {			// Avoid name conflict. See GH-78252.			StringName name = vformat("@group_%d_%s", members.size(), p_annotation_node->export_info.name);			members_indices[name] = members.size();			members.push_back(Member(p_annotation_node));		}		ClassNode() {			type = CLASS;		}	};	struct ConstantNode : public AssignableNode {#ifdef TOOLS_ENABLED		MemberDocData doc_data;#endif // TOOLS_ENABLED		ConstantNode() {			type = CONSTANT;		}	};	struct ContinueNode : public Node {		ContinueNode() {			type = CONTINUE;		}	};	struct DictionaryNode : public ExpressionNode {		struct Pair {			ExpressionNode *key = nullptr;			ExpressionNode *value = nullptr;		};		Vector<Pair> elements;		enum Style {			LUA_TABLE,			PYTHON_DICT,		};		Style style = PYTHON_DICT;		DictionaryNode() {			type = DICTIONARY;		}	};	struct ForNode : public Node {		IdentifierNode *variable = nullptr;		TypeNode *datatype_specifier = nullptr;		bool use_conversion_assign = false;		ExpressionNode *list = nullptr;		SuiteNode *loop = nullptr;		ForNode() {			type = FOR;		}	};	struct FunctionNode : public Node {		IdentifierNode *identifier = nullptr;		Vector<ParameterNode *> parameters;		HashMap<StringName, int> parameters_indices;		ParameterNode *rest_parameter = nullptr;		TypeNode *return_type = nullptr;		SuiteNode *body = nullptr;		bool is_abstract = false;		bool is_static = false; // For lambdas it's determined in the analyzer.		bool is_coroutine = false;		Variant rpc_config;		MethodInfo info;		LambdaNode *source_lambda = nullptr;		Vector<Variant> default_arg_values;#ifdef TOOLS_ENABLED		MemberDocData doc_data;		int min_local_doc_line = 0;		String signature; // For autocompletion.#endif // TOOLS_ENABLED		bool resolved_signature = false;		bool resolved_body = false;		_FORCE_INLINE_ bool is_vararg() const { return rest_parameter != nullptr; }		FunctionNode() {			type = FUNCTION;		}	};	struct GetNodeNode : public ExpressionNode {		String full_path;		bool use_dollar = true;		GetNodeNode() {			type = GET_NODE;		}	};	struct IdentifierNode : public ExpressionNode {		StringName name;		SuiteNode *suite = nullptr; // The block in which the identifier is used.		enum Source {			UNDEFINED_SOURCE,			FUNCTION_PARAMETER,			LOCAL_VARIABLE,			LOCAL_CONSTANT,			LOCAL_ITERATOR, // `for` loop iterator.			LOCAL_BIND, // Pattern bind.			MEMBER_VARIABLE,			MEMBER_CONSTANT,			MEMBER_FUNCTION,			MEMBER_SIGNAL,			MEMBER_CLASS,			INHERITED_VARIABLE,			STATIC_VARIABLE,			NATIVE_CLASS,		};		Source source = UNDEFINED_SOURCE;		union {			ParameterNode *parameter_source = nullptr;			IdentifierNode *bind_source;			VariableNode *variable_source;			ConstantNode *constant_source;			SignalNode *signal_source;			FunctionNode *function_source;		};		bool function_source_is_static = false; // For non-GDScript scripts.		FunctionNode *source_function = nullptr; // TODO: Rename to disambiguate `function_source`.		int usages = 0; // Useful for binds/iterator variable.		IdentifierNode() {			type = IDENTIFIER;		}	};	struct IfNode : public Node {		ExpressionNode *condition = nullptr;		SuiteNode *true_block = nullptr;		SuiteNode *false_block = nullptr;		IfNode() {			type = IF;		}	};	struct LambdaNode : public ExpressionNode {		FunctionNode *function = nullptr;		FunctionNode *parent_function = nullptr;		LambdaNode *parent_lambda = nullptr;		Vector<IdentifierNode *> captures;		HashMap<StringName, int> captures_indices;		bool use_self = false;		bool has_name() const {			return function && function->identifier;		}		LambdaNode() {			type = LAMBDA;		}	};	struct LiteralNode : public ExpressionNode {		Variant value;		LiteralNode() {			type = LITERAL;		}	};	struct MatchNode : public Node {		ExpressionNode *test = nullptr;		Vector<MatchBranchNode *> branches;		MatchNode() {			type = MATCH;		}	};	struct MatchBranchNode : public Node {		Vector<PatternNode *> patterns;		SuiteNode *block = nullptr;		bool has_wildcard = false;		SuiteNode *guard_body = nullptr;		MatchBranchNode() {			type = MATCH_BRANCH;		}	};	struct ParameterNode : public AssignableNode {		ParameterNode() {			type = PARAMETER;		}	};	struct PassNode : public Node {		PassNode() {			type = PASS;		}	};	struct PatternNode : public Node {		enum Type {			PT_LITERAL,			PT_EXPRESSION,			PT_BIND,			PT_ARRAY,			PT_DICTIONARY,			PT_REST,			PT_WILDCARD,		};		Type pattern_type = PT_LITERAL;		union {			LiteralNode *literal = nullptr;			IdentifierNode *bind;			ExpressionNode *expression;		};		Vector<PatternNode *> array;		bool rest_used = false; // For array/dict patterns.		struct Pair {			ExpressionNode *key = nullptr;			PatternNode *value_pattern = nullptr;		};		Vector<Pair> dictionary;		HashMap<StringName, IdentifierNode *> binds;		bool has_bind(const StringName &p_name);		IdentifierNode *get_bind(const StringName &p_name);		PatternNode() {			type = PATTERN;		}	};	struct PreloadNode : public ExpressionNode {		ExpressionNode *path = nullptr;		String resolved_path;		Ref<Resource> resource;		PreloadNode() {			type = PRELOAD;		}	};	struct ReturnNode : public Node {		ExpressionNode *return_value = nullptr;		bool void_return = false;		ReturnNode() {			type = RETURN;		}	};	struct SelfNode : public ExpressionNode {		ClassNode *current_class = nullptr;		SelfNode() {			type = SELF;		}	};	struct SignalNode : public Node {		IdentifierNode *identifier = nullptr;		Vector<ParameterNode *> parameters;		HashMap<StringName, int> parameters_indices;		MethodInfo method_info;#ifdef TOOLS_ENABLED		MemberDocData doc_data;#endif // TOOLS_ENABLED		int usages = 0;		SignalNode() {			type = SIGNAL;		}	};	struct SubscriptNode : public ExpressionNode {		ExpressionNode *base = nullptr;		union {			ExpressionNode *index = nullptr;			IdentifierNode *attribute;		};		bool is_attribute = false;		SubscriptNode() {			type = SUBSCRIPT;		}	};	struct SuiteNode : public Node {		SuiteNode *parent_block = nullptr;		Vector<Node *> statements;		struct Local {			enum Type {				UNDEFINED,				CONSTANT,				VARIABLE,				PARAMETER,				FOR_VARIABLE,				PATTERN_BIND,			};			Type type = UNDEFINED;			union {				ConstantNode *constant = nullptr;				VariableNode *variable;				ParameterNode *parameter;				IdentifierNode *bind;			};			StringName name;			FunctionNode *source_function = nullptr;			int start_line = 0, end_line = 0;			int start_column = 0, end_column = 0;			DataType get_datatype() const;			String get_name() const;			Local() {}			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;				start_column = p_constant->start_column;				end_column = p_constant->end_column;			}			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;				start_column = p_variable->start_column;				end_column = p_variable->end_column;			}			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;				start_column = p_parameter->start_column;				end_column = p_parameter->end_column;			}			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;				start_column = p_identifier->start_column;				end_column = p_identifier->end_column;			}		};		Local empty;		Vector<Local> locals;		HashMap<StringName, int> locals_indices;		FunctionNode *parent_function = nullptr;		IfNode *parent_if = nullptr;		bool has_return = false;		bool has_continue = false;		bool has_unreachable_code = false; // Just so warnings aren't given more than once per block.		bool is_in_loop = false; // The block is nested in a loop (directly or indirectly).		bool has_local(const StringName &p_name) const;		const Local &get_local(const StringName &p_name) const;		template <typename T>		void add_local(T *p_local, FunctionNode *p_source_function) {			locals_indices[p_local->identifier->name] = locals.size();			locals.push_back(Local(p_local, p_source_function));		}		void add_local(const Local &p_local) {			locals_indices[p_local.name] = locals.size();			locals.push_back(p_local);		}		SuiteNode() {			type = SUITE;		}	};	struct TernaryOpNode : public ExpressionNode {		// Only one ternary operation exists, so no abstraction here.		ExpressionNode *condition = nullptr;		ExpressionNode *true_expr = nullptr;		ExpressionNode *false_expr = nullptr;		TernaryOpNode() {			type = TERNARY_OPERATOR;		}	};	struct TypeNode : public Node {		Vector<IdentifierNode *> type_chain;		Vector<TypeNode *> container_types;		TypeNode *get_container_type_or_null(int p_index) const {			return p_index >= 0 && p_index < container_types.size() ? container_types[p_index] : nullptr;		}		TypeNode() {			type = TYPE;		}	};	struct TypeTestNode : public ExpressionNode {		ExpressionNode *operand = nullptr;		TypeNode *test_type = nullptr;		DataType test_datatype;		TypeTestNode() {			type = TYPE_TEST;		}	};	struct UnaryOpNode : public ExpressionNode {		enum OpType {			OP_POSITIVE,			OP_NEGATIVE,			OP_COMPLEMENT,			OP_LOGIC_NOT,		};		OpType operation = OP_POSITIVE;		Variant::Operator variant_op = Variant::OP_MAX;		ExpressionNode *operand = nullptr;		UnaryOpNode() {			type = UNARY_OPERATOR;		}	};	struct VariableNode : public AssignableNode {		enum PropertyStyle {			PROP_NONE,			PROP_INLINE,			PROP_SETGET,		};		PropertyStyle property = PROP_NONE;		union {			FunctionNode *setter = nullptr;			IdentifierNode *setter_pointer;		};		IdentifierNode *setter_parameter = nullptr;		union {			FunctionNode *getter = nullptr;			IdentifierNode *getter_pointer;		};		bool exported = false;		bool onready = false;		PropertyInfo export_info;		int assignments = 0;		bool is_static = false;#ifdef TOOLS_ENABLED		MemberDocData doc_data;#endif // TOOLS_ENABLED		VariableNode() {			type = VARIABLE;		}	};	struct WhileNode : public Node {		ExpressionNode *condition = nullptr;		SuiteNode *loop = nullptr;		WhileNode() {			type = WHILE;		}	};	enum CompletionType {		COMPLETION_NONE,		COMPLETION_ANNOTATION, // Annotation (following @).		COMPLETION_ANNOTATION_ARGUMENTS, // Annotation arguments hint.		COMPLETION_ASSIGN, // Assignment based on type (e.g. enum values).		COMPLETION_ATTRIBUTE, // After id.| to look for members.		COMPLETION_ATTRIBUTE_METHOD, // After id.| to look for methods.		COMPLETION_BUILT_IN_TYPE_CONSTANT_OR_STATIC_METHOD, // Constants inside a built-in type (e.g. Color.BLUE) or static methods (e.g. Color.html).		COMPLETION_CALL_ARGUMENTS, // Complete with nodes, input actions, enum values (or usual expressions).		// TODO: COMPLETION_DECLARATION, // Potential declaration (var, const, func).		COMPLETION_GET_NODE, // Get node with $ notation.		COMPLETION_IDENTIFIER, // List available identifiers in scope.		COMPLETION_INHERIT_TYPE, // Type after extends. Exclude non-viable types (built-ins, enums, void). Includes subtypes using the argument index.		COMPLETION_METHOD, // List available methods in scope.		COMPLETION_OVERRIDE_METHOD, // Override implementation, also for native virtuals.		COMPLETION_PROPERTY_DECLARATION, // Property declaration (get, set).		COMPLETION_PROPERTY_DECLARATION_OR_TYPE, // Property declaration (get, set) or a type hint.		COMPLETION_PROPERTY_METHOD, // Property setter or getter (list available methods).		COMPLETION_RESOURCE_PATH, // For load/preload.		COMPLETION_SUBSCRIPT, // Inside id[|].		COMPLETION_SUPER, // super(), used for lookup.		COMPLETION_SUPER_METHOD, // After super.		COMPLETION_TYPE_ATTRIBUTE, // Attribute in type name (Type.|).		COMPLETION_TYPE_NAME, // Name of type (after :).		COMPLETION_TYPE_NAME_OR_VOID, // Same as TYPE_NAME, but allows void (in function return type).	};	struct CompletionCall {		Node *call = nullptr;		int argument = -1;	};	struct CompletionContext {		CompletionType type = COMPLETION_NONE;		ClassNode *current_class = nullptr;		FunctionNode *current_function = nullptr;		SuiteNode *current_suite = nullptr;		int current_line = -1;		union {			int current_argument = -1;			int type_chain_index;		};		Variant::Type builtin_type = Variant::VARIANT_MAX;		Node *node = nullptr;		Object *base = nullptr;		GDScriptParser *parser = nullptr;		CompletionCall call;	};private:	friend class GDScriptAnalyzer;	friend class GDScriptParserRef;	bool _is_tool = false;	String script_path;	bool for_completion = false;	bool parse_body = true;	bool panic_mode = false;	bool can_break = false;	bool can_continue = false;	List<bool> multiline_stack;	HashMap<String, Ref<GDScriptParserRef>> depended_parsers;	ClassNode *head = nullptr;	Node *list = nullptr;	List<ParserError> errors;#ifdef DEBUG_ENABLED	struct PendingWarning {		const Node *source = nullptr;		GDScriptWarning::Code code = GDScriptWarning::WARNING_MAX;		bool treated_as_error = false;		Vector<String> symbols;	};	bool is_ignoring_warnings = false;	List<GDScriptWarning> warnings;	List<PendingWarning> pending_warnings;	HashSet<int> warning_ignored_lines[GDScriptWarning::WARNING_MAX];	int warning_ignore_start_lines[GDScriptWarning::WARNING_MAX];	HashSet<int> unsafe_lines;#endif	GDScriptTokenizer *tokenizer = nullptr;	GDScriptTokenizer::Token previous;	GDScriptTokenizer::Token current;	ClassNode *current_class = nullptr;	FunctionNode *current_function = nullptr;	LambdaNode *current_lambda = nullptr;	SuiteNode *current_suite = nullptr;	CompletionContext completion_context;	List<CompletionCall> completion_call_stack;	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)(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	struct AnnotationInfo {		enum TargetKind {			NONE = 0,			SCRIPT = 1 << 0,			CLASS = 1 << 1,			VARIABLE = 1 << 2,			CONSTANT = 1 << 3,			SIGNAL = 1 << 4,			FUNCTION = 1 << 5,			STATEMENT = 1 << 6,			STANDALONE = 1 << 7,			CLASS_LEVEL = CLASS | VARIABLE | CONSTANT | SIGNAL | FUNCTION,		};		uint32_t target_kind = 0; // Flags.		AnnotationAction apply = nullptr;		MethodInfo info;	};	static HashMap<StringName, AnnotationInfo> valid_annotations;	List<AnnotationNode *> annotation_stack;	typedef ExpressionNode *(GDScriptParser::*ParseFunction)(ExpressionNode *p_previous_operand, bool p_can_assign);	// Higher value means higher precedence (i.e. is evaluated first).	enum Precedence {		PREC_NONE,		PREC_ASSIGNMENT,		PREC_CAST,		PREC_TERNARY,		PREC_LOGIC_OR,		PREC_LOGIC_AND,		PREC_LOGIC_NOT,		PREC_CONTENT_TEST,		PREC_COMPARISON,		PREC_BIT_OR,		PREC_BIT_XOR,		PREC_BIT_AND,		PREC_BIT_SHIFT,		PREC_ADDITION_SUBTRACTION,		PREC_FACTOR,		PREC_SIGN,		PREC_BIT_NOT,		PREC_POWER,		PREC_TYPE_TEST,		PREC_AWAIT,		PREC_CALL,		PREC_ATTRIBUTE,		PREC_SUBSCRIPT,		PREC_PRIMARY,	};	struct ParseRule {		ParseFunction prefix = nullptr;		ParseFunction infix = nullptr;		Precedence precedence = PREC_NONE;	};	static ParseRule *get_rule(GDScriptTokenizer::Token::Type p_token_type);	List<Node *> nodes_in_progress;	void complete_extents(Node *p_node);	void update_extents(Node *p_node);	void reset_extents(Node *p_node, GDScriptTokenizer::Token p_token);	void reset_extents(Node *p_node, Node *p_from);	template <typename T>	T *alloc_node() {		T *node = memnew(T);		node->next = list;		list = node;		reset_extents(node, previous);		nodes_in_progress.push_back(node);		return node;	}	// Allocates a node for patching up the parse tree when an error occurred.	// Such nodes don't track their extents as they don't relate to actual tokens.	template <typename T>	T *alloc_recovery_node() {		T *node = memnew(T);		node->next = list;		list = node;		return node;	}	SuiteNode *alloc_recovery_suite() {		SuiteNode *suite = alloc_recovery_node<SuiteNode>();		suite->parent_block = current_suite;		suite->parent_function = current_function;		suite->is_in_loop = current_suite->is_in_loop;		return suite;	}	void clear();	void push_error(const String &p_message, const Node *p_origin = nullptr);#ifdef DEBUG_ENABLED	void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols);	template <typename... Symbols>	void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Symbols &...p_symbols) {		push_warning(p_source, p_code, Vector<String>{ p_symbols... });	}	void apply_pending_warnings();#endif	// Setting p_force to false will prevent the completion context from being update if a context was already set before.	// This should only be done when we push context before we consumed any tokens for the corresponding structure.	// See parse_precedence for an example.	void make_completion_context(CompletionType p_type, Node *p_node, int p_argument = -1, bool p_force = true);	void make_completion_context(CompletionType p_type, Variant::Type p_builtin_type, bool p_force = true);	// In some cases it might become necessary to alter the completion context after parsing a subexpression.	// For example to not override COMPLETE_CALL_ARGUMENTS with COMPLETION_NONE from string literals.	void override_completion_context(const Node *p_for_node, CompletionType p_type, Node *p_node, int p_argument = -1);	void push_completion_call(Node *p_call);	void pop_completion_call();	void set_last_completion_call_arg(int p_argument);	GDScriptTokenizer::Token advance();	bool match(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() 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);	void pop_multiline();	// Main blocks.	void parse_program();	ClassNode *parse_class(bool p_is_static);	void parse_class_name();	void parse_extends();	void parse_class_body(bool p_is_multiline);	template <typename T>	void parse_class_member(T *(GDScriptParser::*p_parse_function)(bool), AnnotationInfo::TargetKind p_target, const String &p_member_kind, bool p_is_static = false);	SignalNode *parse_signal(bool p_is_static);	EnumNode *parse_enum(bool p_is_static);	ParameterNode *parse_parameter();	FunctionNode *parse_function(bool p_is_static);	bool parse_function_signature(FunctionNode *p_function, SuiteNode *p_body, const String &p_type, int p_signature_start);	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);	static bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments = Vector<Variant>(), bool p_is_vararg = false);	bool validate_annotation_arguments(AnnotationNode *p_annotation);	void clear_unused_annotations();	bool tool_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool icon_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool static_unload_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool abstract_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool onready_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	template <PropertyHint t_hint, Variant::Type t_type>	bool export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	template <PropertyUsageFlags t_usage>	bool export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool warning_ignore_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool warning_ignore_region_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	bool rpc_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);	// Statements.	Node *parse_statement();	VariableNode *parse_variable(bool p_is_static);	VariableNode *parse_variable(bool p_is_static, bool p_allow_property);	VariableNode *parse_property(VariableNode *p_variable, bool p_need_indent);	void parse_property_getter(VariableNode *p_variable);	void parse_property_setter(VariableNode *p_variable);	ConstantNode *parse_constant(bool p_is_static);	AssertNode *parse_assert();	BreakNode *parse_break();	ContinueNode *parse_continue();	ForNode *parse_for();	IfNode *parse_if(const String &p_token = "if");	MatchNode *parse_match();	MatchBranchNode *parse_match_branch();	PatternNode *parse_match_pattern(PatternNode *p_root_pattern = nullptr);	WhileNode *parse_while();	// Expressions.	ExpressionNode *parse_expression(bool p_can_assign, bool p_stop_on_assign = false);	ExpressionNode *parse_precedence(Precedence p_precedence, bool p_can_assign, bool p_stop_on_assign = false);	ExpressionNode *parse_literal(ExpressionNode *p_previous_operand, bool p_can_assign);	LiteralNode *parse_literal();	ExpressionNode *parse_self(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_identifier(ExpressionNode *p_previous_operand, bool p_can_assign);	IdentifierNode *parse_identifier();	ExpressionNode *parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_unary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_assignment(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_array(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_dictionary(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_call(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_get_node(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_preload(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_grouping(ExpressionNode *p_previous_operand, bool p_can_assign);	ExpressionNode *parse_cast(ExpressionNode *p_previous_operand, bool p_can_assign);	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_type_test(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	int max_script_doc_line = INT_MAX;	int min_member_doc_line = 1;	bool has_comment(int p_line, bool p_must_be_doc = false);	MemberDocData parse_doc_comment(int p_line, bool p_single_line = false);	ClassDocData parse_class_doc_comment(int p_line, bool p_single_line = false);#endif // TOOLS_ENABLEDpublic:	Error parse(const String &p_source_code, const String &p_script_path, bool p_for_completion, bool p_parse_body = true);	Error parse_binary(const Vector<uint8_t> &p_binary, const String &p_script_path);	ClassNode *get_tree() const { return head; }	bool is_tool() const { return _is_tool; }	Ref<GDScriptParserRef> get_depended_parser_for(const String &p_path);	const HashMap<String, Ref<GDScriptParserRef>> &get_depended_parsers();	ClassNode *find_class(const String &p_qualified_name) const;	bool has_class(const GDScriptParser::ClassNode *p_class) const;	static Variant::Type get_builtin_type(const StringName &p_type); // Excluding `Variant::NIL` and `Variant::OBJECT`.	CompletionContext get_completion_context() const { return completion_context; }	void get_annotation_list(List<MethodInfo> *r_annotations) const;	bool annotation_exists(const String &p_annotation_name) const;	const List<ParserError> &get_errors() const { return errors; }	const List<String> get_dependencies() const {		// TODO: Keep track of deps.		return List<String>();	}#ifdef DEBUG_ENABLED	const List<GDScriptWarning> &get_warnings() const { return warnings; }	const HashSet<int> &get_unsafe_lines() const { return unsafe_lines; }	int get_last_line_number() const { return current.end_line; }#endif#ifdef TOOLS_ENABLED	static HashMap<String, String> theme_color_names;	HashMap<int, GDScriptTokenizer::CommentData> comment_data;#endif // TOOLS_ENABLED	GDScriptParser();	~GDScriptParser();#ifdef DEBUG_ENABLED	class TreePrinter {		int indent_level = 0;		String indent;		StringBuilder printed;		bool pending_indent = false;		void increase_indent();		void decrease_indent();		void push_line(const String &p_line = String());		void push_text(const String &p_text);		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);		void print_await(AwaitNode *p_await);		void print_binary_op(BinaryOpNode *p_binary_op);		void print_call(CallNode *p_call);		void print_cast(CastNode *p_cast);		void print_class(ClassNode *p_class);		void print_constant(ConstantNode *p_constant);		void print_dictionary(DictionaryNode *p_dictionary);		void print_expression(ExpressionNode *p_expression);		void print_enum(EnumNode *p_enum);		void print_for(ForNode *p_for);		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);		void print_match_pattern(PatternNode *p_match_pattern);		void print_parameter(ParameterNode *p_parameter);		void print_preload(PreloadNode *p_preload);		void print_return(ReturnNode *p_return);		void print_self(SelfNode *p_self);		void print_signal(SignalNode *p_signal);		void print_statement(Node *p_statement);		void print_subscript(SubscriptNode *p_subscript);		void print_suite(SuiteNode *p_suite);		void print_ternary_op(TernaryOpNode *p_ternary_op);		void print_type(TypeNode *p_type);		void print_type_test(TypeTestNode *p_type_test);		void print_unary_op(UnaryOpNode *p_unary_op);		void print_variable(VariableNode *p_variable);		void print_while(WhileNode *p_while);	public:		void print_tree(const GDScriptParser &p_parser);	};#endif // DEBUG_ENABLED	static void cleanup();};
 |