public:
	enum {
		NOTIFICATION_TRANSFORM_CHANGED = 2000
	};

	enum GroupCallFlags {
		GROUP_CALL_DEFAULT = 0,
		GROUP_CALL_REVERSE = 1,
		GROUP_CALL_DEFERRED = 2,
		GROUP_CALL_UNIQUE = 4,
	};

	_FORCE_INLINE_ Window *get_root() const { return root; }

	void call_group_flagsp(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, const Variant **p_args, int p_argcount);
	void notify_group_flags(uint32_t p_call_flags, const StringName &p_group, int p_notification);
	void set_group_flags(uint32_t p_call_flags, const StringName &p_group, const String &p_name, const Variant &p_value);

	// `notify_group()` is immediate by default since Godot 4.0.
	void notify_group(const StringName &p_group, int p_notification);
	// `set_group()` is immediate by default since Godot 4.0.
	void set_group(const StringName &p_group, const String &p_name, const Variant &p_value);

	template <typename... VarArgs>
	// `call_group()` is immediate by default since Godot 4.0.
	void call_group(const StringName &p_group, const StringName &p_function, VarArgs... p_args) {
		Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
		const Variant *argptrs[sizeof...(p_args) + 1];
		for (uint32_t i = 0; i < sizeof...(p_args); i++) {
			argptrs[i] = &args[i];
		}
		call_group_flagsp(GROUP_CALL_DEFAULT, p_group, p_function, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
	}

	template <typename... VarArgs>
	void call_group_flags(uint32_t p_flags, const StringName &p_group, const StringName &p_function, VarArgs... p_args) {
		Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
		const Variant *argptrs[sizeof...(p_args) + 1];
		for (uint32_t i = 0; i < sizeof...(p_args); i++) {
			argptrs[i] = &args[i];
		}
		call_group_flagsp(p_flags, p_group, p_function, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
	}

	void flush_transform_notifications();

	virtual void initialize() override;

	virtual void iteration_prepare() override;

	virtual bool physics_process(double p_time) override;
	virtual void iteration_end() override;
	virtual bool process(double p_time) override;

	virtual void finalize() override;

	bool is_auto_accept_quit() const;
	void set_auto_accept_quit(bool p_enable);

	bool is_quit_on_go_back() const;
	void set_quit_on_go_back(bool p_enable);

	void quit(int p_exit_code = EXIT_SUCCESS);

	_FORCE_INLINE_ double get_physics_process_time() const { return physics_process_time; }
	_FORCE_INLINE_ double get_process_time() const { return process_time; }

	void set_pause(bool p_enabled);
	bool is_paused() const;

#ifdef DEBUG_ENABLED
	void set_debug_collisions_hint(bool p_enabled);
	bool is_debugging_collisions_hint() const;

	void set_debug_paths_hint(bool p_enabled);
	bool is_debugging_paths_hint() const;

	void set_debug_navigation_hint(bool p_enabled);
	bool is_debugging_navigation_hint() const;
#else
	void set_debug_collisions_hint(bool p_enabled) {}
	bool is_debugging_collisions_hint() const { return false; }

	void set_debug_paths_hint(bool p_enabled) {}
	bool is_debugging_paths_hint() const { return false; }

	void set_debug_navigation_hint(bool p_enabled) {}
	bool is_debugging_navigation_hint() const { return false; }
#endif

	void set_debug_collisions_color(const Color &p_color);
	Color get_debug_collisions_color() const;

	void set_debug_collision_contact_color(const Color &p_color);
	Color get_debug_collision_contact_color() const;

	void set_debug_paths_color(const Color &p_color);
	Color get_debug_paths_color() const;

	void set_debug_paths_width(float p_width);
	float get_debug_paths_width() const;

	Ref<Material> get_debug_paths_material();
	Ref<Material> get_debug_collision_material();
	Ref<ArrayMesh> get_debug_contact_mesh();

	int get_collision_debug_contact_count() { return collision_debug_contacts; }

	int64_t get_frame() const;

	int get_node_count() const;

	void queue_delete(Object *p_object);

	void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list);
	Node *get_first_node_in_group(const StringName &p_group);
	bool has_group(const StringName &p_identifier) const;
	int get_node_count_in_group(const StringName &p_group) const;

	//void change_scene(const String& p_path);
	//Node *get_loaded_scene();

	void set_edited_scene_root(Node *p_node);
	Node *get_edited_scene_root() const;

	void set_current_scene(Node *p_scene);
	Node *get_current_scene() const;
	Error change_scene_to_file(const String &p_path);
	Error change_scene_to_packed(const Ref<PackedScene> &p_scene);
	Error reload_current_scene();
	void unload_current_scene();

	Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false);
	Ref<Tween> create_tween();
	TypedArray<Tween> get_processed_tweens();

	//used by Main::start, don't use otherwise
	void add_current_scene(Node *p_current);

	static SceneTree *get_singleton() { return singleton; }

#ifdef TOOLS_ENABLED
	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#endif

	//network API

	Ref<MultiplayerAPI> get_multiplayer(const NodePath &p_for_path = NodePath()) const;
	void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer, const NodePath &p_root_path = NodePath());
	void set_multiplayer_poll_enabled(bool p_enabled);
	bool is_multiplayer_poll_enabled() const;

	static void add_idle_callback(IdleCallback p_callback);

	void set_disable_node_threading(bool p_disable);
	//default texture settings

	void set_physics_interpolation_enabled(bool p_enabled);
	bool is_physics_interpolation_enabled() const;

#ifndef _3D_DISABLED
	void client_physics_interpolation_add_node_3d(SelfList<Node3D> *p_elem);
	void client_physics_interpolation_remove_node_3d(SelfList<Node3D> *p_elem);
#endif

	SceneTree();
	~SceneTree();
};

VARIANT_ENUM_CAST(SceneTree::GroupCallFlags);

#endif // SCENE_TREE_H


/**************************************************************************/
/*  camera_2d.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.                 */
/**************************************************************************/

#ifndef CAMERA_2D_H
#define CAMERA_2D_H

#include "scene/2d/node_2d.h"

class Camera2D : public Node2D {
	GDCLASS(Camera2D, Node2D);

public:
	enum AnchorMode {
		ANCHOR_MODE_FIXED_TOP_LEFT,
		ANCHOR_MODE_DRAG_CENTER
	};

	enum Camera2DProcessCallback {
		CAMERA2D_PROCESS_PHYSICS,
		CAMERA2D_PROCESS_IDLE
	};

protected:
	Point2 camera_pos;
	Point2 smoothed_camera_pos;
	bool first = true;
	bool just_exited_tree = false;

	ObjectID custom_viewport_id; // to check validity
	Viewport *custom_viewport = nullptr;
	Viewport *viewport = nullptr;

	StringName group_name;
	StringName canvas_group_name;
	RID canvas;
	Vector2 offset;
	Vector2 zoom = Vector2(1, 1);
	Vector2 zoom_scale = Vector2(1, 1);
	AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER;
	bool ignore_rotation = true;
	bool enabled = true;
	real_t position_smoothing_speed = 5.0;
	bool position_smoothing_enabled = false;

	real_t camera_angle = 0.0;
	real_t rotation_smoothing_speed = 5.0;
	bool rotation_smoothing_enabled = false;

	int limit[4];
	bool limit_smoothing_enabled = false;

	real_t drag_margin[4];
	bool drag_horizontal_enabled = false;
	bool drag_vertical_enabled = false;
	real_t drag_horizontal_offset = 0.0;
	real_t drag_vertical_offset = 0.0;
	bool drag_horizontal_offset_changed = false;
	bool drag_vertical_offset_changed = false;

	Point2 camera_screen_center;
	bool _is_editing_in_editor() const;
	void _update_process_callback();
	void _update_scroll();
#ifdef TOOLS_ENABLED
	void _project_settings_changed();
#endif

	void _make_current(Object *p_which);
	void _reset_just_exited() { just_exited_tree = false; }

	void _set_old_smoothing(real_t p_enable);

	void _update_process_internal_for_smoothing();

	bool screen_drawing_enabled = true;
	bool limit_drawing_enabled = false;
	bool margin_drawing_enabled = false;

	Camera2DProcessCallback process_callback = CAMERA2D_PROCESS_IDLE;

	struct InterpolationData {
		Transform2D xform_curr;
		Transform2D xform_prev;
		uint32_t last_update_physics_tick = UINT32_MAX; // Ensure tick 0 is detected as a change.
	} _interpolation_data;

	void _ensure_update_interpolation_data();

	Size2 _get_camera_screen_size() const;

protected:
	virtual Transform2D get_camera_transform();

	void _notification(int p_what);
	static void _bind_methods();
	void _validate_property(PropertyInfo &p_property) const;

public:
	void set_offset(const Vector2 &p_offset);
	Vector2 get_offset() const;

	void set_anchor_mode(AnchorMode p_anchor_mode);
	AnchorMode get_anchor_mode() const;

	void set_ignore_rotation(bool p_ignore);
	bool is_ignoring_rotation() const;

	void set_limit(Side p_side, int p_limit);
	int get_limit(Side p_side) const;

	void set_limit_smoothing_enabled(bool enable);
	bool is_limit_smoothing_enabled() const;

	void set_drag_horizontal_enabled(bool p_enabled);
	bool is_drag_horizontal_enabled() const;

	void set_drag_vertical_enabled(bool p_enabled);
	bool is_drag_vertical_enabled() const;

	void set_drag_margin(Side p_side, real_t p_drag_margin);
	real_t get_drag_margin(Side p_side) const;

	void set_drag_horizontal_offset(real_t p_offset);
	real_t get_drag_horizontal_offset() const;

	void set_drag_vertical_offset(real_t p_offset);
	real_t get_drag_vertical_offset() const;

	void set_position_smoothing_enabled(bool p_enabled);
	bool is_position_smoothing_enabled() const;

	void set_position_smoothing_speed(real_t p_speed);
	real_t get_position_smoothing_speed() const;

	void set_rotation_smoothing_speed(real_t p_speed);
	real_t get_rotation_smoothing_speed() const;

	void set_rotation_smoothing_enabled(bool p_enabled);
	bool is_rotation_smoothing_enabled() const;

	void set_process_callback(Camera2DProcessCallback p_mode);
	Camera2DProcessCallback get_process_callback() const;

	void set_enabled(bool p_enabled);
	bool is_enabled() const;

	void make_current();
	void clear_current();
	bool is_current() const;

	void set_zoom(const Vector2 &p_zoom);
	Vector2 get_zoom() const;

	Point2 get_camera_screen_center() const;

	void set_custom_viewport(Node *p_viewport);
	Node *get_custom_viewport() const;

	Vector2 get_camera_position() const;
	void force_update_scroll();
	void reset_smoothing();
	void align();

	void set_screen_drawing_enabled(bool enable);
	bool is_screen_drawing_enabled() const;

	void set_limit_drawing_enabled(bool enable);
	bool is_limit_drawing_enabled() const;

	void set_margin_drawing_enabled(bool enable);
	bool is_margin_drawing_enabled() const;

	Camera2D();
};

VARIANT_ENUM_CAST(Camera2D::AnchorMode);
VARIANT_ENUM_CAST(Camera2D::Camera2DProcessCallback);

#endif // CAMERA_2D_H


/**************************************************************************/
/*  animated_sprite_2d.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.                 */
/**************************************************************************/

#ifndef ANIMATED_SPRITE_2D_H
#define ANIMATED_SPRITE_2D_H

#include "scene/2d/node_2d.h"
#include "scene/resources/sprite_frames.h"

class AnimatedSprite2D : public Node2D {
	GDCLASS(AnimatedSprite2D, Node2D);

	Ref<SpriteFrames> frames;
	String autoplay;

	bool playing = false;
	StringName animation = "default";
	int frame = 0;
	float speed_scale = 1.0;
	float custom_speed_scale = 1.0;

	bool centered = true;
	Point2 offset;

	real_t frame_speed_scale = 1.0;
	real_t frame_progress = 0.0;

	bool hflip = false;
	bool vflip = false;

	void _res_changed();

	double _get_frame_duration();
	void _calc_frame_speed_scale();
	void _stop_internal(bool p_reset);

	Rect2 _get_rect() const;

protected:
#ifndef DISABLE_DEPRECATED
	bool _set(const StringName &p_name, const Variant &p_value);
#endif
	static void _bind_methods();
	void _notification(int p_what);
	void _validate_property(PropertyInfo &p_property) const;

public:
#ifdef TOOLS_ENABLED
	virtual Dictionary _edit_get_state() const override;
	virtual void _edit_set_state(const Dictionary &p_state) override;

	virtual void _edit_set_pivot(const Point2 &p_pivot) override;
	virtual Point2 _edit_get_pivot() const override;
	virtual bool _edit_use_pivot() const override;
	virtual Rect2 _edit_get_rect() const override;
	virtual bool _edit_use_rect() const override;
#endif

	virtual Rect2 get_anchorable_rect() const override;

	void set_sprite_frames(const Ref<SpriteFrames> &p_frames);
	Ref<SpriteFrames> get_sprite_frames() const;

	void play(const StringName &p_name = StringName(), float p_custom_scale = 1.0, bool p_from_end = false);
	void play_backwards(const StringName &p_name = StringName());
	void pause();
	void stop();

	bool is_playing() const;

	void set_animation(const StringName &p_name);
	StringName get_animation() const;

	void set_autoplay(const String &p_name);
	String get_autoplay() const;

	void set_frame(int p_frame);
	int get_frame() const;

	void set_frame_progress(real_t p_progress);
	real_t get_frame_progress() const;

	void set_frame_and_progress(int p_frame, real_t p_progress);

	void set_speed_scale(float p_speed_scale);
	float get_speed_scale() const;
	float get_playing_speed() const;

	void set_centered(bool p_center);
	bool is_centered() const;

	void set_offset(const Point2 &p_offset);
	Point2 get_offset() const;

	void set_flip_h(bool p_flip);
	bool is_flipped_h() const;

	void set_flip_v(bool p_flip);
	bool is_flipped_v() const;

	PackedStringArray get_configuration_warnings() const override;

#ifdef TOOLS_ENABLED
	virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#endif

	AnimatedSprite2D();
};

#endif // ANIMATED_SPRITE_2D_H


/**************************************************************************/
/*  collision_object_2d.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.                 */
/**************************************************************************/

#ifndef COLLISION_OBJECT_2D_H
#define COLLISION_OBJECT_2D_H

#include "scene/2d/node_2d.h"
#include "scene/main/viewport.h"
#include "scene/resources/2d/shape_2d.h"
#include "servers/physics_server_2d.h"

class CollisionObject2D : public Node2D {
	GDCLASS(CollisionObject2D, Node2D);

public:
	enum DisableMode {
		DISABLE_MODE_REMOVE,
		DISABLE_MODE_MAKE_STATIC,
		DISABLE_MODE_KEEP_ACTIVE,
	};

private:
	uint32_t collision_layer = 1;
	uint32_t collision_mask = 1;
	real_t collision_priority = 1.0;

	bool area = false;
	RID rid;
	uint32_t callback_lock = 0;
	bool pickable = false;

	DisableMode disable_mode = DISABLE_MODE_REMOVE;

	PhysicsServer2D::BodyMode body_mode = PhysicsServer2D::BODY_MODE_STATIC;

	struct ShapeData {
		ObjectID owner_id;
		Transform2D xform;
		struct Shape {
			Ref<Shape2D> shape;
			int index = 0;
		};

		Vector<Shape> shapes;

		bool disabled = false;
		bool one_way_collision = false;
		real_t one_way_collision_margin = 0.0;
	};

	int total_subshapes = 0;

	RBMap<uint32_t, ShapeData> shapes;
	bool only_update_transform_changes = false; // This is used for sync to physics.

	void _apply_disabled();
	void _apply_enabled();

protected:
	_FORCE_INLINE_ void lock_callback() { callback_lock++; }
	_FORCE_INLINE_ void unlock_callback() {
		ERR_FAIL_COND(callback_lock == 0);
		callback_lock--;
	}

	CollisionObject2D(RID p_rid, bool p_area);

	void _notification(int p_what);
	static void _bind_methods();

	void _update_pickable();
	friend class Viewport;
	void _input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape);
	void _mouse_enter();
	void _mouse_exit();

	void _mouse_shape_enter(int p_shape);
	void _mouse_shape_exit(int p_shape);

	void set_only_update_transform_changes(bool p_enable);
	bool is_only_update_transform_changes_enabled() const;

	void set_body_mode(PhysicsServer2D::BodyMode p_mode);

	virtual void _space_changed(const RID &p_new_space);

	GDVIRTUAL3(_input_event, Viewport *, Ref<InputEvent>, int)
	GDVIRTUAL0(_mouse_enter)
	GDVIRTUAL0(_mouse_exit)
	GDVIRTUAL1(_mouse_shape_enter, int)
	GDVIRTUAL1(_mouse_shape_exit, int)
public:
	void set_collision_layer(uint32_t p_layer);
	uint32_t get_collision_layer() const;

	void set_collision_mask(uint32_t p_mask);
	uint32_t get_collision_mask() const;

	void set_collision_layer_value(int p_layer_number, bool p_value);
	bool get_collision_layer_value(int p_layer_number) const;

	void set_collision_mask_value(int p_layer_number, bool p_value);
	bool get_collision_mask_value(int p_layer_number) const;

	void set_collision_priority(real_t p_priority);
	real_t get_collision_priority() const;

	void set_disable_mode(DisableMode p_mode);
	DisableMode get_disable_mode() const;

	uint32_t create_shape_owner(Object *p_owner);
	void remove_shape_owner(uint32_t owner);
	void get_shape_owners(List<uint32_t> *r_owners);
	PackedInt32Array _get_shape_owners();

	void shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform);
	Transform2D shape_owner_get_transform(uint32_t p_owner) const;
	Object *shape_owner_get_owner(uint32_t p_owner) const;

	void shape_owner_set_disabled(uint32_t p_owner, bool p_disabled);
	bool is_shape_owner_disabled(uint32_t p_owner) const;

	void shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable);
	bool is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const;

	void shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin);
	real_t get_shape_owner_one_way_collision_margin(uint32_t p_owner) const;

	void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape);
	int shape_owner_get_shape_count(uint32_t p_owner) const;
	Ref<Shape2D> shape_owner_get_shape(uint32_t p_owner, int p_shape) const;
	int shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const;

	void shape_owner_remove_shape(uint32_t p_owner, int p_shape);
	void shape_owner_clear_shapes(uint32_t p_owner);

	uint32_t shape_find_owner(int p_shape_index) const;

	void set_pickable(bool p_enabled);
	bool is_pickable() const;

	PackedStringArray get_configuration_warnings() const override;

	_FORCE_INLINE_ RID get_rid() const { return rid; }

	CollisionObject2D();
	~CollisionObject2D();
};

VARIANT_ENUM_CAST(CollisionObject2D::DisableMode);

#endif // COLLISION_OBJECT_2D_H


<?xml version="1.0" encoding="UTF-8" ?>
<class name="CSGShape3D" inherits="GeometryInstance3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
	<brief_description>
		The CSG base class.
	</brief_description>
	<description>
		This is the CSG base class that provides CSG operation support to the various CSG nodes in Godot.
		[b]Performance:[/b] CSG nodes are only intended for prototyping as they have a significant CPU performance cost.
		Consider baking final CSG operation results into static geometry that replaces the CSG nodes.
		Individual CSG root node results can be baked to nodes with static resources with the editor menu that appears when a CSG root node is selected.
		Individual CSG root nodes can also be baked to static resources with scripts by calling [method bake_static_mesh] for the visual mesh or [method bake_collision_shape] for the physics collision.
		Entire scenes of CSG nodes can be baked to static geometry and exported with the editor gltf scene exporter.
	</description>
	<tutorials>
		<link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link>
	</tutorials>
	<methods>
		<method name="bake_collision_shape">
			<return type="ConcavePolygonShape3D" />
			<description>
				Returns a baked physics [ConcavePolygonShape3D] of this node's CSG operation result. Returns an empty shape if the node is not a CSG root node or has no valid geometry.
				[b]Performance:[/b] If the CSG operation results in a very detailed geometry with many faces physics performance will be very slow. Concave shapes should in general only be used for static level geometry and not with dynamic objects that are moving.
			</description>
		</method>
		<method name="bake_static_mesh">
			<return type="ArrayMesh" />
			<description>
				Returns a baked static [ArrayMesh] of this node's CSG operation result. Materials from involved CSG nodes are added as extra mesh surfaces. Returns an empty mesh if the node is not a CSG root node or has no valid geometry.
			</description>
		</method>
		<method name="get_collision_layer_value" qualifiers="const">
			<return type="bool" />
			<param index="0" name="layer_number" type="int" />
			<description>
				Returns whether or not the specified layer of the [member collision_layer] is enabled, given a [param layer_number] between 1 and 32.
			</description>
		</method>
		<method name="get_collision_mask_value" qualifiers="const">
			<return type="bool" />
			<param index="0" name="layer_number" type="int" />
			<description>
				Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [param layer_number] between 1 and 32.
			</description>
		</method>
		<method name="get_meshes" qualifiers="const">
			<return type="Array" />
			<description>
				Returns an [Array] with two elements, the first is the [Transform3D] of this node and the second is the root [Mesh] of this node. Only works when this node is the root shape.
			</description>
		</method>
		<method name="is_root_shape" qualifiers="const">
			<return type="bool" />
			<description>
				Returns [code]true[/code] if this is a root shape and is thus the object that is rendered.
			</description>
		</method>
		<method name="set_collision_layer_value">
			<return type="void" />
			<param index="0" name="layer_number" type="int" />
			<param index="1" name="value" type="bool" />
			<description>
				Based on [param value], enables or disables the specified layer in the [member collision_layer], given a [param layer_number] between 1 and 32.
			</description>
		</method>
		<method name="set_collision_mask_value">
			<return type="void" />
			<param index="0" name="layer_number" type="int" />
			<param index="1" name="value" type="bool" />
			<description>
				Based on [param value], enables or disables the specified layer in the [member collision_mask], given a [param layer_number] between 1 and 32.
			</description>
		</method>
	</methods>
	<members>
		<member name="calculate_tangents" type="bool" setter="set_calculate_tangents" getter="is_calculating_tangents" default="true">
			Calculate tangents for the CSG shape which allows the use of normal maps. This is only applied on the root shape, this setting is ignored on any child.
		</member>
		<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
			The physics layers this area is in.
			Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property.
			A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
		</member>
		<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
			The physics layers this CSG shape scans for collisions. Only effective if [member use_collision] is [code]true[/code]. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
		</member>
		<member name="collision_priority" type="float" setter="set_collision_priority" getter="get_collision_priority" default="1.0">
			The priority used to solve colliding when occurring penetration. Only effective if [member use_collision] is [code]true[/code]. The higher the priority is, the lower the penetration into the object will be. This can for example be used to prevent the player from breaking through the boundaries of a level.
		</member>
		<member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape3D.Operation" default="0">
			The operation that is performed on this shape. This is ignored for the first CSG child node as the operation is between this node and the previous child of this nodes parent.
		</member>
		<member name="snap" type="float" setter="set_snap" getter="get_snap" default="0.001">
			Snap makes the mesh vertices snap to a given distance so that the faces of two meshes can be perfectly aligned. A lower value results in greater precision but may be harder to adjust. The top-level CSG shape's snap value is used for the entire CSG tree.
		</member>
		<member name="use_collision" type="bool" setter="set_use_collision" getter="is_using_collision" default="false">
			Adds a collision shape to the physics engine for our CSG shape. This will always act like a static body. Note that the collision shape is still active even if the CSG shape itself is hidden. See also [member collision_mask] and [member collision_priority].
		</member>
	</members>
	<constants>
		<constant name="OPERATION_UNION" value="0" enum="Operation">
			Geometry of both primitives is merged, intersecting geometry is removed.
		</constant>
		<constant name="OPERATION_INTERSECTION" value="1" enum="Operation">
			Only intersecting geometry remains, the rest is removed.
		</constant>
		<constant name="OPERATION_SUBTRACTION" value="2" enum="Operation">
			The second shape is subtracted from the first, leaving a dent with its shape.
		</constant>
	</constants>
</class>


<?xml version="1.0" encoding="UTF-8" ?>
<class name="CSGMesh3D" inherits="CSGPrimitive3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
	<brief_description>
		A CSG Mesh shape that uses a mesh resource.
	</brief_description>
	<description>
		This CSG node allows you to use any mesh resource as a CSG shape, provided it is closed, does not self-intersect, does not contain internal faces and has no edges that connect to more than two faces. See also [CSGPolygon3D] for drawing 2D extruded polygons to be used as CSG nodes.
		[b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay.
	</description>
	<tutorials>
		<link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link>
	</tutorials>
	<members>
		<member name="material" type="Material" setter="set_material" getter="get_material">
			The [Material] used in drawing the CSG shape.
		</member>
		<member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh">
			The [Mesh] resource to use as a CSG shape.
			[b]Note:[/b] When using an [ArrayMesh], all vertex attributes except [constant Mesh.ARRAY_VERTEX], [constant Mesh.ARRAY_NORMAL] and [constant Mesh.ARRAY_TEX_UV] are left unused. Only [constant Mesh.ARRAY_VERTEX] and [constant Mesh.ARRAY_TEX_UV] will be passed to the GPU.
			[constant Mesh.ARRAY_NORMAL] is only used to determine which faces require the use of flat shading. By default, CSGMesh will ignore the mesh's vertex normals, recalculate them for each vertex and use a smooth shader. If a flat shader is required for a face, ensure that all vertex normals of the face are approximately equal.
		</member>
	</members>
</class>


# Basic GDScript module architecture
This provides some basic information in how GDScript is implemented and integrates with the rest of the engine. You can learn more about GDScript in the [documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/index.html). It describes the syntax and user facing systems and concepts, and can be used as a reference for what user expectations are.

## General design

GDScript is:

1. A [gradually typed](https://en.wikipedia.org/wiki/Gradual_typing) language. Type hints are optional and help with static analysis and performance. However, typed code must easily interoperate with untyped code.
2. A tightly designed language. Features are added because they are _needed_, and not because they can be added or are interesting to develop.
3. Primarily an interpreted scripting language: it is compiled to GDScript byte code and interpreted in a GDScript virtual machine. It is meant to be easy to use and develop gameplay in. It is not meant for CPU-intensive algorithms or data processing, and is not optimized for it. For that, [C#](https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_basics.html) or [GDExtension](https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/what_is_gdextension.html) may be used.

## Integration into Godot

GDScript is integrated into Godot as a module. Since modules are optional, this means that Godot may be built without GDScript and work perfectly fine without it!

The GDScript module interfaces with Godot's codebase by inheriting from the engine's scripting-related classes. New languages inherit from [`ScriptLanguage`](/core/object/script_language.h), and are registered in Godot's [`ScriptServer`](/core/object/script_language.h). Scripts, referring to a file containing code, are represented in the engine by the `Script` class. Instances of that script, which are used at runtime when actually executing the code, inherit from [`ScriptInstance`](/core/object/script_instance.h).

To access Godot's internal classes, GDScript uses [`ClassDB`](/core/object/class_db.h). `ClassDB` is where Godot registers classes, methods and properties that it wants exposed to its scripting system. This is how GDScript understands that `Node2D` is a class it can use, and that it has a `get_parent()` method.

[Built-in GDScript methods](https://docs.godotengine.org/en/latest/classes/class_@gdscript.html#methods) are defined and exported by [`GDScriptUtilityFunctions`](gdscript_utility_functions.h), whereas [global scope methods](https://docs.godotengine.org/en/latest/classes/class_%2540globalscope.html) are registered in [`Variant::_register_variant_utility_functions()`](/core/variant/variant_utility.cpp).

## Compilation

Scripts can be at different stages of compilation. The process isn't entirely linear, but consists of this general order: tokenizing, parsing, analyzing, and finally compiling. This process is the same for scripts in the editor and scripts in an exported game. Scripts are stored as text files in both cases, and the compilation process must happen in full before the bytecode can be passed to the virtual machine and run.

The main class of the GDScript module is the [`GDScript`](gdscript.h) class, which represents a class defined in GDScript. Each `.gd` file is called a _class file_ because it implicitly defines a class in GDScript, and thus results in an associated `GDScript` object. However, GDScript classes may define [_inner classes_](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#inner-classes), and those are also represented by further `GDScript` objects, even though they are not in files of their own.

The `GDScript` class contains all the information related to the corresponding GDScript class: its name and path, its members like variables, functions, symbols, signals, implicit methods like initializers, etc. This is the main class that the compilation step deals with.

A secondary class is `GDScriptInstance`, defined in the same file, containing _runtime_ information for an instance of a `GDScript`, and is more related to the execution of a script by the virtual machine.

### Loading source code

This mostly happens by calling `GDScript::load_source_code()` on a `GDScript` object. Parsing only requires a `String`, so it is entirely possible to parse a script without a `GDScript` object!

### Tokenizing (see [`GDScriptTokenizer`](gdscript_tokenizer.h))

Tokenizing is the process of converting the source code `String` into a sequence of tokens, which represent language constructs (such as `for` or `if`), identifiers, literals, etc. This happens almost exclusively during the parsing process, which asks for the next token in order to make sense of the source code. The tokenizer is only used outside of the parsing process in very rare exceptions.

### Parsing (see [`GDScriptParser`](gdscript_parser.h))

The parser takes a sequence of tokens and builds [the abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of the GDScript program. The AST is used in the analyzing and compilation steps, and the source code `String` and sequence of tokens are discarded. The AST-building process finds syntax errors in a GDScript program and reports them to the user.

The parser class also defines all the possible nodes of the AST as subtypes of `GDScriptParser::Node`, not to be confused with Godot's scene tree `Node`. For example, `GDScriptParser::IfNode` has two children nodes, one for the code in the `if` block, and one for the code in the `else` block. A `GDScriptParser::FunctionNode` contains children nodes for its name, parameters, return type, body, etc. The parser also defines typechecking data structures like `GDScriptParser::Datatype`.

The parser was [intentionally designed](https://godotengine.org/article/gdscript-progress-report-writing-new-parser/#less-lookahead) with a look-ahead of a single token. This means that the parser only has access to the current token and the previous token (or, if you prefer, the current token and the next token). This parsing limitation ensures that GDScript will remain syntactically simple and accessible, and that the parsing process cannot become overly complex.


### Analysis and typechecking (see [`GDScriptAnalyzer`](gdscript_analyzer.h))

The analyzer takes in the AST of a program and verifies that "everything checks out". For example, when analyzing a method call with three parameters, it will check whether the function definition also contains three parameters. If the code is typed, it will check that argument and parameter types are compatible.

There are two types of functions in the analyzer: `reduce` functions and `resolve` functions. Their parameters always include the AST node that they are attempting to reduce or resolve.
- The `reduce` functions work on GDScript expressions, which return values, and thus their main goal is to populate the `GDScriptParser::Datatype` of the underlying AST node. The datatype is then used to typecheck code that depends on this expression, and gives the compiler necessary information to generate appropriate, safe, and optimized bytecode.
For example, function calls are handled with `reduce_call()`, which must figure out what function is being called and check that the passed arguments match the function's parameters. The type of the underlying `CallNode` will be the return type of the function.
Another example is `reduce_identifier()`, which does _a lot_ of work: given the string of its `IdentifierNode`, it must figure out what that identifier refers to. It could be a local variable, class name, global or class function, function parameter, class or superclass member, or any number of other things. It has to check many different places to find this information!
A secondary goal of the `reduce` functions is to perform [constant folding](https://en.wikipedia.org/wiki/Constant_folding): to determine whether an expression is constant, and if it is, compute its _reduced value_ at this time so it does not need to be computed over and over at runtime!
- The resolve functions work on AST nodes that represent statements, and don't necessarily have values. Their goal is to do work related to program control flow, resolve their child AST nodes, deal with scoping, etc. One of the simplest examples is `resolve_if()`, which reduces the `if` condition, then resolves the `if` body and `else` body if it exists.
The `resolve_for()` function does more work than simply resolving its code block. With `for i in range(10)`, for example, it must also declare and type the new variable `i` within the scope of its code block, as well as make sure `range(10)` is iterable, among other things.
To understand classes and inheritance without introducing cyclic dependency problems that would come from immediate full class code analysis, the analyzer often asks only for class _interfaces_: it needs to know what member variables and methods exist as well as their types, but no more.
This is done through `resolve_class_interface()`, which populates `ClassNode`'s `Datatype` with that information. It first checks for superclass information with `resolve_class_inheritance()`, then populates its member information by calling `resolve_class_member()` on each member. Since this step is only about the class _interface_, methods are resolved with `resolve_function_signature()`, which gets all relevant typing information without resolving the function body!
The remaining steps of resolution, including member variable initialization code, method code, etc, can happen at a later time.

In fully untyped code, very little static analysis is possible. For example, the analyzer cannot know whether `my_var.some_member` exists when it does not know the type of `my_var`. Therefore, it cannot emit a warning or error because `some_member` _could_ exist - or it could not. The analyzer must trust the programmer. If an error does occur, it will be at runtime.
However, GDScript is gradually typed, so all of these analyses must work when parts of the code are typed and others untyped. Static analysis in a gradually typed language is a best-effort situation: suppose there is a typed variable `var x : int`, and an untyped `var y = "some string"`. We can obviously tell this isn't going to work, but the analyzer will accept the assignment `x = y` without warnings or errors: it only knows that `y` is untyped and can therefore be anything, including the `int` that `x` expects. It must once again trust the programmer to have written code that works. In this instance, the code will error at runtime.
In both these cases, the analyzer handles the uncertainty of untyped code by calling `mark_node_unsafe()` on the respective AST node. This means it didn't have enough information to know whether the code was fully safe or necessarily wrong. Lines with unsafe AST nodes are represented by gray line numbers in the GDScript editor. Green line numbers indicate a line of code without any unsafe nodes.

This analysis step is also where dependencies are introduced and that information stored for use later. If class `A` extends class `B` or contains a member with type `B` from some other script file, then the analyzer will attempt to load that second script. If `B` contains references to `A`, then a _cyclic_ dependency is introduced. This is OK in many cases, but impossible to resolve in others.

Clearly, the analyzer is where a lot of the "magic" happens! It determines what constitutes proper code that can actually be compiled, and provides as many safety guarantees as possible with the typing information it is provided with. The more typed the code, the safer and more optimized it will be!

#### Cyclic dependencies and member resolution

Cyclic dependencies from inheritance (`A extends B, B extends A`) are not supported in any programming language. Other cyclic dependencies are supported, such as `A extends B` and `B` uses, contains, or preloads, members of type `A`.

To see why cyclic dependencies are complicated, suppose there is one between classes `A <-> B`. Partially through the analysis of `A`, we will need information about `B`, and therefore trigger its analysis. However, the analysis of `B` will eventually need information from `A`, which is incomplete because we never finished analyzing it. This would result in members not being found when they actually exist!

GDScript supports cyclic dependencies due to a few features of the analyzer:

1. Class interface resolution: when analyzing code of class `A` that depends on some other class `B`, we don't need to resolve the _code_ of `B` (its member initializers, function code, etc). We only need to know what members and methods the class has, as well as their types. These are the only things one class can use to work with, or _interface_ with, another. Because of inheritance, a class's interface depends on its superclass as well, so recursive interface resolution is needed. More details can be found in `GDScriptAnalyzer::resolve_class_interface()`.
2. Out of order member resolution: the analyzer may not even need an entire class interface to be resolved in order to figure out a specific type! For example, if class `A` contains code that references `B.is_alive`, then the analyzer doesn't need to immediately resolve `B`'s entire interface. It may simply check whether `is_alive` exists in `B`, and reduce it for its type information, on-demand.
A fundamental cyclic dependency problem occurs when the types of two different member variables are mutually dependent. This is commonly checked by a pattern that declares a temporary datatype with `GDScriptParser::DataType resolving_datatype;`, followed by `resolving_datatype.kind = GDScriptParser::DataType::RESOLVING;`. If the analyzer attempts to resolve a member on-demand that is already tagged as resolving, then a cyclic dependency problem has been found and can be reported.


### Compiling (see [`GDScriptCompiler`](gdscript_compiler.h))

Compiling is the final step in making a GDScript executable in the [virtual machine](gdscript_vm.h) (VM). The compiler takes a `GDScript` object and an AST, and uses another class, [`GDScriptByteCodeGenerator`](gdscript_byte_codegen.h), to generate bytecode corresponding to the class. In doing this, it creates the objects that the VM understands how to run, like [`GDScriptFunction`](gdscript_function.h), and completes a few extra tasks needed for compilation, such as populating runtime class member information.

Importantly, the compilation process of a class, specifically the `GDScriptCompiler::_compile_class()` method, _cannot_ depend on information obtained by calling `GDScriptCompiler::_compile_class()` on another class, for the same cyclic dependency reasons explained in the previous section.
Any information that can only be obtained or populated during the compilation step, when `GDScript` objects become available, must be handled before `GDScriptCompiler::_compile_class()` is called. This process is centralized in `GDScriptCompiler::_prepare_compilation()` which works as the compile-time equivalent of `GDScriptAnalyzer::resolve_class_interface()`: it populates a `GDScript`'s "interface" exclusively with information from the analysis step, and without processing other external classes. This information may then be referenced by other classes without introducing problematic cycles.

The more typing information a GDScript has, the more optimized the compiled bytecode can be. For example, if `my_var` is untyped, the bytecode for `my_var.some_member` will need to go through several layers of indirection to figure out the type of `my_var` at runtime, and from there determine how to obtain `some_member`. This varies depending on whether `my_var` is a dictionary, a script, or a native class. If the type of `my_var` was known at compile time, the bytecode can directly call the type-specific method for obtaining a member.
Similar optimizations are possible for `my_var.some_func()`. With untyped GDScript, the VM will need to resolve `my_var`'s type at runtime, then, depending on the type, use different methods to resolve the function and call it. When the function is fully resolved during static analysis, native function pointers or GDScript function objects can be compiled into the bytecode and directly called by the VM, removing several layers of indirection.

Typed code is safer code and faster code!

## Loading scripts

GDScripts can be loaded in a couple of different ways. The main method, used almost everywhere in the engine, is to load scripts through the `ResourceLoader` singleton. In this way, GDScripts are resources like any others: `ResourceLoader::load()` will simply reroute to `ResourceFormatLoaderGDScript::load()`, found in `gdscript.h/cpp`(gdscript.h). This generates a GDScript object which is compiled and ready to use.

The other method is to manually load the source code, then pass it to a parser, then to an analyzer and then to a compiler. The previous approach does this behind the scenes, alongside some smart caching of scripts and other functionalities. It is used in the [GDScript test runner infrastructure](tests/gdscript_test_runner.h).

### Full and shallow scripts

The `ResourceFormatLoaderGDScript::load()` method simply calls `GDScriptCache::get_full_script()`. The [`GDScriptCache`](gdscript_cache.h) is, as it sounds, a cache for GDScripts. Its two main methods, `get_shallow_script()` and `get_full_script()`, get and cache, respectively, scripts that have been merely parsed, and scripts which have been statically analyzed and fully compiled. Another internal class, `GDScriptParserRef`, found in the same file, provides even more granularity over the different steps of the parsing process, and is used extensively in the analyzer.

Shallow, or "just parsed" scripts, provide information such as defined classes, class members, and so forth. This is sufficient for many purposes, like obtaining a class interface or checking whether a member exists on a specific class. Full scripts, on the other hand, have been analyzed and compiled and are ready to use.

The distinction between full and shallow scripts is very important, as shallow scripts cannot create cyclic dependency problems, whereas full scripts can. The analyzer, for example, never asks for full scripts. Choosing when to request a shallow vs a full script is an important but subtle decision.

In practice, full scripts are simply scripts where `GDScript::reload()` has been called. This critical function is the primary way in which scripts get compiled in Godot, and essentially does all the compilation steps covered so far in order. Whenever a script is loaded, or updated and reloaded in Godot, it will end up going through `GDScript::reload()`, except in very rare circumstances like the test runner. It is an excellent place to start reading and understanding the GDScript module!

## Special types of scripts

Certain types of GDScripts behave slightly differently. For example, autoloads are loaded with `ResourceLoader::load()` during `Main::start()`, very soon after Godot is launched. Many systems aren't initialized at that time, so error reporting is often significantly reduced and may not even show up in the editor.

Tool scripts, declared with the `@tool` annotation on a GDScript file, run in the editor itself as opposed to just when the game is launched. This leads to a significant increase in complexity, as many things that can be changed in the editor may affect a currently executing tool script.

## Other

There are many other classes in the GDScript module. Here is a brief overview of some of them:

- Declaration of GDScript warnings in [`GDScriptWarning`](gdscript_warning.h).
- [`GDScriptFunction`](gdscript_function.h), which represents an executable GDScript function. The relevant file contains both static as well as runtime information.
- The [virtual machine](gdscript_vm.cpp) is essentially defined as calling `GDScriptFunction::call()`.
- Editor-related functions can be found in parts of `GDScriptLanguage`, originally declared in [`gdscript.h`](gdscript.h) but defined in [`gdscript_editor.cpp`](gdscript_editor.cpp). Code highlighting can be found in [`GDScriptSyntaxHighlighter`](editor/gdscript_highlighter.h).
- GDScript decompilation is found in [`gdscript_disassembler.cpp`](gdscript_disassembler.h), defined as `GDScriptFunction::disassemble()`.
- Documentation generation from GDScript comments in [`GDScriptDocGen`](editor/gdscript_docgen.h)


class_name Utils

# `assert()` is not evaluated in non-debug builds. Do not use `assert()`
# for anything other than testing the `assert()` itself.
static func check(condition: Variant) -> void:
	if not condition:
		printerr("Check failed.")

static func get_type(property: Dictionary, is_return: bool = false) -> String:
	match property.type:
		TYPE_NIL:
			if property.usage & PROPERTY_USAGE_NIL_IS_VARIANT:
				return "Variant"
			return "void" if is_return else "null"
		TYPE_INT:
			if property.usage & PROPERTY_USAGE_CLASS_IS_ENUM:
				if property.class_name == &"":
					return "<unknown enum>"
				return property.class_name
		TYPE_ARRAY:
			if property.hint == PROPERTY_HINT_ARRAY_TYPE:
				if str(property.hint_string).is_empty():
					return "Array[<unknown type>]"
				return "Array[%s]" % property.hint_string
		TYPE_DICTIONARY:
			if property.hint == PROPERTY_HINT_DICTIONARY_TYPE:
				if str(property.hint_string).is_empty():
					return "Dictionary[<unknown type>, <unknown type>]"
				return "Dictionary[%s]" % str(property.hint_string).replace(";", ", ")
		TYPE_OBJECT:
			if not str(property.class_name).is_empty():
				return property.class_name
	return type_string(property.type)

static func get_property_signature(property: Dictionary, base: Object = null, is_static: bool = false) -> String:
	if property.usage & PROPERTY_USAGE_CATEGORY:
		return '@export_category("%s")' % str(property.name).c_escape()
	if property.usage & PROPERTY_USAGE_GROUP:
		return '@export_group("%s")' % str(property.name).c_escape()
	if property.usage & PROPERTY_USAGE_SUBGROUP:
		return '@export_subgroup("%s")' % str(property.name).c_escape()

	var result: String = ""
	if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
		printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.")
	if is_static:
		result += "static "
	result += "var " + property.name + ": " + get_type(property)
	if is_instance_valid(base):
		result += " = " + var_to_str(base.get(property.name))
	return result

static func get_human_readable_hint_string(property: Dictionary) -> String:
	if property.type >= TYPE_ARRAY and property.hint == PROPERTY_HINT_TYPE_STRING:
		var type_hint_prefixes: String = ""
		var hint_string: String = property.hint_string

		while true:
			if not hint_string.contains(":"):
				printerr("Invalid PROPERTY_HINT_TYPE_STRING format.")
			var elem_type_hint: String = hint_string.get_slice(":", 0)
			hint_string = hint_string.substr(elem_type_hint.length() + 1)

			var elem_type: int
			var elem_hint: int

			if elem_type_hint.is_valid_int():
				elem_type = elem_type_hint.to_int()
				type_hint_prefixes += "<%s>:" % type_string(elem_type)
			else:
				if elem_type_hint.count("/") != 1:
					printerr("Invalid PROPERTY_HINT_TYPE_STRING format.")
				elem_type = elem_type_hint.get_slice("/", 0).to_int()
				elem_hint = elem_type_hint.get_slice("/", 1).to_int()
				type_hint_prefixes += "<%s>/<%s>:" % [
					type_string(elem_type),
					get_property_hint_name(elem_hint).trim_prefix("PROPERTY_HINT_"),
				]

			if elem_type < TYPE_ARRAY or hint_string.is_empty():
				break

		return type_hint_prefixes + hint_string

	return property.hint_string

static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void:
	print(get_property_signature(property, base, is_static))
	print('  hint=%s hint_string="%s" usage=%s class_name=&"%s"' % [
		get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
		get_human_readable_hint_string(property).c_escape(),
		get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
		property.class_name.c_escape(),
	])

static func get_method_signature(method: Dictionary, is_signal: bool = false) -> String:
	var result: String = ""
	if method.flags & METHOD_FLAG_STATIC:
		result += "static "
	result += ("signal " if is_signal else "func ") + method.name + "("

	var args: Array[Dictionary] = method.args
	var default_args: Array = method.default_args
	var mandatory_argc: int = args.size() - default_args.size()
	for i in args.size():
		if i > 0:
			result += ", "
		var arg: Dictionary = args[i]
		result += arg.name + ": " + get_type(arg)
		if i >= mandatory_argc:
			result += " = " + var_to_str(default_args[i - mandatory_argc])

	result += ")"
	if is_signal:
		if get_type(method.return, true) != "void":
			printerr("Signal return type must be `void`.")
	else:
		result += " -> " + get_type(method.return, true)
	return result

static func get_property_hint_name(hint: PropertyHint) -> String:
	match hint:
		PROPERTY_HINT_NONE:
			return "PROPERTY_HINT_NONE"
		PROPERTY_HINT_RANGE:
			return "PROPERTY_HINT_RANGE"
		PROPERTY_HINT_ENUM:
			return "PROPERTY_HINT_ENUM"
		PROPERTY_HINT_ENUM_SUGGESTION:
			return "PROPERTY_HINT_ENUM_SUGGESTION"
		PROPERTY_HINT_EXP_EASING:
			return "PROPERTY_HINT_EXP_EASING"
		PROPERTY_HINT_LINK:
			return "PROPERTY_HINT_LINK"
		PROPERTY_HINT_FLAGS:
			return "PROPERTY_HINT_FLAGS"
		PROPERTY_HINT_LAYERS_2D_RENDER:
			return "PROPERTY_HINT_LAYERS_2D_RENDER"
		PROPERTY_HINT_LAYERS_2D_PHYSICS:
			return "PROPERTY_HINT_LAYERS_2D_PHYSICS"
		PROPERTY_HINT_LAYERS_2D_NAVIGATION:
			return "PROPERTY_HINT_LAYERS_2D_NAVIGATION"
		PROPERTY_HINT_LAYERS_3D_RENDER:
			return "PROPERTY_HINT_LAYERS_3D_RENDER"
		PROPERTY_HINT_LAYERS_3D_PHYSICS:
			return "PROPERTY_HINT_LAYERS_3D_PHYSICS"
		PROPERTY_HINT_LAYERS_3D_NAVIGATION:
			return "PROPERTY_HINT_LAYERS_3D_NAVIGATION"
		PROPERTY_HINT_LAYERS_AVOIDANCE:
			return "PROPERTY_HINT_LAYERS_AVOIDANCE"
		PROPERTY_HINT_FILE:
			return "PROPERTY_HINT_FILE"
		PROPERTY_HINT_DIR:
			return "PROPERTY_HINT_DIR"
		PROPERTY_HINT_GLOBAL_FILE:
			return "PROPERTY_HINT_GLOBAL_FILE"
		PROPERTY_HINT_GLOBAL_DIR:
			return "PROPERTY_HINT_GLOBAL_DIR"
		PROPERTY_HINT_RESOURCE_TYPE:
			return "PROPERTY_HINT_RESOURCE_TYPE"
		PROPERTY_HINT_MULTILINE_TEXT:
			return "PROPERTY_HINT_MULTILINE_TEXT"
		PROPERTY_HINT_EXPRESSION:
			return "PROPERTY_HINT_EXPRESSION"
		PROPERTY_HINT_PLACEHOLDER_TEXT:
			return "PROPERTY_HINT_PLACEHOLDER_TEXT"
		PROPERTY_HINT_COLOR_NO_ALPHA:
			return "PROPERTY_HINT_COLOR_NO_ALPHA"
		PROPERTY_HINT_OBJECT_ID:
			return "PROPERTY_HINT_OBJECT_ID"
		PROPERTY_HINT_TYPE_STRING:
			return "PROPERTY_HINT_TYPE_STRING"
		PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE:
			return "PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE"
		PROPERTY_HINT_OBJECT_TOO_BIG:
			return "PROPERTY_HINT_OBJECT_TOO_BIG"
		PROPERTY_HINT_NODE_PATH_VALID_TYPES:
			return "PROPERTY_HINT_NODE_PATH_VALID_TYPES"
		PROPERTY_HINT_SAVE_FILE:
			return "PROPERTY_HINT_SAVE_FILE"
		PROPERTY_HINT_GLOBAL_SAVE_FILE:
			return "PROPERTY_HINT_GLOBAL_SAVE_FILE"
		PROPERTY_HINT_INT_IS_OBJECTID:
			return "PROPERTY_HINT_INT_IS_OBJECTID"
		PROPERTY_HINT_INT_IS_POINTER:
			return "PROPERTY_HINT_INT_IS_POINTER"
		PROPERTY_HINT_ARRAY_TYPE:
			return "PROPERTY_HINT_ARRAY_TYPE"
		PROPERTY_HINT_DICTIONARY_TYPE:
			return "PROPERTY_HINT_DICTIONARY_TYPE"
		PROPERTY_HINT_LOCALE_ID:
			return "PROPERTY_HINT_LOCALE_ID"
		PROPERTY_HINT_LOCALIZABLE_STRING:
			return "PROPERTY_HINT_LOCALIZABLE_STRING"
		PROPERTY_HINT_NODE_TYPE:
			return "PROPERTY_HINT_NODE_TYPE"
		PROPERTY_HINT_HIDE_QUATERNION_EDIT:
			return "PROPERTY_HINT_HIDE_QUATERNION_EDIT"
		PROPERTY_HINT_PASSWORD:
			return "PROPERTY_HINT_PASSWORD"
		PROPERTY_HINT_TOOL_BUTTON:
			return "PROPERTY_HINT_TOOL_BUTTON"

	printerr("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.")
	return "<invalid hint>"


class_name TestMemberInfo

class MyClass:
	pass

enum MyEnum {}

static var test_static_var_untyped
static var test_static_var_weak_null = null
static var test_static_var_weak_int = 1
static var test_static_var_hard_int: int

var test_var_untyped
var test_var_weak_null = null
var test_var_weak_int = 1
@export var test_var_weak_int_exported = 1
var test_var_weak_variant_type = TYPE_NIL
@export var test_var_weak_variant_type_exported = TYPE_NIL
var test_var_hard_variant: Variant
var test_var_hard_int: int
var test_var_hard_variant_type: Variant.Type
@export var test_var_hard_variant_type_exported: Variant.Type
var test_var_hard_node_process_mode: Node.ProcessMode
@warning_ignore("enum_variable_without_default")
var test_var_hard_my_enum: MyEnum
var test_var_hard_array: Array
var test_var_hard_array_int: Array[int]
var test_var_hard_array_variant_type: Array[Variant.Type]
var test_var_hard_array_node_process_mode: Array[Node.ProcessMode]
var test_var_hard_array_my_enum: Array[MyEnum]
var test_var_hard_array_resource: Array[Resource]
var test_var_hard_array_this: Array[TestMemberInfo]
var test_var_hard_array_my_class: Array[MyClass]
var test_var_hard_dictionary: Dictionary
var test_var_hard_dictionary_int_variant: Dictionary[int, Variant]
var test_var_hard_dictionary_variant_int: Dictionary[Variant, int]
var test_var_hard_dictionary_int_int: Dictionary[int, int]
var test_var_hard_dictionary_variant_type: Dictionary[Variant.Type, Variant.Type]
var test_var_hard_dictionary_node_process_mode: Dictionary[Node.ProcessMode, Node.ProcessMode]
var test_var_hard_dictionary_my_enum: Dictionary[MyEnum, MyEnum]
var test_var_hard_dictionary_resource: Dictionary[Resource, Resource]
var test_var_hard_dictionary_this: Dictionary[TestMemberInfo, TestMemberInfo]
var test_var_hard_dictionary_my_class: Dictionary[MyClass, MyClass]
var test_var_hard_resource: Resource
var test_var_hard_this: TestMemberInfo
var test_var_hard_my_class: MyClass

static func test_static_func(): pass

func test_func_implicit_void(): pass
func test_func_explicit_void() -> void: pass
func test_func_weak_null(): return null
func test_func_weak_int(): return 1
func test_func_hard_variant() -> Variant: return null
func test_func_hard_int() -> int: return 1
func test_func_args_1(_a: int, _b: Array[int], _c: Dictionary[int, int], _d: int = 1, _e = 2): pass
func test_func_args_2(_a = 1, _b = _a, _c = [2], _d = 3): pass

signal test_signal_1()
signal test_signal_2(a: Variant, b)
signal test_signal_3(a: int, b: Array[int], c: Dictionary[int, int])
signal test_signal_4(a: Variant.Type, b: Array[Variant.Type], c: Dictionary[Variant.Type, Variant.Type])
signal test_signal_5(a: MyEnum, b: Array[MyEnum], c: Dictionary[MyEnum, MyEnum])
signal test_signal_6(a: Resource, b: Array[Resource], c: Dictionary[Resource, Resource])
signal test_signal_7(a: TestMemberInfo, b: Array[TestMemberInfo], c: Dictionary[TestMemberInfo, TestMemberInfo])
signal test_signal_8(a: MyClass, b: Array[MyClass], c: Dictionary[MyClass, MyClass])

func no_exec():
	test_signal_1.emit()
	test_signal_2.emit()
	test_signal_3.emit()
	test_signal_4.emit()
	test_signal_5.emit()
	test_signal_6.emit()
	test_signal_7.emit()
	test_signal_8.emit()

func test():
	var script: Script = get_script()
	for property in script.get_property_list():
		if str(property.name).begins_with("test_"):
			print(Utils.get_property_signature(property, null, true))
	for property in get_property_list():
		if str(property.name).begins_with("test_"):
			print(Utils.get_property_signature(property))
	for method in get_method_list():
		if str(method.name).begins_with("test_"):
			print(Utils.get_method_signature(method))
	for method in get_signal_list():
		if str(method.name).begins_with("test_"):
			print(Utils.get_method_signature(method, true))


func get_parse_string(t: Variant):
	return t.parse_string

func test():
	var a: Callable = JSON.parse_string
	var b: Callable = get_parse_string(JSON)
	prints(a.call("{\"test\": \"a\"}"), a.is_valid())
	prints(b.call("{\"test\": \"b\"}"), b.is_valid())


# https://github.com/godotengine/godot/issues/72967

class CustomNode:
	extends Node

	static func test_custom_node(n: CustomNode):
		if not n:
			print("null node")

func test():
	test_typed_argument_is_null()

func get_custom_node() -> CustomNode:
	return null

func test_typed_argument_is_null():
	var node: Node = Node.new()
	print_node_name(node.get_parent())
	node.free()
	test_custom_node()

func test_custom_node():
	CustomNode.test_custom_node(get_custom_node())

func print_node_name(n: Node):
	if not n:
		print("null node")


# https://github.com/godotengine/godot/issues/90086

class MyObj:
	var obj : WeakRef

func test():
	var obj_1 = MyObj.new()
	var obj_2 = MyObj.new()
	Utils.check(obj_2.get_reference_count() == 1)
	obj_1.set(&"obj", obj_2)
	Utils.check(obj_2.get_reference_count() == 1)


# https://github.com/godotengine/godot/issues/89439

signal my_signal

func foo():
	print("Foo")
	my_signal.emit()

func bar():
	print("Bar")

func baz():
	print("Baz")

func test():
	@warning_ignore("return_value_discarded")
	my_signal.connect(foo, CONNECT_ONE_SHOT)
	@warning_ignore("return_value_discarded")
	my_signal.connect(bar, CONNECT_ONE_SHOT)
	@warning_ignore("return_value_discarded")
	my_signal.connect(baz)
	my_signal.emit()


extends Node

func my_func_1(_foo, _bar):
    pass

func my_func_2(_foo, _bar, _baz):
    pass

static func my_static_func_1(_foo, _bar):
    pass

static func my_static_func_2(_foo, _bar, _baz):
    pass

@rpc
func my_rpc_func_1(_foo, _bar):
    pass

@rpc
func my_rpc_func_2(_foo, _bar, _baz):
    pass

func test():
    # Test built-in methods.
    var builtin_callable_1 : Callable = add_to_group
    print(builtin_callable_1.get_argument_count()) # Should print 2.
    var builtin_callable_2 : Callable = find_child
    print(builtin_callable_2.get_argument_count()) # Should print 3.

    # Test built-in vararg methods.
    var builtin_vararg_callable_1 : Callable = call_thread_safe
    print(builtin_vararg_callable_1.get_argument_count()) # Should print 1.
    var builtin_vararg_callable_2 : Callable = rpc_id
    print(builtin_vararg_callable_2.get_argument_count()) # Should print 2.

    # Test plain methods.
    var callable_1 : Callable = my_func_1
    print(callable_1.get_argument_count()) # Should print 2.
    var callable_2 : Callable = my_func_2
    print(callable_2.get_argument_count()) # Should print 3.

    # Test static methods.
    var static_callable_1 : Callable = my_static_func_1
    print(static_callable_1.get_argument_count()) # Should print 2.
    var static_callable_2 : Callable = my_static_func_2
    print(static_callable_2.get_argument_count()) # Should print 3.

    # Test rpc methods.
    var rpc_callable_1 : Callable = my_rpc_func_1
    print(rpc_callable_1.get_argument_count()) # Should print 2.
    var rpc_callable_2 : Callable = my_rpc_func_2
    print(rpc_callable_2.get_argument_count()) # Should print 3.

    # Test lambdas.
    var lambda_callable_1 : Callable = func(_foo, _bar): pass
    print(lambda_callable_1.get_argument_count()) # Should print 2.
    var lambda_callable_2 : Callable = func(_foo, _bar, _baz): pass
    print(lambda_callable_2.get_argument_count()) # Should print 3.

    # Test lambdas with self.
    var lambda_self_callable_1 : Callable = func(_foo, _bar): return self
    print(lambda_self_callable_1.get_argument_count()) # Should print 2.
    var lambda_self_callable_2 : Callable = func(_foo, _bar, _baz): return self
    print(lambda_self_callable_2.get_argument_count()) # Should print 3.

    # Test bind.
    var bind_callable_1 : Callable = my_func_2.bind(1)
    print(bind_callable_1.get_argument_count()) # Should print 2.
    var bind_callable_2 : Callable = my_func_2.bind(1, 2)
    print(bind_callable_2.get_argument_count()) # Should print 1.

    # Test unbind.
    var unbind_callable_1 : Callable = my_func_2.unbind(1)
    print(unbind_callable_1.get_argument_count()) # Should print 4.
    var unbind_callable_2 : Callable = my_func_2.unbind(2)
    print(unbind_callable_2.get_argument_count()) # Should print 5.

    # Test variant callables.
    var string_tmp := String()
    var variant_callable_1 : Callable = string_tmp.replace
    print(variant_callable_1.get_argument_count()) # Should print 2.
    var variant_callable_2 : Callable = string_tmp.rsplit
    print(variant_callable_2.get_argument_count()) # Should print 3.

    # Test variant vararg callables.
    var callable_tmp := Callable()
    var variant_vararg_callable_1 : Callable = callable_tmp.call
    print(variant_vararg_callable_1.get_argument_count()) # Should print 0.
    var variant_vararg_callable_2 : Callable = callable_tmp.rpc_id
    print(variant_vararg_callable_2.get_argument_count()) # Should print 1.

    # Test global methods.
    var global_callable_1 = is_equal_approx
    print(global_callable_1.get_argument_count()) # Should print 2.
    var global_callable_2 = inverse_lerp
    print(global_callable_2.get_argument_count()) # Should print 3.

    # Test GDScript methods.
    var gdscript_callable_1 = char
    print(gdscript_callable_1.get_argument_count()) # Should print 1.
    var gdscript_callable_2 = is_instance_of
    print(gdscript_callable_2.get_argument_count()) # Should print 2.


extends Node

func test() -> void:
    var node1 := Node.new()
    node1.name = "_"
    var node2 := Node.new()
    node2.name = "Child"
    var node3 := Node.new()
    node3.name = "Child"

    add_child(node1)
    node1.add_child(node2)
    add_child(node3)

    Utils.check(get_node("_/Child") == $_/Child)


# https://github.com/godotengine/godot/issues/75658

class MyObj:
	var callable: Callable

	func run():
		callable.call()

	var prop:
		set(value):
			callable.call()
		get:
			callable.call()
			return 0

	func _on_some_signal():
		callable.call()

	func _init(p_callable: Callable):
		self.callable = p_callable

signal some_signal

var obj: MyObj

func test():
	# Call.
	obj = MyObj.new(nullify_obj)
	obj.run()
	print(obj)

	# Get.
	obj = MyObj.new(nullify_obj)
	var _aux = obj.prop
	print(obj)

	# Set.
	obj = MyObj.new(nullify_obj)
	obj.prop = 1
	print(obj)

	# Signal handling.
	obj = MyObj.new(nullify_obj)
	@warning_ignore("return_value_discarded")
	some_signal.connect(obj._on_some_signal)
	some_signal.emit()
	print(obj)

func nullify_obj():
	obj = null


GDTEST_RUNTIME_ERROR
>> SCRIPT ERROR
>> on function: test()
>> runtime/errors/callable_call_after_free_object.gd
>> 6
>> Attempt to call function 'null::is_inside_tree (Callable)' on a null instance.


extends Node

class Inner1 extends Node:
#     ^^^^^^ class1 -> class1
	var member1 := 42
	#   ^^^^^^^ class1:member1 -> class1:member1
	var member2 : int = 13
	#   ^^^^^^^ class1:member2 -> class1:member2
	var member3 = 1337
	#   ^^^^^^^ class1:member3 -> class1:member3

	signal changed(old, new)
	#      ^^^^^^^ class1:signal -> class1:signal
	func my_func(arg1: int, arg2: String, arg3):
	#    |     | |  |       |  |          ^^^^ class1:func:arg3 -> class1:func:arg3
	#    |     | |  |       ^^^^ class1:func:arg2 -> class1:func:arg2
	#    |     | ^^^^ class1:func:arg1 -> class1:func:arg1
	#    ^^^^^^^ class1:func -> class1:func
		print(arg1, arg2, arg3)
		#     |  |  |  |  ^^^^ -> class1:func:arg3
		#     |  |  ^^^^ -> class1:func:arg2
		#     ^^^^ -> class1:func:arg1
		changed.emit(arg1, arg3)
		#     |      |  |  ^^^^ -> class1:func:arg3
		#     |      ^^^^ -> class1:func:arg1
		#<^^^^^ -> class1:signal
		return arg1 + arg2.length() + arg3
		#      |  |   |  |            ^^^^ -> class1:func:arg3
		#      |  |   ^^^^ -> class1:func:arg2
		#      ^^^^ -> class1:func:arg1

class Inner2:
#     ^^^^^^ class2 -> class2
	var member1 := 42
	#   ^^^^^^^ class2:member1 -> class2:member1
	var member2 : int = 13
	#   ^^^^^^^ class2:member2 -> class2:member2
	var member3 = 1337
	#   ^^^^^^^ class2:member3 -> class2:member3

	signal changed(old, new)
	#      ^^^^^^^ class2:signal -> class2:signal
	func my_func(arg1: int, arg2: String, arg3):
	#    |     | |  |       |  |          ^^^^ class2:func:arg3 -> class2:func:arg3
	#    |     | |  |       ^^^^ class2:func:arg2 -> class2:func:arg2
	#    |     | ^^^^ class2:func:arg1 -> class2:func:arg1
	#    ^^^^^^^ class2:func -> class2:func
		print(arg1, arg2, arg3)
		#     |  |  |  |  ^^^^ -> class2:func:arg3
		#     |  |  ^^^^ -> class2:func:arg2
		#     ^^^^ -> class2:func:arg1
		changed.emit(arg1, arg3)
		#     |      |  |  ^^^^ -> class2:func:arg3
		#     |      ^^^^ -> class2:func:arg1
		#<^^^^^ -> class2:signal
		return arg1 + arg2.length() + arg3
		#      |  |   |  |            ^^^^ -> class2:func:arg3
		#      |  |   ^^^^ -> class2:func:arg2
		#      ^^^^ -> class2:func:arg1

class Inner3 extends Inner2:
#     |    |         ^^^^^^ -> class2
#     ^^^^^^ class3 -> class3
	var whatever = "foo"
	#   ^^^^^^^^ class3:whatever -> class3:whatever

	func _init():
	#    ^^^^^ class3:init
	# Note: no self-ref check here: resolves to `Object._init`.
	#       usages of `Inner3.new()` DO resolve to this `_init`
		pass

	class NestedInInner3:
	#     ^^^^^^^^^^^^^^ class3:nested1 -> class3:nested1
		var some_value := 42
		#   ^^^^^^^^^^ class3:nested1:some_value -> class3:nested1:some_value

	class AnotherNestedInInner3 extends NestedInInner3:
	#!    |                   |         ^^^^^^^^^^^^^^ -> class3:nested1
	#     ^^^^^^^^^^^^^^^^^^^^^ class3:nested2 -> class3:nested2
		var another_value := 13
		#   ^^^^^^^^^^^^^ class3:nested2:another_value -> class3:nested2:another_value

func _ready():
	var inner1 = Inner1.new()
	#   |    |   ^^^^^^ -> class1
	#   ^^^^^^ func:class1 -> func:class1
	var value1 = inner1.my_func(1,"",3)
	#   |    |   |    | ^^^^^^^ -> class1:func
	#   |    |   ^^^^^^ -> func:class1
	#   ^^^^^^ func:class1:value1 -> func:class1:value1
	var value2 = inner1.member3
	#   |    |   |    | ^^^^^^^ -> class1:member3
	#   |    |   ^^^^^^ -> func:class1
	#   ^^^^^^ func:class1:value2 -> func:class1:value2
	print(value1, value2)
	#     |    |  ^^^^^^ -> func:class1:value2
	#     ^^^^^^ -> func:class1:value1

	var inner3 = Inner3.new()
	#   |    |   |    | ^^^ -> class3:init
	#   |    |   ^^^^^^ -> class3
	#   ^^^^^^ func:class3 -> func:class3
	print(inner3)
	#     ^^^^^^ -> func:class3

	var nested1 = Inner3.NestedInInner3.new()
	#   |     |   |    | ^^^^^^^^^^^^^^ -> class3:nested1
	#   |     |   ^^^^^^ -> class3
	#   ^^^^^^^ func:class3:nested1 -> func:class3:nested1
	var value_nested1 = nested1.some_value
	#   |           |   |     | ^^^^^^^^^^ -> class3:nested1:some_value
	#   |           |   ^^^^^^^ -> func:class3:nested1
	#   ^^^^^^^^^^^^^ func:class3:nested1:value
	print(value_nested1)
	#     ^^^^^^^^^^^^^ -> func:class3:nested1:value

	var nested2 = Inner3.AnotherNestedInInner3.new()
	#   |     |   |    | ^^^^^^^^^^^^^^^^^^^^^ -> class3:nested2
	#   |     |   ^^^^^^ -> class3
	#   ^^^^^^^ func:class3:nested2 -> func:class3:nested2
	var value_nested2 = nested2.some_value
	#   |           |   |     | ^^^^^^^^^^ -> class3:nested1:some_value
	#   |           |   ^^^^^^^ -> func:class3:nested2
	#   ^^^^^^^^^^^^^ func:class3:nested2:value
	var another_value_nested2 = nested2.another_value
	#   |                   |   |     | ^^^^^^^^^^^^^ -> class3:nested2:another_value
	#   |                   |   ^^^^^^^ -> func:class3:nested2
	#   ^^^^^^^^^^^^^^^^^^^^^ func:class3:nested2:another_value_nested
	print(value_nested2, another_value_nested2)
	#     |           |  ^^^^^^^^^^^^^^^^^^^^^ -> func:class3:nested2:another_value_nested
	#     ^^^^^^^^^^^^^ -> func:class3:nested2:value


extends Node

var prop1 := 42
#   ^^^^^ prop1 -> prop1
var prop2 : int = 42
#   ^^^^^ prop2 -> prop2
var prop3 := 42:
#   ^^^^^ prop3 -> prop3
	get:
		return prop3 + 13
		#      ^^^^^ -> prop3
	set(value):
	#   ^^^^^ prop3:value -> prop3:value
		prop3 = value - 13
		#   |   ^^^^^ -> prop3:value
		#<^^^ -> prop3
var prop4: int:
#   ^^^^^ prop4 -> prop4
	get:
		return 42
var prop5 := 42:
#   ^^^^^ prop5 -> prop5
	set(value):
	#   ^^^^^ prop5:value -> prop5:value
		prop5 = value - 13
		#   |   ^^^^^ -> prop5:value
		#<^^^ -> prop5

var prop6:
#   ^^^^^ prop6 -> prop6
	get = get_prop6,
	#     ^^^^^^^^^ -> get_prop6
	set = set_prop6
	#     ^^^^^^^^^ -> set_prop6
func get_prop6():
#    ^^^^^^^^^ get_prop6 -> get_prop6
	return 42
func set_prop6(value):
#    |       | ^^^^^ set_prop6:value -> set_prop6:value
#    ^^^^^^^^^ set_prop6 -> set_prop6
	print(value)
	#     ^^^^^ -> set_prop6:value

var prop7:
#   ^^^^^ prop7 -> prop7
	get = get_prop7
	#     ^^^^^^^^^ -> get_prop7
func get_prop7():
#    ^^^^^^^^^ get_prop7 -> get_prop7
	return 42

var prop8:
#   ^^^^^ prop8 -> prop8
	set = set_prop8
	#     ^^^^^^^^^ -> set_prop8
func set_prop8(value):
#    |       | ^^^^^ set_prop8:value -> set_prop8:value
#    ^^^^^^^^^ set_prop8 -> set_prop8
	print(value)
	#     ^^^^^ -> set_prop8:value

const const_var := 42
#     ^^^^^^^^^ const_var -> const_var
static var static_var := 42
#          ^^^^^^^^^^ static_var -> static_var


extends Node

func test():
	var child = Node.new()
	child.name = "Child"
	@warning_ignore("unsafe_call_argument")
	add_child(child)
	child.owner = self

	var hey = Node.new()
	hey.name = "Hey"
	@warning_ignore("unsafe_call_argument")
	child.add_child(hey)
	hey.owner = self
	hey.unique_name_in_owner = true

	var fake_hey = Node.new()
	fake_hey.name = "Hey"
	@warning_ignore("unsafe_call_argument")
	add_child(fake_hey)
	fake_hey.owner = self

	var sub_child = Node.new()
	sub_child.name = "SubChild"
	@warning_ignore("unsafe_call_argument")
	hey.add_child(sub_child)
	sub_child.owner = self

	var howdy = Node.new()
	howdy.name = "Howdy"
	@warning_ignore("unsafe_call_argument")
	sub_child.add_child(howdy)
	howdy.owner = self
	howdy.unique_name_in_owner = true

	print(hey == $Child/Hey)
	print(howdy == $Child/Hey/SubChild/Howdy)

	print(%Hey == hey)
	print($%Hey == hey)
	print(%"Hey" == hey)
	print($"%Hey" == hey)
	print($%"Hey" == hey)
	print(%Hey/%Howdy == howdy)
	print($%Hey/%Howdy == howdy)
	print($"%Hey/%Howdy" == howdy)
	print($"%Hey"/"%Howdy" == howdy)
	print(%"Hey"/"%Howdy" == howdy)
	print($%"Hey"/"%Howdy" == howdy)
	print($"%Hey"/%"Howdy" == howdy)
	print(%"Hey"/%"Howdy" == howdy)
	print($%"Hey"/%"Howdy" == howdy)
	print(%"Hey/%Howdy" == howdy)
	print($%"Hey/%Howdy" == howdy)


class_name ExportVariableTestGlobalClass
extends Node2D


@tool
class_name ExportVariableTest
extends Node

const PreloadedGlobalClass = preload("./export_variable_global.notest.gd")
const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd")

# Built-in types.
@export var test_weak_int = 1
@export var test_hard_int: int = 2
@export_range(0, 100) var test_range = 100
@export_range(0, 100, 1) var test_range_step = 101
@export_range(0, 100, 1, "or_greater") var test_range_step_or_greater = 102
@export var test_color: Color
@export_color_no_alpha var test_color_no_alpha: Color
@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var test_node_path := ^"hello"

# Enums.
@export var test_side: Side
@export var test_atm: AutoTranslateMode

# Resources and nodes.
@export var test_image: Image
@export var test_timer: Timer

# Global custom classes.
@export var test_global_class: ExportVariableTest
@export var test_preloaded_global_class: PreloadedGlobalClass
@export var test_preloaded_unnamed_class: PreloadedUnnamedClass # GH-93168

# Arrays.
@export var test_array: Array
@export var test_array_bool: Array[bool]
@export var test_array_array: Array[Array]
@export var test_array_side: Array[Side]
@export var test_array_atm: Array[AutoTranslateMode]
@export var test_array_image: Array[Image]
@export var test_array_timer: Array[Timer]

# `@export_storage`.
@export_storage var test_storage_untyped
@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`.
@export_storage var test_storage_hard_int: int = 4

# `@export_custom`.
# NOTE: `PROPERTY_USAGE_NIL_IS_VARIANT` flag will be removed.
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_untyped
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_weak_int = 5
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_hard_int: int = 6

# `@export_tool_button`.
@export_tool_button("Click me!") var test_tool_button_1: Callable
@export_tool_button("Click me!", "ColorRect") var test_tool_button_2: Callable

func test():
	for property in get_property_list():
		if str(property.name).begins_with("test_"):
			Utils.print_property_extended_info(property, self)


hint=TYPE_STRING hint_string="<float>/<EXP_EASING>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_node_path: Array
  hint=TYPE_STRING hint_string="<NodePath>/<NODE_PATH_VALID_TYPES>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color: Array
  hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color_packed: PackedColorArray
  hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_byte_array: PackedByteArray
  hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int32_array: PackedInt32Array
  hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int64_array: PackedInt64Array
  hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_float32_array: PackedFloat32Array
  hint=TYPE_STRING hint_string="<float>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_float64_array: PackedFloat64Array
  hint=TYPE_STRING hint_string="<float>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_color_array: PackedColorArray
  hint=TYPE_STRING hint_string="<Color>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector2_array: PackedVector2Array
  hint=TYPE_STRING hint_string="<Vector2>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector3_array: PackedVector3Array
  hint=TYPE_STRING hint_string="<Vector3>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector4_array: PackedVector4Array
  hint=TYPE_STRING hint_string="<Vector4>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_byte_array: PackedByteArray
  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_int32_array: PackedInt32Array
  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_int64_array: PackedInt64Array
  hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_float32_array: PackedFloat32Array
  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_float64_array: PackedFloat64Array
  hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_noalpha_weak_packed_color_array: PackedColorArray
  hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""


@export_enum("A", "B", "C") var x: Color

func test():
    pass


@export_enum("A", "B", "C") var x: Array[Color]

func test():
	pass


func i_return_int() -> int:
	return 4

func test():
	i_return_int()
	preload("../../utils.notest.gd") # `preload` is a function-like keyword.


class A:
	func int_to_variant(_p: int): pass
	func node_to_variant(_p: Node): pass
	func node_2d_to_node(_p: Node2D): pass

	func variant_to_untyped(_p: Variant): pass
	func int_to_untyped(_p: int): pass
	func node_to_untyped(_p: Node): pass

class B extends A:
	func int_to_variant(_p: Variant): pass
	func node_to_variant(_p: Variant): pass
	func node_2d_to_node(_p: Node): pass

	func variant_to_untyped(_p): pass
	func int_to_untyped(_p): pass
	func node_to_untyped(_p): pass

func test():
	pass


class A extends RefCounted:
	pass

class B extends A:
	pass

func test():
	var builtin: Variant = 3
	Utils.check((builtin is Variant) == true)
	Utils.check((builtin is int) == true)
	Utils.check(is_instance_of(builtin, TYPE_INT) == true)
	Utils.check((builtin is float) == false)
	Utils.check(is_instance_of(builtin, TYPE_FLOAT) == false)

	const const_builtin: Variant = 3
	Utils.check((const_builtin is Variant) == true)
	Utils.check((const_builtin is int) == true)
	Utils.check(is_instance_of(const_builtin, TYPE_INT) == true)
	Utils.check((const_builtin is float) == false)
	Utils.check(is_instance_of(const_builtin, TYPE_FLOAT) == false)

	var int_array: Variant = [] as Array[int]
	Utils.check((int_array is Variant) == true)
	Utils.check((int_array is Array) == true)
	Utils.check(is_instance_of(int_array, TYPE_ARRAY) == true)
	Utils.check((int_array is Array[int]) == true)
	Utils.check((int_array is Array[float]) == false)
	Utils.check((int_array is int) == false)
	Utils.check(is_instance_of(int_array, TYPE_INT) == false)

	var const_int_array: Variant = [] as Array[int]
	Utils.check((const_int_array is Variant) == true)
	Utils.check((const_int_array is Array) == true)
	Utils.check(is_instance_of(const_int_array, TYPE_ARRAY) == true)
	Utils.check((const_int_array is Array[int]) == true)
	Utils.check((const_int_array is Array[float]) == false)
	Utils.check((const_int_array is int) == false)
	Utils.check(is_instance_of(const_int_array, TYPE_INT) == false)

	var b_array: Variant = [] as Array[B]
	Utils.check((b_array is Variant) == true)
	Utils.check((b_array is Array) == true)
	Utils.check(is_instance_of(b_array, TYPE_ARRAY) == true)
	Utils.check((b_array is Array[B]) == true)
	Utils.check((b_array is Array[A]) == false)
	Utils.check((b_array is Array[int]) == false)
	Utils.check((b_array is int) == false)
	Utils.check(is_instance_of(b_array, TYPE_INT) == false)

	var const_b_array: Variant = [] as Array[B]
	Utils.check((const_b_array is Variant) == true)
	Utils.check((const_b_array is Array) == true)
	Utils.check(is_instance_of(const_b_array, TYPE_ARRAY) == true)
	Utils.check((const_b_array is Array[B]) == true)
	Utils.check((const_b_array is Array[A]) == false)
	Utils.check((const_b_array is Array[int]) == false)
	Utils.check((const_b_array is int) == false)
	Utils.check(is_instance_of(const_b_array, TYPE_INT) == false)

	var native: Variant = RefCounted.new()
	Utils.check((native is Variant) == true)
	Utils.check((native is Object) == true)
	Utils.check(is_instance_of(native, TYPE_OBJECT) == true)
	Utils.check(is_instance_of(native, Object) == true)
	Utils.check((native is RefCounted) == true)
	Utils.check(is_instance_of(native, RefCounted) == true)
	Utils.check((native is Node) == false)
	Utils.check(is_instance_of(native, Node) == false)
	Utils.check((native is int) == false)
	Utils.check(is_instance_of(native, TYPE_INT) == false)

	var a_script: Variant = A.new()
	Utils.check((a_script is Variant) == true)
	Utils.check((a_script is Object) == true)
	Utils.check(is_instance_of(a_script, TYPE_OBJECT) == true)
	Utils.check(is_instance_of(a_script, Object) == true)
	Utils.check((a_script is RefCounted) == true)
	Utils.check(is_instance_of(a_script, RefCounted) == true)
	Utils.check((a_script is A) == true)
	Utils.check(is_instance_of(a_script, A) == true)
	Utils.check((a_script is B) == false)
	Utils.check(is_instance_of(a_script, B) == false)
	Utils.check((a_script is Node) == false)
	Utils.check(is_instance_of(a_script, Node) == false)
	Utils.check((a_script is int) == false)
	Utils.check(is_instance_of(a_script, TYPE_INT) == false)

	var b_script: Variant = B.new()
	Utils.check((b_script is Variant) == true)
	Utils.check((b_script is Object) == true)
	Utils.check(is_instance_of(b_script, TYPE_OBJECT) == true)
	Utils.check(is_instance_of(b_script, Object) == true)
	Utils.check((b_script is RefCounted) == true)
	Utils.check(is_instance_of(b_script, RefCounted) == true)
	Utils.check((b_script is A) == true)
	Utils.check(is_instance_of(b_script, A) == true)
	Utils.check((b_script is B) == true)
	Utils.check(is_instance_of(b_script, B) == true)
	Utils.check((b_script is Node) == false)
	Utils.check(is_instance_of(b_script, Node) == false)
	Utils.check((b_script is int) == false)
	Utils.check(is_instance_of(b_script, TYPE_INT) == false)

	var var_null: Variant = null
	Utils.check((var_null is Variant) == true)
	Utils.check((var_null is int) == false)
	Utils.check(is_instance_of(var_null, TYPE_INT) == false)
	Utils.check((var_null is Object) == false)
	Utils.check(is_instance_of(var_null, TYPE_OBJECT) == false)
	Utils.check((var_null is RefCounted) == false)
	Utils.check(is_instance_of(var_null, RefCounted) == false)
	Utils.check((var_null is A) == false)
	Utils.check(is_instance_of(var_null, A) == false)

	const const_null: Variant = null
	Utils.check((const_null is Variant) == true)
	Utils.check((const_null is int) == false)
	Utils.check(is_instance_of(const_null, TYPE_INT) == false)
	Utils.check((const_null is Object) == false)
	Utils.check(is_instance_of(const_null, TYPE_OBJECT) == false)
	Utils.check((const_null is RefCounted) == false)
	Utils.check(is_instance_of(const_null, RefCounted) == false)
	Utils.check((const_null is A) == false)
	Utils.check(is_instance_of(const_null, A) == false)

	print('ok')


# Untyped inline property
var prop1:
	get:
		return prop1
	set(value):
		prop1 = value

# Typed inline property
var prop2: int:
	get:
		return prop2
	set(value):
		prop2 = value

# Typed inline property with default value
var prop3: int = 1:
	get:
		return prop3
	set(value):
		prop3 = value

# Typed inline property with backing variable
var _prop4: int = 2
var prop4: int:
	get:
		return _prop4
	set(value):
		_prop4 = value

func test():
	print(prop1)
	print(prop2)
	print(prop3)
	print(prop4)

	print()

	prop1 = 1
	prop2 = 2
	prop3 = 3
	prop4 = 4

	print(prop1)
	print(prop2)
	print(prop3)
	print(prop4)


const Preloaded := preload( 'preload_script_native_type.notest.gd' )

func test() -> void:
	var inferred := Preloaded.new()
	var inferred_owner := inferred.owner

	var typed: Preloaded
	typed = Preloaded.new()
	var typed_owner := typed.owner

	print(typed_owner == inferred_owner)

	inferred.free()
	typed.free()
	print('ok')


var Value:int = 8:
	get:
		return Value
	set(v):
		Value = v

func test():
	var f:float = Value
	print(int(f))


const A = preload("preload_cyclic_reference_a.notest.gd")

static func test_cyclic_reference():
	A.test_cyclic_reference_2()

static func test_cyclic_reference_2():
	A.test_cyclic_reference_3()

static func test_cyclic_reference_3():
	print(A.WAITING_FOR)


extends Node

func test():
	var typed: Variant = get_node_or_null("does_not_exist")
	var untyped = null
	var node_1: Node = typed
	var node_2: Node = untyped
	var node_3 = typed
	var node_4 = untyped
	print(typed)
	print(untyped)
	print(node_1)
	print(node_2)
	print(node_3)
	print(node_4)


const preloaded: GDScript = preload("gdscript_to_preload.notest.gd")

func test():
	var preloaded_instance: preloaded = preloaded.new()
	print(preloaded_instance.something())


# https://github.com/godotengine/godot/issues/43221
extends Node

func test():
	name = "Node"
	print(self["name"])
	self["name"] = "Changed"
	print(name)


var _prop = 1
var prop:
	get = get_prop, set = set_prop

func get_prop():
	return _prop

func set_prop(value):
	_prop = value

func test():
	print(prop)

	prop = 2

	print(prop)


var _prop: int

# Inline getter returns int instead of String.
var prop: String:
	get:
		return _prop

func test():
	pass


var with_setter := 0:
	set(val):
		var x: String = val
		with_setter = val

func test():
	with_setter = 1
	print(with_setter)


GDTEST_ANALYZER_ERROR
Expression is of type "StringName" so it can't be of type "int".


# Doesn't produce the warning:
signal used_as_first_class_signal()
signal used_with_signal_constructor()
signal used_with_signal_emit()
signal used_with_object_emit_signal()
signal used_with_object_connect()
signal used_with_object_disconnect()
signal used_with_self_prefix()

# Produce the warning:
signal used_with_dynamic_name()
signal just_unused()
@warning_ignore("unused_signal")
signal unused_but_ignored()

func no_exec():
	print(used_as_first_class_signal)
	print(Signal(self, "used_with_signal_constructor"))
	used_with_signal_emit.emit()
	print(emit_signal("used_with_object_emit_signal"))
	print(connect("used_with_object_connect", Callable()))
	disconnect("used_with_object_disconnect", Callable())
	print(self.emit_signal("used_with_self_prefix"))

	var dynamic_name := "used_with_dynamic_name"
	print(emit_signal(dynamic_name))

func test():
	pass


func test():
	print("warn")

func get(_property: StringName) -> Variant:
	return null


<?xml version="1.0" encoding="UTF-8" ?>
<class name="GDScript" inherits="Script" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
	<brief_description>
		A script implemented in the GDScript programming language.
	</brief_description>
	<description>
		A script implemented in the GDScript programming language, saved with the [code].gd[/code] extension. The script extends the functionality of all objects that instantiate it.
		Calling [method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes.
		If you are looking for GDScript's built-in functions, see [@GDScript] instead.
	</description>
	<tutorials>
		<link title="GDScript documentation index">$DOCS_URL/tutorials/scripting/gdscript/index.html</link>
	</tutorials>
	<methods>
		<method name="new" qualifiers="vararg">
			<return type="Variant" />
			<description>
				Returns a new instance of the script.
				For example:
				[codeblock]
				var MyClass = load("myclass.gd")
				var instance = MyClass.new()
				assert(instance.get_script() == MyClass)
				[/codeblock]
			</description>
		</method>
	</methods>
</class>