Path: blob/master/modules/gdscript/gdscript_parser.h
10277 views
/**************************************************************************/1/* gdscript_parser.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "gdscript_cache.h"33#include "gdscript_tokenizer.h"3435#ifdef DEBUG_ENABLED36#include "gdscript_warning.h"37#endif3839#include "core/io/resource.h"40#include "core/object/ref_counted.h"41#include "core/object/script_language.h"42#include "core/string/string_name.h"43#include "core/string/ustring.h"44#include "core/templates/hash_map.h"45#include "core/templates/list.h"46#include "core/templates/vector.h"47#include "core/variant/variant.h"4849#ifdef DEBUG_ENABLED50#include "core/string/string_builder.h"51#endif5253class GDScriptParser {54struct AnnotationInfo;5556public:57// Forward-declare all parser nodes, to avoid ordering issues.58struct AnnotationNode;59struct ArrayNode;60struct AssertNode;61struct AssignableNode;62struct AssignmentNode;63struct AwaitNode;64struct BinaryOpNode;65struct BreakNode;66struct BreakpointNode;67struct CallNode;68struct CastNode;69struct ClassNode;70struct ConstantNode;71struct ContinueNode;72struct DictionaryNode;73struct EnumNode;74struct ExpressionNode;75struct ForNode;76struct FunctionNode;77struct GetNodeNode;78struct IdentifierNode;79struct IfNode;80struct LambdaNode;81struct LiteralNode;82struct MatchNode;83struct MatchBranchNode;84struct ParameterNode;85struct PassNode;86struct PatternNode;87struct PreloadNode;88struct ReturnNode;89struct SelfNode;90struct SignalNode;91struct SubscriptNode;92struct SuiteNode;93struct TernaryOpNode;94struct TypeNode;95struct TypeTestNode;96struct UnaryOpNode;97struct VariableNode;98struct WhileNode;99100class DataType {101public:102Vector<DataType> container_element_types;103104enum Kind {105BUILTIN,106NATIVE,107SCRIPT,108CLASS, // GDScript.109ENUM, // Enumeration.110VARIANT, // Can be any type.111RESOLVING, // Currently resolving.112UNRESOLVED,113};114Kind kind = UNRESOLVED;115116enum TypeSource {117UNDETECTED, // Can be any type.118INFERRED, // Has inferred type, but still dynamic.119ANNOTATED_EXPLICIT, // Has a specific type annotated.120ANNOTATED_INFERRED, // Has a static type but comes from the assigned value.121};122TypeSource type_source = UNDETECTED;123124bool is_constant = false;125bool is_read_only = false;126bool is_meta_type = false;127bool is_pseudo_type = false; // For global names that can't be used standalone.128bool is_coroutine = false; // For function calls.129130Variant::Type builtin_type = Variant::NIL;131StringName native_type;132StringName enum_type; // Enum name or the value name in an enum.133Ref<Script> script_type;134String script_path;135ClassNode *class_type = nullptr;136137MethodInfo method_info; // For callable/signals.138HashMap<StringName, int64_t> enum_values; // For enums.139140_FORCE_INLINE_ bool is_set() const { return kind != RESOLVING && kind != UNRESOLVED; }141_FORCE_INLINE_ bool is_resolving() const { return kind == RESOLVING; }142_FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }143_FORCE_INLINE_ bool is_variant() const { return kind == VARIANT || kind == RESOLVING || kind == UNRESOLVED; }144_FORCE_INLINE_ bool is_hard_type() const { return type_source > INFERRED; }145146String to_string() const;147_FORCE_INLINE_ String to_string_strict() const { return is_hard_type() ? to_string() : "Variant"; }148PropertyInfo to_property_info(const String &p_name) const;149150_FORCE_INLINE_ static DataType get_variant_type() { // Default DataType for container elements.151DataType datatype;152datatype.kind = VARIANT;153datatype.type_source = INFERRED;154return datatype;155}156157_FORCE_INLINE_ void set_container_element_type(int p_index, const DataType &p_type) {158ERR_FAIL_COND(p_index < 0);159while (p_index >= container_element_types.size()) {160container_element_types.push_back(get_variant_type());161}162container_element_types.write[p_index] = DataType(p_type);163}164165_FORCE_INLINE_ int get_container_element_type_count() const {166return container_element_types.size();167}168169_FORCE_INLINE_ DataType get_container_element_type(int p_index) const {170ERR_FAIL_INDEX_V(p_index, container_element_types.size(), get_variant_type());171return container_element_types[p_index];172}173174_FORCE_INLINE_ DataType get_container_element_type_or_variant(int p_index) const {175if (p_index < 0 || p_index >= container_element_types.size()) {176return get_variant_type();177}178return container_element_types[p_index];179}180181_FORCE_INLINE_ bool has_container_element_type(int p_index) const {182return p_index >= 0 && p_index < container_element_types.size();183}184185_FORCE_INLINE_ bool has_container_element_types() const {186return !container_element_types.is_empty();187}188189bool is_typed_container_type() const;190191GDScriptParser::DataType get_typed_container_type() const;192193bool can_reference(const DataType &p_other) const;194195bool operator==(const DataType &p_other) const {196if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) {197return true; // Can be considered equal for parsing purposes.198}199200if (type_source == INFERRED || p_other.type_source == INFERRED) {201return true; // Can be considered equal for parsing purposes.202}203204if (kind != p_other.kind) {205return false;206}207208switch (kind) {209case VARIANT:210return true; // All variants are the same.211case BUILTIN:212return builtin_type == p_other.builtin_type;213case NATIVE:214case ENUM: // Enums use native_type to identify the enum and its base class.215return native_type == p_other.native_type;216case SCRIPT:217return script_type == p_other.script_type;218case CLASS:219return class_type == p_other.class_type || class_type->fqcn == p_other.class_type->fqcn;220case RESOLVING:221case UNRESOLVED:222break;223}224225return false;226}227228bool operator!=(const DataType &p_other) const {229return !(*this == p_other);230}231232void operator=(const DataType &p_other) {233kind = p_other.kind;234type_source = p_other.type_source;235is_read_only = p_other.is_read_only;236is_constant = p_other.is_constant;237is_meta_type = p_other.is_meta_type;238is_pseudo_type = p_other.is_pseudo_type;239is_coroutine = p_other.is_coroutine;240builtin_type = p_other.builtin_type;241native_type = p_other.native_type;242enum_type = p_other.enum_type;243script_type = p_other.script_type;244script_path = p_other.script_path;245class_type = p_other.class_type;246method_info = p_other.method_info;247enum_values = p_other.enum_values;248container_element_types = p_other.container_element_types;249}250251DataType() = default;252253DataType(const DataType &p_other) {254*this = p_other;255}256257~DataType() {}258};259260struct ParserError {261// TODO: Do I really need a "type"?262// enum Type {263// NO_ERROR,264// EMPTY_FILE,265// CLASS_NAME_USED_TWICE,266// EXTENDS_USED_TWICE,267// EXPECTED_END_STATEMENT,268// };269// Type type = NO_ERROR;270String message;271int line = 0, column = 0;272};273274#ifdef TOOLS_ENABLED275struct ClassDocData {276String brief;277String description;278Vector<Pair<String, String>> tutorials;279bool is_deprecated = false;280String deprecated_message;281bool is_experimental = false;282String experimental_message;283};284285struct MemberDocData {286String description;287bool is_deprecated = false;288String deprecated_message;289bool is_experimental = false;290String experimental_message;291};292#endif // TOOLS_ENABLED293294struct Node {295enum Type {296NONE,297ANNOTATION,298ARRAY,299ASSERT,300ASSIGNMENT,301AWAIT,302BINARY_OPERATOR,303BREAK,304BREAKPOINT,305CALL,306CAST,307CLASS,308CONSTANT,309CONTINUE,310DICTIONARY,311ENUM,312FOR,313FUNCTION,314GET_NODE,315IDENTIFIER,316IF,317LAMBDA,318LITERAL,319MATCH,320MATCH_BRANCH,321PARAMETER,322PASS,323PATTERN,324PRELOAD,325RETURN,326SELF,327SIGNAL,328SUBSCRIPT,329SUITE,330TERNARY_OPERATOR,331TYPE,332TYPE_TEST,333UNARY_OPERATOR,334VARIABLE,335WHILE,336};337338Type type = NONE;339int start_line = 0, end_line = 0;340int start_column = 0, end_column = 0;341Node *next = nullptr;342List<AnnotationNode *> annotations;343344DataType datatype;345346virtual DataType get_datatype() const { return datatype; }347virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }348349virtual bool is_expression() const { return false; }350351virtual ~Node() {}352};353354struct ExpressionNode : public Node {355// Base type for all expression kinds.356bool reduced = false;357bool is_constant = false;358Variant reduced_value;359360virtual bool is_expression() const override { return true; }361virtual ~ExpressionNode() {}362363protected:364ExpressionNode() {}365};366367struct AnnotationNode : public Node {368StringName name;369Vector<ExpressionNode *> arguments;370Vector<Variant> resolved_arguments;371372/** Information of the annotation. Might be null for unknown annotations. */373AnnotationInfo *info = nullptr;374PropertyInfo export_info;375bool is_resolved = false;376bool is_applied = false;377378bool apply(GDScriptParser *p_this, Node *p_target, ClassNode *p_class);379bool applies_to(uint32_t p_target_kinds) const;380381AnnotationNode() {382type = ANNOTATION;383}384};385386struct ArrayNode : public ExpressionNode {387Vector<ExpressionNode *> elements;388389ArrayNode() {390type = ARRAY;391}392};393394struct AssertNode : public Node {395ExpressionNode *condition = nullptr;396ExpressionNode *message = nullptr;397398AssertNode() {399type = ASSERT;400}401};402403struct AssignableNode : public Node {404IdentifierNode *identifier = nullptr;405ExpressionNode *initializer = nullptr;406TypeNode *datatype_specifier = nullptr;407bool infer_datatype = false;408bool use_conversion_assign = false;409int usages = 0;410411virtual ~AssignableNode() {}412413protected:414AssignableNode() {}415};416417struct AssignmentNode : public ExpressionNode {418// Assignment is not really an expression but it's easier to parse as if it were.419enum Operation {420OP_NONE,421OP_ADDITION,422OP_SUBTRACTION,423OP_MULTIPLICATION,424OP_DIVISION,425OP_MODULO,426OP_POWER,427OP_BIT_SHIFT_LEFT,428OP_BIT_SHIFT_RIGHT,429OP_BIT_AND,430OP_BIT_OR,431OP_BIT_XOR,432};433434Operation operation = OP_NONE;435Variant::Operator variant_op = Variant::OP_MAX;436ExpressionNode *assignee = nullptr;437ExpressionNode *assigned_value = nullptr;438bool use_conversion_assign = false;439440AssignmentNode() {441type = ASSIGNMENT;442}443};444445struct AwaitNode : public ExpressionNode {446ExpressionNode *to_await = nullptr;447448AwaitNode() {449type = AWAIT;450}451};452453struct BinaryOpNode : public ExpressionNode {454enum OpType {455OP_ADDITION,456OP_SUBTRACTION,457OP_MULTIPLICATION,458OP_DIVISION,459OP_MODULO,460OP_POWER,461OP_BIT_LEFT_SHIFT,462OP_BIT_RIGHT_SHIFT,463OP_BIT_AND,464OP_BIT_OR,465OP_BIT_XOR,466OP_LOGIC_AND,467OP_LOGIC_OR,468OP_CONTENT_TEST,469OP_COMP_EQUAL,470OP_COMP_NOT_EQUAL,471OP_COMP_LESS,472OP_COMP_LESS_EQUAL,473OP_COMP_GREATER,474OP_COMP_GREATER_EQUAL,475};476477OpType operation = OpType::OP_ADDITION;478Variant::Operator variant_op = Variant::OP_MAX;479ExpressionNode *left_operand = nullptr;480ExpressionNode *right_operand = nullptr;481482BinaryOpNode() {483type = BINARY_OPERATOR;484}485};486487struct BreakNode : public Node {488BreakNode() {489type = BREAK;490}491};492493struct BreakpointNode : public Node {494BreakpointNode() {495type = BREAKPOINT;496}497};498499struct CallNode : public ExpressionNode {500ExpressionNode *callee = nullptr;501Vector<ExpressionNode *> arguments;502StringName function_name;503bool is_super = false;504bool is_static = false;505506CallNode() {507type = CALL;508}509510Type get_callee_type() const {511if (callee == nullptr) {512return Type::NONE;513} else {514return callee->type;515}516}517};518519struct CastNode : public ExpressionNode {520ExpressionNode *operand = nullptr;521TypeNode *cast_type = nullptr;522523CastNode() {524type = CAST;525}526};527528struct EnumNode : public Node {529struct Value {530IdentifierNode *identifier = nullptr;531ExpressionNode *custom_value = nullptr;532EnumNode *parent_enum = nullptr;533int index = -1;534bool resolved = false;535int64_t value = 0;536int line = 0;537int start_column = 0;538int end_column = 0;539#ifdef TOOLS_ENABLED540MemberDocData doc_data;541#endif // TOOLS_ENABLED542};543544IdentifierNode *identifier = nullptr;545Vector<Value> values;546Variant dictionary;547#ifdef TOOLS_ENABLED548MemberDocData doc_data;549#endif // TOOLS_ENABLED550551EnumNode() {552type = ENUM;553}554};555556struct ClassNode : public Node {557struct Member {558enum Type {559UNDEFINED,560CLASS,561CONSTANT,562FUNCTION,563SIGNAL,564VARIABLE,565ENUM,566ENUM_VALUE, // For unnamed enums.567GROUP, // For member grouping.568};569570Type type = UNDEFINED;571572union {573ClassNode *m_class = nullptr;574ConstantNode *constant;575FunctionNode *function;576SignalNode *signal;577VariableNode *variable;578EnumNode *m_enum;579AnnotationNode *annotation;580};581EnumNode::Value enum_value;582583String get_name() const {584switch (type) {585case UNDEFINED:586return "<undefined member>";587case CLASS:588// All class-type members have an id.589return m_class->identifier->name;590case CONSTANT:591return constant->identifier->name;592case FUNCTION:593return function->identifier->name;594case SIGNAL:595return signal->identifier->name;596case VARIABLE:597return variable->identifier->name;598case ENUM:599// All enum-type members have an id.600return m_enum->identifier->name;601case ENUM_VALUE:602return enum_value.identifier->name;603case GROUP:604return annotation->export_info.name;605}606return "";607}608609String get_type_name() const {610switch (type) {611case UNDEFINED:612return "???";613case CLASS:614return "class";615case CONSTANT:616return "constant";617case FUNCTION:618return "function";619case SIGNAL:620return "signal";621case VARIABLE:622return "variable";623case ENUM:624return "enum";625case ENUM_VALUE:626return "enum value";627case GROUP:628return "group";629}630return "";631}632633int get_line() const {634switch (type) {635case CLASS:636return m_class->start_line;637case CONSTANT:638return constant->start_line;639case FUNCTION:640return function->start_line;641case VARIABLE:642return variable->start_line;643case ENUM_VALUE:644return enum_value.line;645case ENUM:646return m_enum->start_line;647case SIGNAL:648return signal->start_line;649case GROUP:650return annotation->start_line;651case UNDEFINED:652ERR_FAIL_V_MSG(-1, "Reaching undefined member type.");653}654ERR_FAIL_V_MSG(-1, "Reaching unhandled type.");655}656657DataType get_datatype() const {658switch (type) {659case CLASS:660return m_class->get_datatype();661case CONSTANT:662return constant->get_datatype();663case FUNCTION:664return function->get_datatype();665case VARIABLE:666return variable->get_datatype();667case ENUM:668return m_enum->get_datatype();669case ENUM_VALUE:670return enum_value.identifier->get_datatype();671case SIGNAL:672return signal->get_datatype();673case GROUP:674return DataType();675case UNDEFINED:676return DataType();677}678ERR_FAIL_V_MSG(DataType(), "Reaching unhandled type.");679}680681Node *get_source_node() const {682switch (type) {683case CLASS:684return m_class;685case CONSTANT:686return constant;687case FUNCTION:688return function;689case VARIABLE:690return variable;691case ENUM:692return m_enum;693case ENUM_VALUE:694return enum_value.identifier;695case SIGNAL:696return signal;697case GROUP:698return annotation;699case UNDEFINED:700return nullptr;701}702ERR_FAIL_V_MSG(nullptr, "Reaching unhandled type.");703}704705Member() {}706707Member(ClassNode *p_class) {708type = CLASS;709m_class = p_class;710}711Member(ConstantNode *p_constant) {712type = CONSTANT;713constant = p_constant;714}715Member(VariableNode *p_variable) {716type = VARIABLE;717variable = p_variable;718}719Member(SignalNode *p_signal) {720type = SIGNAL;721signal = p_signal;722}723Member(FunctionNode *p_function) {724type = FUNCTION;725function = p_function;726}727Member(EnumNode *p_enum) {728type = ENUM;729m_enum = p_enum;730}731Member(const EnumNode::Value &p_enum_value) {732type = ENUM_VALUE;733enum_value = p_enum_value;734}735Member(AnnotationNode *p_annotation) {736type = GROUP;737annotation = p_annotation;738}739};740741IdentifierNode *identifier = nullptr;742String icon_path;743String simplified_icon_path;744Vector<Member> members;745HashMap<StringName, int> members_indices;746ClassNode *outer = nullptr;747bool extends_used = false;748bool onready_used = false;749bool is_abstract = false;750bool has_static_data = false;751bool annotated_static_unload = false;752String extends_path;753Vector<IdentifierNode *> extends; // List for indexing: extends A.B.C754DataType base_type;755String fqcn; // Fully-qualified class name. Identifies uniquely any class in the project.756#ifdef TOOLS_ENABLED757ClassDocData doc_data;758759// EnumValue docs are parsed after itself, so we need a method to add/modify the doc property later.760void set_enum_value_doc_data(const StringName &p_name, const MemberDocData &p_doc_data) {761ERR_FAIL_INDEX(members_indices[p_name], members.size());762members.write[members_indices[p_name]].enum_value.doc_data = p_doc_data;763}764#endif // TOOLS_ENABLED765766bool resolved_interface = false;767bool resolved_body = false;768769StringName get_global_name() const {770return (outer == nullptr && identifier != nullptr) ? identifier->name : StringName();771}772773Member get_member(const StringName &p_name) const {774return members[members_indices[p_name]];775}776bool has_member(const StringName &p_name) const {777return members_indices.has(p_name);778}779bool has_function(const StringName &p_name) const {780return has_member(p_name) && members[members_indices[p_name]].type == Member::FUNCTION;781}782template <typename T>783void add_member(T *p_member_node) {784members_indices[p_member_node->identifier->name] = members.size();785members.push_back(Member(p_member_node));786}787void add_member(const EnumNode::Value &p_enum_value) {788members_indices[p_enum_value.identifier->name] = members.size();789members.push_back(Member(p_enum_value));790}791void add_member_group(AnnotationNode *p_annotation_node) {792// Avoid name conflict. See GH-78252.793StringName name = vformat("@group_%d_%s", members.size(), p_annotation_node->export_info.name);794members_indices[name] = members.size();795members.push_back(Member(p_annotation_node));796}797798ClassNode() {799type = CLASS;800}801};802803struct ConstantNode : public AssignableNode {804#ifdef TOOLS_ENABLED805MemberDocData doc_data;806#endif // TOOLS_ENABLED807808ConstantNode() {809type = CONSTANT;810}811};812813struct ContinueNode : public Node {814ContinueNode() {815type = CONTINUE;816}817};818819struct DictionaryNode : public ExpressionNode {820struct Pair {821ExpressionNode *key = nullptr;822ExpressionNode *value = nullptr;823};824Vector<Pair> elements;825826enum Style {827LUA_TABLE,828PYTHON_DICT,829};830Style style = PYTHON_DICT;831832DictionaryNode() {833type = DICTIONARY;834}835};836837struct ForNode : public Node {838IdentifierNode *variable = nullptr;839TypeNode *datatype_specifier = nullptr;840bool use_conversion_assign = false;841ExpressionNode *list = nullptr;842SuiteNode *loop = nullptr;843844ForNode() {845type = FOR;846}847};848849struct FunctionNode : public Node {850IdentifierNode *identifier = nullptr;851Vector<ParameterNode *> parameters;852HashMap<StringName, int> parameters_indices;853ParameterNode *rest_parameter = nullptr;854TypeNode *return_type = nullptr;855SuiteNode *body = nullptr;856bool is_abstract = false;857bool is_static = false; // For lambdas it's determined in the analyzer.858bool is_coroutine = false;859Variant rpc_config;860MethodInfo info;861LambdaNode *source_lambda = nullptr;862Vector<Variant> default_arg_values;863#ifdef TOOLS_ENABLED864MemberDocData doc_data;865int min_local_doc_line = 0;866String signature; // For autocompletion.867#endif // TOOLS_ENABLED868869bool resolved_signature = false;870bool resolved_body = false;871872_FORCE_INLINE_ bool is_vararg() const { return rest_parameter != nullptr; }873874FunctionNode() {875type = FUNCTION;876}877};878879struct GetNodeNode : public ExpressionNode {880String full_path;881bool use_dollar = true;882883GetNodeNode() {884type = GET_NODE;885}886};887888struct IdentifierNode : public ExpressionNode {889StringName name;890SuiteNode *suite = nullptr; // The block in which the identifier is used.891892enum Source {893UNDEFINED_SOURCE,894FUNCTION_PARAMETER,895LOCAL_VARIABLE,896LOCAL_CONSTANT,897LOCAL_ITERATOR, // `for` loop iterator.898LOCAL_BIND, // Pattern bind.899MEMBER_VARIABLE,900MEMBER_CONSTANT,901MEMBER_FUNCTION,902MEMBER_SIGNAL,903MEMBER_CLASS,904INHERITED_VARIABLE,905STATIC_VARIABLE,906NATIVE_CLASS,907};908Source source = UNDEFINED_SOURCE;909910union {911ParameterNode *parameter_source = nullptr;912IdentifierNode *bind_source;913VariableNode *variable_source;914ConstantNode *constant_source;915SignalNode *signal_source;916FunctionNode *function_source;917};918bool function_source_is_static = false; // For non-GDScript scripts.919920FunctionNode *source_function = nullptr; // TODO: Rename to disambiguate `function_source`.921922int usages = 0; // Useful for binds/iterator variable.923924IdentifierNode() {925type = IDENTIFIER;926}927};928929struct IfNode : public Node {930ExpressionNode *condition = nullptr;931SuiteNode *true_block = nullptr;932SuiteNode *false_block = nullptr;933934IfNode() {935type = IF;936}937};938939struct LambdaNode : public ExpressionNode {940FunctionNode *function = nullptr;941FunctionNode *parent_function = nullptr;942LambdaNode *parent_lambda = nullptr;943Vector<IdentifierNode *> captures;944HashMap<StringName, int> captures_indices;945bool use_self = false;946947bool has_name() const {948return function && function->identifier;949}950951LambdaNode() {952type = LAMBDA;953}954};955956struct LiteralNode : public ExpressionNode {957Variant value;958959LiteralNode() {960type = LITERAL;961}962};963964struct MatchNode : public Node {965ExpressionNode *test = nullptr;966Vector<MatchBranchNode *> branches;967968MatchNode() {969type = MATCH;970}971};972973struct MatchBranchNode : public Node {974Vector<PatternNode *> patterns;975SuiteNode *block = nullptr;976bool has_wildcard = false;977SuiteNode *guard_body = nullptr;978979MatchBranchNode() {980type = MATCH_BRANCH;981}982};983984struct ParameterNode : public AssignableNode {985ParameterNode() {986type = PARAMETER;987}988};989990struct PassNode : public Node {991PassNode() {992type = PASS;993}994};995996struct PatternNode : public Node {997enum Type {998PT_LITERAL,999PT_EXPRESSION,1000PT_BIND,1001PT_ARRAY,1002PT_DICTIONARY,1003PT_REST,1004PT_WILDCARD,1005};1006Type pattern_type = PT_LITERAL;10071008union {1009LiteralNode *literal = nullptr;1010IdentifierNode *bind;1011ExpressionNode *expression;1012};1013Vector<PatternNode *> array;1014bool rest_used = false; // For array/dict patterns.10151016struct Pair {1017ExpressionNode *key = nullptr;1018PatternNode *value_pattern = nullptr;1019};1020Vector<Pair> dictionary;10211022HashMap<StringName, IdentifierNode *> binds;10231024bool has_bind(const StringName &p_name);1025IdentifierNode *get_bind(const StringName &p_name);10261027PatternNode() {1028type = PATTERN;1029}1030};1031struct PreloadNode : public ExpressionNode {1032ExpressionNode *path = nullptr;1033String resolved_path;1034Ref<Resource> resource;10351036PreloadNode() {1037type = PRELOAD;1038}1039};10401041struct ReturnNode : public Node {1042ExpressionNode *return_value = nullptr;1043bool void_return = false;10441045ReturnNode() {1046type = RETURN;1047}1048};10491050struct SelfNode : public ExpressionNode {1051ClassNode *current_class = nullptr;10521053SelfNode() {1054type = SELF;1055}1056};10571058struct SignalNode : public Node {1059IdentifierNode *identifier = nullptr;1060Vector<ParameterNode *> parameters;1061HashMap<StringName, int> parameters_indices;1062MethodInfo method_info;1063#ifdef TOOLS_ENABLED1064MemberDocData doc_data;1065#endif // TOOLS_ENABLED10661067int usages = 0;10681069SignalNode() {1070type = SIGNAL;1071}1072};10731074struct SubscriptNode : public ExpressionNode {1075ExpressionNode *base = nullptr;1076union {1077ExpressionNode *index = nullptr;1078IdentifierNode *attribute;1079};10801081bool is_attribute = false;10821083SubscriptNode() {1084type = SUBSCRIPT;1085}1086};10871088struct SuiteNode : public Node {1089SuiteNode *parent_block = nullptr;1090Vector<Node *> statements;1091struct Local {1092enum Type {1093UNDEFINED,1094CONSTANT,1095VARIABLE,1096PARAMETER,1097FOR_VARIABLE,1098PATTERN_BIND,1099};1100Type type = UNDEFINED;1101union {1102ConstantNode *constant = nullptr;1103VariableNode *variable;1104ParameterNode *parameter;1105IdentifierNode *bind;1106};1107StringName name;1108FunctionNode *source_function = nullptr;11091110int start_line = 0, end_line = 0;1111int start_column = 0, end_column = 0;11121113DataType get_datatype() const;1114String get_name() const;11151116Local() {}1117Local(ConstantNode *p_constant, FunctionNode *p_source_function) {1118type = CONSTANT;1119constant = p_constant;1120name = p_constant->identifier->name;1121source_function = p_source_function;11221123start_line = p_constant->start_line;1124end_line = p_constant->end_line;1125start_column = p_constant->start_column;1126end_column = p_constant->end_column;1127}1128Local(VariableNode *p_variable, FunctionNode *p_source_function) {1129type = VARIABLE;1130variable = p_variable;1131name = p_variable->identifier->name;1132source_function = p_source_function;11331134start_line = p_variable->start_line;1135end_line = p_variable->end_line;1136start_column = p_variable->start_column;1137end_column = p_variable->end_column;1138}1139Local(ParameterNode *p_parameter, FunctionNode *p_source_function) {1140type = PARAMETER;1141parameter = p_parameter;1142name = p_parameter->identifier->name;1143source_function = p_source_function;11441145start_line = p_parameter->start_line;1146end_line = p_parameter->end_line;1147start_column = p_parameter->start_column;1148end_column = p_parameter->end_column;1149}1150Local(IdentifierNode *p_identifier, FunctionNode *p_source_function) {1151type = FOR_VARIABLE;1152bind = p_identifier;1153name = p_identifier->name;1154source_function = p_source_function;11551156start_line = p_identifier->start_line;1157end_line = p_identifier->end_line;1158start_column = p_identifier->start_column;1159end_column = p_identifier->end_column;1160}1161};1162Local empty;1163Vector<Local> locals;1164HashMap<StringName, int> locals_indices;11651166FunctionNode *parent_function = nullptr;1167IfNode *parent_if = nullptr;11681169bool has_return = false;1170bool has_continue = false;1171bool has_unreachable_code = false; // Just so warnings aren't given more than once per block.1172bool is_in_loop = false; // The block is nested in a loop (directly or indirectly).11731174bool has_local(const StringName &p_name) const;1175const Local &get_local(const StringName &p_name) const;1176template <typename T>1177void add_local(T *p_local, FunctionNode *p_source_function) {1178locals_indices[p_local->identifier->name] = locals.size();1179locals.push_back(Local(p_local, p_source_function));1180}1181void add_local(const Local &p_local) {1182locals_indices[p_local.name] = locals.size();1183locals.push_back(p_local);1184}11851186SuiteNode() {1187type = SUITE;1188}1189};11901191struct TernaryOpNode : public ExpressionNode {1192// Only one ternary operation exists, so no abstraction here.1193ExpressionNode *condition = nullptr;1194ExpressionNode *true_expr = nullptr;1195ExpressionNode *false_expr = nullptr;11961197TernaryOpNode() {1198type = TERNARY_OPERATOR;1199}1200};12011202struct TypeNode : public Node {1203Vector<IdentifierNode *> type_chain;1204Vector<TypeNode *> container_types;12051206TypeNode *get_container_type_or_null(int p_index) const {1207return p_index >= 0 && p_index < container_types.size() ? container_types[p_index] : nullptr;1208}12091210TypeNode() {1211type = TYPE;1212}1213};12141215struct TypeTestNode : public ExpressionNode {1216ExpressionNode *operand = nullptr;1217TypeNode *test_type = nullptr;1218DataType test_datatype;12191220TypeTestNode() {1221type = TYPE_TEST;1222}1223};12241225struct UnaryOpNode : public ExpressionNode {1226enum OpType {1227OP_POSITIVE,1228OP_NEGATIVE,1229OP_COMPLEMENT,1230OP_LOGIC_NOT,1231};12321233OpType operation = OP_POSITIVE;1234Variant::Operator variant_op = Variant::OP_MAX;1235ExpressionNode *operand = nullptr;12361237UnaryOpNode() {1238type = UNARY_OPERATOR;1239}1240};12411242struct VariableNode : public AssignableNode {1243enum PropertyStyle {1244PROP_NONE,1245PROP_INLINE,1246PROP_SETGET,1247};12481249PropertyStyle property = PROP_NONE;1250union {1251FunctionNode *setter = nullptr;1252IdentifierNode *setter_pointer;1253};1254IdentifierNode *setter_parameter = nullptr;1255union {1256FunctionNode *getter = nullptr;1257IdentifierNode *getter_pointer;1258};12591260bool exported = false;1261bool onready = false;1262PropertyInfo export_info;1263int assignments = 0;1264bool is_static = false;1265#ifdef TOOLS_ENABLED1266MemberDocData doc_data;1267#endif // TOOLS_ENABLED12681269VariableNode() {1270type = VARIABLE;1271}1272};12731274struct WhileNode : public Node {1275ExpressionNode *condition = nullptr;1276SuiteNode *loop = nullptr;12771278WhileNode() {1279type = WHILE;1280}1281};12821283enum CompletionType {1284COMPLETION_NONE,1285COMPLETION_ANNOTATION, // Annotation (following @).1286COMPLETION_ANNOTATION_ARGUMENTS, // Annotation arguments hint.1287COMPLETION_ASSIGN, // Assignment based on type (e.g. enum values).1288COMPLETION_ATTRIBUTE, // After id.| to look for members.1289COMPLETION_ATTRIBUTE_METHOD, // After id.| to look for methods.1290COMPLETION_BUILT_IN_TYPE_CONSTANT_OR_STATIC_METHOD, // Constants inside a built-in type (e.g. Color.BLUE) or static methods (e.g. Color.html).1291COMPLETION_CALL_ARGUMENTS, // Complete with nodes, input actions, enum values (or usual expressions).1292// TODO: COMPLETION_DECLARATION, // Potential declaration (var, const, func).1293COMPLETION_GET_NODE, // Get node with $ notation.1294COMPLETION_IDENTIFIER, // List available identifiers in scope.1295COMPLETION_INHERIT_TYPE, // Type after extends. Exclude non-viable types (built-ins, enums, void). Includes subtypes using the argument index.1296COMPLETION_METHOD, // List available methods in scope.1297COMPLETION_OVERRIDE_METHOD, // Override implementation, also for native virtuals.1298COMPLETION_PROPERTY_DECLARATION, // Property declaration (get, set).1299COMPLETION_PROPERTY_DECLARATION_OR_TYPE, // Property declaration (get, set) or a type hint.1300COMPLETION_PROPERTY_METHOD, // Property setter or getter (list available methods).1301COMPLETION_RESOURCE_PATH, // For load/preload.1302COMPLETION_SUBSCRIPT, // Inside id[|].1303COMPLETION_SUPER, // super(), used for lookup.1304COMPLETION_SUPER_METHOD, // After super.1305COMPLETION_TYPE_ATTRIBUTE, // Attribute in type name (Type.|).1306COMPLETION_TYPE_NAME, // Name of type (after :).1307COMPLETION_TYPE_NAME_OR_VOID, // Same as TYPE_NAME, but allows void (in function return type).1308};13091310struct CompletionCall {1311Node *call = nullptr;1312int argument = -1;1313};13141315struct CompletionContext {1316CompletionType type = COMPLETION_NONE;1317ClassNode *current_class = nullptr;1318FunctionNode *current_function = nullptr;1319SuiteNode *current_suite = nullptr;1320int current_line = -1;1321union {1322int current_argument = -1;1323int type_chain_index;1324};1325Variant::Type builtin_type = Variant::VARIANT_MAX;1326Node *node = nullptr;1327Object *base = nullptr;1328GDScriptParser *parser = nullptr;1329CompletionCall call;1330};13311332private:1333friend class GDScriptAnalyzer;1334friend class GDScriptParserRef;13351336bool _is_tool = false;1337String script_path;1338bool for_completion = false;1339bool parse_body = true;1340bool panic_mode = false;1341bool can_break = false;1342bool can_continue = false;1343List<bool> multiline_stack;1344HashMap<String, Ref<GDScriptParserRef>> depended_parsers;13451346ClassNode *head = nullptr;1347Node *list = nullptr;1348List<ParserError> errors;13491350#ifdef DEBUG_ENABLED1351struct PendingWarning {1352const Node *source = nullptr;1353GDScriptWarning::Code code = GDScriptWarning::WARNING_MAX;1354bool treated_as_error = false;1355Vector<String> symbols;1356};13571358bool is_ignoring_warnings = false;1359List<GDScriptWarning> warnings;1360List<PendingWarning> pending_warnings;1361HashSet<int> warning_ignored_lines[GDScriptWarning::WARNING_MAX];1362int warning_ignore_start_lines[GDScriptWarning::WARNING_MAX];1363HashSet<int> unsafe_lines;1364#endif13651366GDScriptTokenizer *tokenizer = nullptr;1367GDScriptTokenizer::Token previous;1368GDScriptTokenizer::Token current;13691370ClassNode *current_class = nullptr;1371FunctionNode *current_function = nullptr;1372LambdaNode *current_lambda = nullptr;1373SuiteNode *current_suite = nullptr;13741375CompletionContext completion_context;1376List<CompletionCall> completion_call_stack;1377bool in_lambda = false;1378bool lambda_ended = false; // Marker for when a lambda ends, to apply an end of statement if needed.13791380typedef bool (GDScriptParser::*AnnotationAction)(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1381struct AnnotationInfo {1382enum TargetKind {1383NONE = 0,1384SCRIPT = 1 << 0,1385CLASS = 1 << 1,1386VARIABLE = 1 << 2,1387CONSTANT = 1 << 3,1388SIGNAL = 1 << 4,1389FUNCTION = 1 << 5,1390STATEMENT = 1 << 6,1391STANDALONE = 1 << 7,1392CLASS_LEVEL = CLASS | VARIABLE | CONSTANT | SIGNAL | FUNCTION,1393};1394uint32_t target_kind = 0; // Flags.1395AnnotationAction apply = nullptr;1396MethodInfo info;1397};1398static HashMap<StringName, AnnotationInfo> valid_annotations;1399List<AnnotationNode *> annotation_stack;14001401typedef ExpressionNode *(GDScriptParser::*ParseFunction)(ExpressionNode *p_previous_operand, bool p_can_assign);1402// Higher value means higher precedence (i.e. is evaluated first).1403enum Precedence {1404PREC_NONE,1405PREC_ASSIGNMENT,1406PREC_CAST,1407PREC_TERNARY,1408PREC_LOGIC_OR,1409PREC_LOGIC_AND,1410PREC_LOGIC_NOT,1411PREC_CONTENT_TEST,1412PREC_COMPARISON,1413PREC_BIT_OR,1414PREC_BIT_XOR,1415PREC_BIT_AND,1416PREC_BIT_SHIFT,1417PREC_ADDITION_SUBTRACTION,1418PREC_FACTOR,1419PREC_SIGN,1420PREC_BIT_NOT,1421PREC_POWER,1422PREC_TYPE_TEST,1423PREC_AWAIT,1424PREC_CALL,1425PREC_ATTRIBUTE,1426PREC_SUBSCRIPT,1427PREC_PRIMARY,1428};1429struct ParseRule {1430ParseFunction prefix = nullptr;1431ParseFunction infix = nullptr;1432Precedence precedence = PREC_NONE;1433};1434static ParseRule *get_rule(GDScriptTokenizer::Token::Type p_token_type);14351436List<Node *> nodes_in_progress;1437void complete_extents(Node *p_node);1438void update_extents(Node *p_node);1439void reset_extents(Node *p_node, GDScriptTokenizer::Token p_token);1440void reset_extents(Node *p_node, Node *p_from);14411442template <typename T>1443T *alloc_node() {1444T *node = memnew(T);14451446node->next = list;1447list = node;14481449reset_extents(node, previous);1450nodes_in_progress.push_back(node);14511452return node;1453}14541455// Allocates a node for patching up the parse tree when an error occurred.1456// Such nodes don't track their extents as they don't relate to actual tokens.1457template <typename T>1458T *alloc_recovery_node() {1459T *node = memnew(T);1460node->next = list;1461list = node;14621463return node;1464}14651466SuiteNode *alloc_recovery_suite() {1467SuiteNode *suite = alloc_recovery_node<SuiteNode>();1468suite->parent_block = current_suite;1469suite->parent_function = current_function;1470suite->is_in_loop = current_suite->is_in_loop;1471return suite;1472}14731474void clear();1475void push_error(const String &p_message, const Node *p_origin = nullptr);1476#ifdef DEBUG_ENABLED1477void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols);1478template <typename... Symbols>1479void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Symbols &...p_symbols) {1480push_warning(p_source, p_code, Vector<String>{ p_symbols... });1481}1482void apply_pending_warnings();1483#endif1484// Setting p_force to false will prevent the completion context from being update if a context was already set before.1485// This should only be done when we push context before we consumed any tokens for the corresponding structure.1486// See parse_precedence for an example.1487void make_completion_context(CompletionType p_type, Node *p_node, int p_argument = -1, bool p_force = true);1488void make_completion_context(CompletionType p_type, Variant::Type p_builtin_type, bool p_force = true);1489// In some cases it might become necessary to alter the completion context after parsing a subexpression.1490// For example to not override COMPLETE_CALL_ARGUMENTS with COMPLETION_NONE from string literals.1491void override_completion_context(const Node *p_for_node, CompletionType p_type, Node *p_node, int p_argument = -1);1492void push_completion_call(Node *p_call);1493void pop_completion_call();1494void set_last_completion_call_arg(int p_argument);14951496GDScriptTokenizer::Token advance();1497bool match(GDScriptTokenizer::Token::Type p_token_type);1498bool check(GDScriptTokenizer::Token::Type p_token_type) const;1499bool consume(GDScriptTokenizer::Token::Type p_token_type, const String &p_error_message);1500bool is_at_end() const;1501bool is_statement_end_token() const;1502bool is_statement_end() const;1503void end_statement(const String &p_context);1504void synchronize();1505void push_multiline(bool p_state);1506void pop_multiline();15071508// Main blocks.1509void parse_program();1510ClassNode *parse_class(bool p_is_static);1511void parse_class_name();1512void parse_extends();1513void parse_class_body(bool p_is_multiline);1514template <typename T>1515void parse_class_member(T *(GDScriptParser::*p_parse_function)(bool), AnnotationInfo::TargetKind p_target, const String &p_member_kind, bool p_is_static = false);1516SignalNode *parse_signal(bool p_is_static);1517EnumNode *parse_enum(bool p_is_static);1518ParameterNode *parse_parameter();1519FunctionNode *parse_function(bool p_is_static);1520bool parse_function_signature(FunctionNode *p_function, SuiteNode *p_body, const String &p_type, int p_signature_start);1521SuiteNode *parse_suite(const String &p_context, SuiteNode *p_suite = nullptr, bool p_for_lambda = false);1522// Annotations1523AnnotationNode *parse_annotation(uint32_t p_valid_targets);1524static 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);1525bool validate_annotation_arguments(AnnotationNode *p_annotation);1526void clear_unused_annotations();1527bool tool_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1528bool icon_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1529bool static_unload_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1530bool abstract_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1531bool onready_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1532template <PropertyHint t_hint, Variant::Type t_type>1533bool export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1534bool export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1535bool export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1536bool export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1537template <PropertyUsageFlags t_usage>1538bool export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1539bool warning_ignore_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1540bool warning_ignore_region_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1541bool rpc_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);1542// Statements.1543Node *parse_statement();1544VariableNode *parse_variable(bool p_is_static);1545VariableNode *parse_variable(bool p_is_static, bool p_allow_property);1546VariableNode *parse_property(VariableNode *p_variable, bool p_need_indent);1547void parse_property_getter(VariableNode *p_variable);1548void parse_property_setter(VariableNode *p_variable);1549ConstantNode *parse_constant(bool p_is_static);1550AssertNode *parse_assert();1551BreakNode *parse_break();1552ContinueNode *parse_continue();1553ForNode *parse_for();1554IfNode *parse_if(const String &p_token = "if");1555MatchNode *parse_match();1556MatchBranchNode *parse_match_branch();1557PatternNode *parse_match_pattern(PatternNode *p_root_pattern = nullptr);1558WhileNode *parse_while();1559// Expressions.1560ExpressionNode *parse_expression(bool p_can_assign, bool p_stop_on_assign = false);1561ExpressionNode *parse_precedence(Precedence p_precedence, bool p_can_assign, bool p_stop_on_assign = false);1562ExpressionNode *parse_literal(ExpressionNode *p_previous_operand, bool p_can_assign);1563LiteralNode *parse_literal();1564ExpressionNode *parse_self(ExpressionNode *p_previous_operand, bool p_can_assign);1565ExpressionNode *parse_identifier(ExpressionNode *p_previous_operand, bool p_can_assign);1566IdentifierNode *parse_identifier();1567ExpressionNode *parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign);1568ExpressionNode *parse_unary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);1569ExpressionNode *parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);1570ExpressionNode *parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign);1571ExpressionNode *parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);1572ExpressionNode *parse_assignment(ExpressionNode *p_previous_operand, bool p_can_assign);1573ExpressionNode *parse_array(ExpressionNode *p_previous_operand, bool p_can_assign);1574ExpressionNode *parse_dictionary(ExpressionNode *p_previous_operand, bool p_can_assign);1575ExpressionNode *parse_call(ExpressionNode *p_previous_operand, bool p_can_assign);1576ExpressionNode *parse_get_node(ExpressionNode *p_previous_operand, bool p_can_assign);1577ExpressionNode *parse_preload(ExpressionNode *p_previous_operand, bool p_can_assign);1578ExpressionNode *parse_grouping(ExpressionNode *p_previous_operand, bool p_can_assign);1579ExpressionNode *parse_cast(ExpressionNode *p_previous_operand, bool p_can_assign);1580ExpressionNode *parse_await(ExpressionNode *p_previous_operand, bool p_can_assign);1581ExpressionNode *parse_attribute(ExpressionNode *p_previous_operand, bool p_can_assign);1582ExpressionNode *parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign);1583ExpressionNode *parse_lambda(ExpressionNode *p_previous_operand, bool p_can_assign);1584ExpressionNode *parse_type_test(ExpressionNode *p_previous_operand, bool p_can_assign);1585ExpressionNode *parse_yield(ExpressionNode *p_previous_operand, bool p_can_assign);1586ExpressionNode *parse_invalid_token(ExpressionNode *p_previous_operand, bool p_can_assign);1587TypeNode *parse_type(bool p_allow_void = false);15881589#ifdef TOOLS_ENABLED1590int max_script_doc_line = INT_MAX;1591int min_member_doc_line = 1;1592bool has_comment(int p_line, bool p_must_be_doc = false);1593MemberDocData parse_doc_comment(int p_line, bool p_single_line = false);1594ClassDocData parse_class_doc_comment(int p_line, bool p_single_line = false);1595#endif // TOOLS_ENABLED15961597public:1598Error parse(const String &p_source_code, const String &p_script_path, bool p_for_completion, bool p_parse_body = true);1599Error parse_binary(const Vector<uint8_t> &p_binary, const String &p_script_path);1600ClassNode *get_tree() const { return head; }1601bool is_tool() const { return _is_tool; }1602Ref<GDScriptParserRef> get_depended_parser_for(const String &p_path);1603const HashMap<String, Ref<GDScriptParserRef>> &get_depended_parsers();1604ClassNode *find_class(const String &p_qualified_name) const;1605bool has_class(const GDScriptParser::ClassNode *p_class) const;1606static Variant::Type get_builtin_type(const StringName &p_type); // Excluding `Variant::NIL` and `Variant::OBJECT`.16071608CompletionContext get_completion_context() const { return completion_context; }1609void get_annotation_list(List<MethodInfo> *r_annotations) const;1610bool annotation_exists(const String &p_annotation_name) const;16111612const List<ParserError> &get_errors() const { return errors; }1613const List<String> get_dependencies() const {1614// TODO: Keep track of deps.1615return List<String>();1616}1617#ifdef DEBUG_ENABLED1618const List<GDScriptWarning> &get_warnings() const { return warnings; }1619const HashSet<int> &get_unsafe_lines() const { return unsafe_lines; }1620int get_last_line_number() const { return current.end_line; }1621#endif16221623#ifdef TOOLS_ENABLED1624static HashMap<String, String> theme_color_names;16251626HashMap<int, GDScriptTokenizer::CommentData> comment_data;1627#endif // TOOLS_ENABLED16281629GDScriptParser();1630~GDScriptParser();16311632#ifdef DEBUG_ENABLED1633class TreePrinter {1634int indent_level = 0;1635String indent;1636StringBuilder printed;1637bool pending_indent = false;16381639void increase_indent();1640void decrease_indent();1641void push_line(const String &p_line = String());1642void push_text(const String &p_text);16431644void print_annotation(const AnnotationNode *p_annotation);1645void print_array(ArrayNode *p_array);1646void print_assert(AssertNode *p_assert);1647void print_assignment(AssignmentNode *p_assignment);1648void print_await(AwaitNode *p_await);1649void print_binary_op(BinaryOpNode *p_binary_op);1650void print_call(CallNode *p_call);1651void print_cast(CastNode *p_cast);1652void print_class(ClassNode *p_class);1653void print_constant(ConstantNode *p_constant);1654void print_dictionary(DictionaryNode *p_dictionary);1655void print_expression(ExpressionNode *p_expression);1656void print_enum(EnumNode *p_enum);1657void print_for(ForNode *p_for);1658void print_function(FunctionNode *p_function, const String &p_context = "Function");1659void print_get_node(GetNodeNode *p_get_node);1660void print_if(IfNode *p_if, bool p_is_elif = false);1661void print_identifier(IdentifierNode *p_identifier);1662void print_lambda(LambdaNode *p_lambda);1663void print_literal(LiteralNode *p_literal);1664void print_match(MatchNode *p_match);1665void print_match_branch(MatchBranchNode *p_match_branch);1666void print_match_pattern(PatternNode *p_match_pattern);1667void print_parameter(ParameterNode *p_parameter);1668void print_preload(PreloadNode *p_preload);1669void print_return(ReturnNode *p_return);1670void print_self(SelfNode *p_self);1671void print_signal(SignalNode *p_signal);1672void print_statement(Node *p_statement);1673void print_subscript(SubscriptNode *p_subscript);1674void print_suite(SuiteNode *p_suite);1675void print_ternary_op(TernaryOpNode *p_ternary_op);1676void print_type(TypeNode *p_type);1677void print_type_test(TypeTestNode *p_type_test);1678void print_unary_op(UnaryOpNode *p_unary_op);1679void print_variable(VariableNode *p_variable);1680void print_while(WhileNode *p_while);16811682public:1683void print_tree(const GDScriptParser &p_parser);1684};1685#endif // DEBUG_ENABLED1686static void cleanup();1687};168816891690