godot/modules/gdscript/gdscript_parser.cpp

/**************************************************************************/
/*  gdscript_parser.cpp                                                   */
/**************************************************************************/
/*                         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.                 */
/**************************************************************************/

#include "gdscript_parser.h"

#include "gdscript.h"
#include "gdscript_tokenizer_buffer.h"

#include "core/config/project_settings.h"
#include "core/io/file_access.h"
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
#include "scene/main/multiplayer_api.h"

#ifdef DEBUG_ENABLED
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "servers/text_server.h"
#endif

#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
#endif

// This function is used to determine that a type is "built-in" as opposed to native
// and custom classes. So `Variant::NIL` and `Variant::OBJECT` are excluded:
// `Variant::NIL` - `null` is literal, not a type.
// `Variant::OBJECT` - `Object` should be treated as a class, not as a built-in type.
static HashMap<StringName, Variant::Type> builtin_types;
Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) {}

#ifdef TOOLS_ENABLED
HashMap<String, String> GDScriptParser::theme_color_names;
#endif

HashMap<StringName, GDScriptParser::AnnotationInfo> GDScriptParser::valid_annotations;

void GDScriptParser::cleanup() {}

void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const {}

bool GDScriptParser::annotation_exists(const String &p_annotation_name) const {}

GDScriptParser::GDScriptParser() {}

GDScriptParser::~GDScriptParser() {}

void GDScriptParser::clear() {}

void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {}

#ifdef DEBUG_ENABLED
void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols) {}

void GDScriptParser::apply_pending_warnings() {}
#endif

void GDScriptParser::override_completion_context(const Node *p_for_node, CompletionType p_type, Node *p_node, int p_argument) {}

void GDScriptParser::make_completion_context(CompletionType p_type, Node *p_node, int p_argument, bool p_force) {}

void GDScriptParser::make_completion_context(CompletionType p_type, Variant::Type p_builtin_type, bool p_force) {}

void GDScriptParser::push_completion_call(Node *p_call) {}

void GDScriptParser::pop_completion_call() {}

void GDScriptParser::set_last_completion_call_arg(int p_argument) {}

Error GDScriptParser::parse(const String &p_source_code, const String &p_script_path, bool p_for_completion, bool p_parse_body) {}

Error GDScriptParser::parse_binary(const Vector<uint8_t> &p_binary, const String &p_script_path) {}

GDScriptTokenizer::Token GDScriptParser::advance() {}

bool GDScriptParser::match(GDScriptTokenizer::Token::Type p_token_type) {}

bool GDScriptParser::check(GDScriptTokenizer::Token::Type p_token_type) const {}

bool GDScriptParser::consume(GDScriptTokenizer::Token::Type p_token_type, const String &p_error_message) {}

bool GDScriptParser::is_at_end() const {}

void GDScriptParser::synchronize() {}

void GDScriptParser::push_multiline(bool p_state) {}

void GDScriptParser::pop_multiline() {}

bool GDScriptParser::is_statement_end_token() const {}

bool GDScriptParser::is_statement_end() const {}

void GDScriptParser::end_statement(const String &p_context) {}

void GDScriptParser::parse_program() {}

Ref<GDScriptParserRef> GDScriptParser::get_depended_parser_for(const String &p_path) {}

const HashMap<String, Ref<GDScriptParserRef>> &GDScriptParser::get_depended_parsers() {}

GDScriptParser::ClassNode *GDScriptParser::find_class(const String &p_qualified_name) const {}

bool GDScriptParser::has_class(const GDScriptParser::ClassNode *p_class) const {}

GDScriptParser::ClassNode *GDScriptParser::parse_class(bool p_is_static) {}

void GDScriptParser::parse_class_name() {}

void GDScriptParser::parse_extends() {}

template <typename T>
void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)(bool), AnnotationInfo::TargetKind p_target, const String &p_member_kind, bool p_is_static) {}

void GDScriptParser::parse_class_body(bool p_is_multiline) {}

GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static) {}

GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static, bool p_allow_property) {}

GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_variable, bool p_need_indent) {}

void GDScriptParser::parse_property_setter(VariableNode *p_variable) {}

void GDScriptParser::parse_property_getter(VariableNode *p_variable) {}

GDScriptParser::ConstantNode *GDScriptParser::parse_constant(bool p_is_static) {}

GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {}

GDScriptParser::SignalNode *GDScriptParser::parse_signal(bool p_is_static) {}

GDScriptParser::EnumNode *GDScriptParser::parse_enum(bool p_is_static) {}

void GDScriptParser::parse_function_signature(FunctionNode *p_function, SuiteNode *p_body, const String &p_type) {}

GDScriptParser::FunctionNode *GDScriptParser::parse_function(bool p_is_static) {}

GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_valid_targets) {}

void GDScriptParser::clear_unused_annotations() {}

bool GDScriptParser::register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments, bool p_is_vararg) {}

GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context, SuiteNode *p_suite, bool p_for_lambda) {}

GDScriptParser::Node *GDScriptParser::parse_statement() {}

GDScriptParser::AssertNode *GDScriptParser::parse_assert() {}

GDScriptParser::BreakNode *GDScriptParser::parse_break() {}

GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {}

GDScriptParser::ForNode *GDScriptParser::parse_for() {}

GDScriptParser::IfNode *GDScriptParser::parse_if(const String &p_token) {}

GDScriptParser::MatchNode *GDScriptParser::parse_match() {}

GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {}

GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_root_pattern) {}

bool GDScriptParser::PatternNode::has_bind(const StringName &p_name) {}

GDScriptParser::IdentifierNode *GDScriptParser::PatternNode::get_bind(const StringName &p_name) {}

GDScriptParser::WhileNode *GDScriptParser::parse_while() {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_precedence(Precedence p_precedence, bool p_can_assign, bool p_stop_on_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_expression(bool p_can_assign, bool p_stop_on_assign) {}

GDScriptParser::IdentifierNode *GDScriptParser::parse_identifier() {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_identifier(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::LiteralNode *GDScriptParser::parse_literal() {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_literal(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_self(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_unary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_assignment(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_await(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_array(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_dictionary(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_grouping(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_attribute(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_cast(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_preload(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_type_test(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_yield(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::ExpressionNode *GDScriptParser::parse_invalid_token(ExpressionNode *p_previous_operand, bool p_can_assign) {}

GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {}

#ifdef TOOLS_ENABLED
enum DocLineState {};

static String _process_doc_line(const String &p_line, const String &p_text, const String &p_space_prefix, DocLineState &r_state) {}

bool GDScriptParser::has_comment(int p_line, bool p_must_be_doc) {}

GDScriptParser::MemberDocData GDScriptParser::parse_doc_comment(int p_line, bool p_single_line) {}

GDScriptParser::ClassDocData GDScriptParser::parse_class_doc_comment(int p_line, bool p_single_line) {}
#endif // TOOLS_ENABLED

GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Type p_token_type) {}

bool GDScriptParser::SuiteNode::has_local(const StringName &p_name) const {}

const GDScriptParser::SuiteNode::Local &GDScriptParser::SuiteNode::get_local(const StringName &p_name) const {}

bool GDScriptParser::AnnotationNode::apply(GDScriptParser *p_this, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::AnnotationNode::applies_to(uint32_t p_target_kinds) const {}

bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) {}

bool GDScriptParser::tool_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::icon_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::onready_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

static String _get_annotation_error_string(const StringName &p_annotation_name, const Vector<Variant::Type> &p_expected_types, const GDScriptParser::DataType &p_provided_type) {}

static StringName _find_narrowest_native_or_global_class(const GDScriptParser::DataType &p_type) {}

template <PropertyHint t_hint, Variant::Type t_type>
bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

// For `@export_storage` and `@export_custom`, there is no need to check the variable type, argument values,
// or handle array exports in a special way, so they are implemented as separate methods.

bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

template <PropertyUsageFlags t_usage>
bool GDScriptParser::export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::warning_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::rpc_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

bool GDScriptParser::static_unload_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {}

GDScriptParser::DataType GDScriptParser::SuiteNode::Local::get_datatype() const {}

String GDScriptParser::SuiteNode::Local::get_name() const {}

String GDScriptParser::DataType::to_string() const {}

PropertyInfo GDScriptParser::DataType::to_property_info(const String &p_name) const {}

static Variant::Type _variant_type_to_typed_array_element_type(Variant::Type p_type) {}

bool GDScriptParser::DataType::is_typed_container_type() const {}

GDScriptParser::DataType GDScriptParser::DataType::get_typed_container_type() const {}

bool GDScriptParser::DataType::can_reference(const GDScriptParser::DataType &p_other) const {}

void GDScriptParser::complete_extents(Node *p_node) {}

void GDScriptParser::update_extents(Node *p_node) {}

void GDScriptParser::reset_extents(Node *p_node, GDScriptTokenizer::Token p_token) {}

void GDScriptParser::reset_extents(Node *p_node, Node *p_from) {}

/*---------- PRETTY PRINT FOR DEBUG ----------*/

#ifdef DEBUG_ENABLED

void GDScriptParser::TreePrinter::increase_indent() {}

void GDScriptParser::TreePrinter::decrease_indent() {}

void GDScriptParser::TreePrinter::push_line(const String &p_line) {}

void GDScriptParser::TreePrinter::push_text(const String &p_text) {}

void GDScriptParser::TreePrinter::print_annotation(const AnnotationNode *p_annotation) {}

void GDScriptParser::TreePrinter::print_array(ArrayNode *p_array) {}

void GDScriptParser::TreePrinter::print_assert(AssertNode *p_assert) {}

void GDScriptParser::TreePrinter::print_assignment(AssignmentNode *p_assignment) {}

void GDScriptParser::TreePrinter::print_await(AwaitNode *p_await) {}

void GDScriptParser::TreePrinter::print_binary_op(BinaryOpNode *p_binary_op) {}

void GDScriptParser::TreePrinter::print_call(CallNode *p_call) {}

void GDScriptParser::TreePrinter::print_cast(CastNode *p_cast) {}

void GDScriptParser::TreePrinter::print_class(ClassNode *p_class) {}

void GDScriptParser::TreePrinter::print_constant(ConstantNode *p_constant) {}

void GDScriptParser::TreePrinter::print_dictionary(DictionaryNode *p_dictionary) {}

void GDScriptParser::TreePrinter::print_expression(ExpressionNode *p_expression) {}

void GDScriptParser::TreePrinter::print_enum(EnumNode *p_enum) {}

void GDScriptParser::TreePrinter::print_for(ForNode *p_for) {}

void GDScriptParser::TreePrinter::print_function(FunctionNode *p_function, const String &p_context) {}

void GDScriptParser::TreePrinter::print_get_node(GetNodeNode *p_get_node) {}

void GDScriptParser::TreePrinter::print_identifier(IdentifierNode *p_identifier) {}

void GDScriptParser::TreePrinter::print_if(IfNode *p_if, bool p_is_elif) {}

void GDScriptParser::TreePrinter::print_lambda(LambdaNode *p_lambda) {}

void GDScriptParser::TreePrinter::print_literal(LiteralNode *p_literal) {}

void GDScriptParser::TreePrinter::print_match(MatchNode *p_match) {}

void GDScriptParser::TreePrinter::print_match_branch(MatchBranchNode *p_match_branch) {}

void GDScriptParser::TreePrinter::print_match_pattern(PatternNode *p_match_pattern) {}

void GDScriptParser::TreePrinter::print_parameter(ParameterNode *p_parameter) {}

void GDScriptParser::TreePrinter::print_preload(PreloadNode *p_preload) {}

void GDScriptParser::TreePrinter::print_return(ReturnNode *p_return) {}

void GDScriptParser::TreePrinter::print_self(SelfNode *p_self) {}

void GDScriptParser::TreePrinter::print_signal(SignalNode *p_signal) {}

void GDScriptParser::TreePrinter::print_subscript(SubscriptNode *p_subscript) {}

void GDScriptParser::TreePrinter::print_statement(Node *p_statement) {}

void GDScriptParser::TreePrinter::print_suite(SuiteNode *p_suite) {}

void GDScriptParser::TreePrinter::print_ternary_op(TernaryOpNode *p_ternary_op) {}

void GDScriptParser::TreePrinter::print_type(TypeNode *p_type) {}

void GDScriptParser::TreePrinter::print_type_test(TypeTestNode *p_test) {}

void GDScriptParser::TreePrinter::print_unary_op(UnaryOpNode *p_unary_op) {}

void GDScriptParser::TreePrinter::print_variable(VariableNode *p_variable) {}

void GDScriptParser::TreePrinter::print_while(WhileNode *p_while) {}

void GDScriptParser::TreePrinter::print_tree(const GDScriptParser &p_parser) {}

#endif // DEBUG_ENABLED