summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/variant/variant.cpp3
-rw-r--r--core/variant/variant.h3
-rw-r--r--core/variant/variant_call.cpp61
-rw-r--r--doc/classes/Projection.xml12
-rw-r--r--doc/classes/Vector2.xml4
-rw-r--r--doc/classes/Vector2i.xml4
-rw-r--r--doc/classes/Vector3.xml6
-rw-r--r--doc/classes/Vector3i.xml6
-rw-r--r--doc/classes/Vector4.xml8
-rw-r--r--doc/classes/Vector4i.xml8
-rwxr-xr-xdoc/tools/make_rst.py4
-rw-r--r--editor/doc_tools.cpp17
-rw-r--r--misc/extension_api_validation/4.3-stable.expected30
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp97
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.gd28
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.out25
-rw-r--r--modules/mono/editor/bindings_generator.cpp35
-rw-r--r--tests/core/object/test_class_db.h23
24 files changed, 278 insertions, 108 deletions
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 3e74dc4e67..8aca56c1d5 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -3560,9 +3560,6 @@ bool Variant::is_ref_counted() const {
return type == OBJECT && _get_obj().id.is_ref_counted();
}
-void Variant::static_assign(const Variant &p_variant) {
-}
-
bool Variant::is_type_shared(Variant::Type p_type) {
switch (p_type) {
case OBJECT:
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 9702c67a37..babd2cf084 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -792,7 +792,6 @@ public:
String stringify(int recursion_count = 0) const;
String to_json_string() const;
- void static_assign(const Variant &p_variant);
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
static int get_constants_count_for_type(Variant::Type p_type);
static bool has_constant(Variant::Type p_type, const StringName &p_value);
@@ -801,6 +800,8 @@ public:
static void get_enums_for_type(Variant::Type p_type, List<StringName> *p_enums);
static void get_enumerations_for_enum(Variant::Type p_type, const StringName &p_enum_name, List<StringName> *p_enumerations);
static int get_enum_value(Variant::Type p_type, const StringName &p_enum_name, const StringName &p_enumeration, bool *r_valid = nullptr);
+ static bool has_enum(Variant::Type p_type, const StringName &p_enum_name);
+ static StringName get_enum_for_enumeration(Variant::Type p_type, const StringName &p_enumeration);
typedef String (*ObjectDeConstruct)(const Variant &p_object, void *ud);
typedef void (*ObjectConstruct)(const String &p_text, void *ud, Variant &r_value);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 381b848b2b..d612cb9cea 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1091,6 +1091,11 @@ struct _VariantCall {
static ConstantData *constant_data;
static void add_constant(int p_type, const StringName &p_constant_name, int64_t p_constant_value) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(constant_data[p_type].value.has(p_constant_name));
+ ERR_FAIL_COND(enum_data[p_type].value.has(p_constant_name));
+ ERR_FAIL_COND(enum_data[p_type].value_to_enum.has(p_constant_name));
+#endif
constant_data[p_type].value[p_constant_name] = p_constant_value;
#ifdef DEBUG_ENABLED
constant_data[p_type].value_ordered.push_back(p_constant_name);
@@ -1106,12 +1111,19 @@ struct _VariantCall {
struct EnumData {
HashMap<StringName, HashMap<StringName, int>> value;
+ HashMap<StringName, StringName> value_to_enum;
};
static EnumData *enum_data;
static void add_enum_constant(int p_type, const StringName &p_enum_type_name, const StringName &p_enumeration_name, int p_enum_value) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(constant_data[p_type].value.has(p_enumeration_name));
+ ERR_FAIL_COND(enum_data[p_type].value.has(p_enumeration_name));
+ ERR_FAIL_COND(enum_data[p_type].value_to_enum.has(p_enumeration_name));
+#endif
enum_data[p_type].value[p_enum_type_name][p_enumeration_name] = p_enum_value;
+ enum_data[p_type].value_to_enum[p_enumeration_name] = p_enum_type_name;
}
};
@@ -1561,6 +1573,23 @@ int Variant::get_enum_value(Variant::Type p_type, const StringName &p_enum_name,
return V->value;
}
+bool Variant::has_enum(Variant::Type p_type, const StringName &p_enum_name) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
+
+ _VariantCall::EnumData &enum_data = _VariantCall::enum_data[p_type];
+
+ return enum_data.value.has(p_enum_name);
+}
+
+StringName Variant::get_enum_for_enumeration(Variant::Type p_type, const StringName &p_enumeration) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, StringName());
+
+ _VariantCall::EnumData &enum_data = _VariantCall::enum_data[p_type];
+
+ const StringName *enum_name = enum_data.value_to_enum.getptr(p_enumeration);
+ return (enum_name == nullptr) ? StringName() : *enum_name;
+}
+
#ifdef DEBUG_METHODS_ENABLED
#define bind_method(m_type, m_method, m_arg_names, m_default_args) \
METHOD_CLASS(m_type, m_method, &m_type::m_method); \
@@ -2660,10 +2689,6 @@ static void _register_variant_builtin_constants() {
_VariantCall::add_variant_constant(Variant::COLOR, Color::get_named_color_name(i), Color::get_named_color(i));
}
- _VariantCall::add_constant(Variant::VECTOR3, "AXIS_X", Vector3::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Y", Vector3::AXIS_Y);
- _VariantCall::add_constant(Variant::VECTOR3, "AXIS_Z", Vector3::AXIS_Z);
-
_VariantCall::add_enum_constant(Variant::VECTOR3, "Axis", "AXIS_X", Vector3::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR3, "Axis", "AXIS_Y", Vector3::AXIS_Y);
_VariantCall::add_enum_constant(Variant::VECTOR3, "Axis", "AXIS_Z", Vector3::AXIS_Z);
@@ -2685,32 +2710,19 @@ static void _register_variant_builtin_constants() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_FRONT", Vector3(0, 0, 1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "MODEL_REAR", Vector3(0, 0, -1));
- _VariantCall::add_constant(Variant::VECTOR4, "AXIS_X", Vector4::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Y", Vector4::AXIS_Y);
- _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Z", Vector4::AXIS_Z);
- _VariantCall::add_constant(Variant::VECTOR4, "AXIS_W", Vector4::AXIS_W);
-
_VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_X", Vector4::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Y", Vector4::AXIS_Y);
_VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Z", Vector4::AXIS_Z);
_VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_W", Vector4::AXIS_W);
+
_VariantCall::add_variant_constant(Variant::VECTOR4, "ZERO", Vector4(0, 0, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR4, "ONE", Vector4(1, 1, 1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR4, "INF", Vector4(INFINITY, INFINITY, INFINITY, INFINITY));
- _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y);
- _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z);
-
_VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_X", Vector3i::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Y", Vector3i::AXIS_Y);
_VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Z", Vector3i::AXIS_Z);
- _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_X", Vector4i::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Y", Vector4i::AXIS_Y);
- _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Z", Vector4i::AXIS_Z);
- _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_W", Vector4i::AXIS_W);
-
_VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_X", Vector4i::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Y", Vector4i::AXIS_Y);
_VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Z", Vector4i::AXIS_Z);
@@ -2732,15 +2744,9 @@ static void _register_variant_builtin_constants() {
_VariantCall::add_variant_constant(Variant::VECTOR3I, "FORWARD", Vector3i(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3I, "BACK", Vector3i(0, 0, 1));
- _VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y);
-
_VariantCall::add_enum_constant(Variant::VECTOR2, "Axis", "AXIS_X", Vector2::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR2, "Axis", "AXIS_Y", Vector2::AXIS_Y);
- _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_X", Vector2i::AXIS_X);
- _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_Y", Vector2i::AXIS_Y);
-
_VariantCall::add_enum_constant(Variant::VECTOR2I, "Axis", "AXIS_X", Vector2i::AXIS_X);
_VariantCall::add_enum_constant(Variant::VECTOR2I, "Axis", "AXIS_Y", Vector2i::AXIS_Y);
@@ -2789,13 +2795,6 @@ static void _register_variant_builtin_constants() {
_VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1));
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_NEAR", Projection::PLANE_NEAR);
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_FAR", Projection::PLANE_FAR);
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_LEFT", Projection::PLANE_LEFT);
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_TOP", Projection::PLANE_TOP);
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_RIGHT", Projection::PLANE_RIGHT);
- _VariantCall::add_constant(Variant::PROJECTION, "PLANE_BOTTOM", Projection::PLANE_BOTTOM);
-
_VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_NEAR", Projection::PLANE_NEAR);
_VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_FAR", Projection::PLANE_FAR);
_VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_LEFT", Projection::PLANE_LEFT);
diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml
index f781083abf..091e0bf54f 100644
--- a/doc/classes/Projection.xml
+++ b/doc/classes/Projection.xml
@@ -278,22 +278,22 @@
</member>
</members>
<constants>
- <constant name="PLANE_NEAR" value="0">
+ <constant name="PLANE_NEAR" value="0" enum="Planes">
The index value of the projection's near clipping plane.
</constant>
- <constant name="PLANE_FAR" value="1">
+ <constant name="PLANE_FAR" value="1" enum="Planes">
The index value of the projection's far clipping plane.
</constant>
- <constant name="PLANE_LEFT" value="2">
+ <constant name="PLANE_LEFT" value="2" enum="Planes">
The index value of the projection's left clipping plane.
</constant>
- <constant name="PLANE_TOP" value="3">
+ <constant name="PLANE_TOP" value="3" enum="Planes">
The index value of the projection's top clipping plane.
</constant>
- <constant name="PLANE_RIGHT" value="4">
+ <constant name="PLANE_RIGHT" value="4" enum="Planes">
The index value of the projection's right clipping plane.
</constant>
- <constant name="PLANE_BOTTOM" value="5">
+ <constant name="PLANE_BOTTOM" value="5" enum="Planes">
The index value of the projection bottom clipping plane.
</constant>
<constant name="IDENTITY" value="Projection(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)">
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 78183ae36c..c03262bb33 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -424,10 +424,10 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector2(0, 0)">
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index 4afc62e038..53c7c92ca3 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -170,10 +170,10 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector2i(0, 0)">
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index c04fcd0b24..4ab3140eb6 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -421,13 +421,13 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Z" value="2">
+ <constant name="AXIS_Z" value="2" enum="Axis">
Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector3(0, 0, 0)">
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index df4624dbb1..7fe469aec0 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -168,13 +168,13 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Z" value="2">
+ <constant name="AXIS_Z" value="2" enum="Axis">
Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector3i(0, 0, 0)">
diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml
index f70c59fbef..8fa17b57e6 100644
--- a/doc/classes/Vector4.xml
+++ b/doc/classes/Vector4.xml
@@ -287,16 +287,16 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Z" value="2">
+ <constant name="AXIS_Z" value="2" enum="Axis">
Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_W" value="3">
+ <constant name="AXIS_W" value="3" enum="Axis">
Enumerated value for the W axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector4(0, 0, 0, 0)">
diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml
index b351f2ccb6..e1d65eb1b5 100644
--- a/doc/classes/Vector4i.xml
+++ b/doc/classes/Vector4i.xml
@@ -169,16 +169,16 @@
</member>
</members>
<constants>
- <constant name="AXIS_X" value="0">
+ <constant name="AXIS_X" value="0" enum="Axis">
Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Y" value="1">
+ <constant name="AXIS_Y" value="1" enum="Axis">
Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_Z" value="2">
+ <constant name="AXIS_Z" value="2" enum="Axis">
Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
- <constant name="AXIS_W" value="3">
+ <constant name="AXIS_W" value="3" enum="Axis">
Enumerated value for the W axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector4i(0, 0, 0, 0)">
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index e1a6aa4a98..38e3edef2f 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -1555,9 +1555,7 @@ def make_enum(t: str, is_bitfield: bool, state: State) -> str:
else:
return f":ref:`{e}<enum_{c}_{e}>`"
- # Don't fail for `Vector3.Axis`, as this enum is a special case which is expected not to be resolved.
- if f"{c}.{e}" != "Vector3.Axis":
- print_error(f'{state.current_class}.xml: Unresolved enum "{t}".', state)
+ print_error(f'{state.current_class}.xml: Unresolved enum "{t}".', state)
return t
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 79e0c7ebd1..842c4acce0 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -908,6 +908,23 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
c.properties.sort();
+ List<StringName> enums;
+ Variant::get_enums_for_type(Variant::Type(i), &enums);
+
+ for (const StringName &E : enums) {
+ List<StringName> enumerations;
+ Variant::get_enumerations_for_enum(Variant::Type(i), E, &enumerations);
+
+ for (const StringName &F : enumerations) {
+ DocData::ConstantDoc constant;
+ constant.name = F;
+ constant.value = itos(Variant::get_enum_value(Variant::Type(i), E, F));
+ constant.is_value_valid = true;
+ constant.enumeration = E;
+ c.constants.push_back(constant);
+ }
+ }
+
List<StringName> constants;
Variant::get_constants_for_type(Variant::Type(i), &constants);
diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected
index 3d862b10c1..506844e6d6 100644
--- a/misc/extension_api_validation/4.3-stable.expected
+++ b/misc/extension_api_validation/4.3-stable.expected
@@ -129,3 +129,33 @@ GH-98972
Validate extension JSON: Error: Field 'classes/TranslationServer/methods/standardize_locale/arguments': size changed value in new API, from 1 to 2.
Optional argument added. Compatibility method registered.
+
+
+GH-99424
+--------
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_BOTTOM
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_FAR
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_LEFT
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_NEAR
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_RIGHT
+Validate extension JSON: API was removed: builtin_classes/Projection/constants/PLANE_TOP
+Validate extension JSON: API was removed: builtin_classes/Vector2/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector2/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector2i/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector2i/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector3/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector3/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector3/constants/AXIS_Z
+Validate extension JSON: API was removed: builtin_classes/Vector3i/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector3i/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector3i/constants/AXIS_Z
+Validate extension JSON: API was removed: builtin_classes/Vector4/constants/AXIS_W
+Validate extension JSON: API was removed: builtin_classes/Vector4/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector4/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector4/constants/AXIS_Z
+Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXIS_W
+Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXIS_X
+Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXIS_Y
+Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXIS_Z
+
+These constants have been replaced with corresponding enum constants.
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 6241ada06a..af92450835 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -169,7 +169,9 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_enum_n
GDScriptParser::DataType type = make_enum_type(p_enum_name, native_base, p_meta);
if (p_meta) {
- type.builtin_type = Variant::NIL; // Native enum types are not Dictionaries.
+ // Native enum types are not dictionaries.
+ type.builtin_type = Variant::NIL;
+ type.is_pseudo_type = true;
}
List<StringName> enum_values;
@@ -182,10 +184,29 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_enum_n
return type;
}
+static GDScriptParser::DataType make_builtin_enum_type(const StringName &p_enum_name, Variant::Type p_type, bool p_meta = true) {
+ GDScriptParser::DataType type = make_enum_type(p_enum_name, Variant::get_type_name(p_type), p_meta);
+ if (p_meta) {
+ // Built-in enum types are not dictionaries.
+ type.builtin_type = Variant::NIL;
+ type.is_pseudo_type = true;
+ }
+
+ List<StringName> enum_values;
+ Variant::get_enumerations_for_enum(p_type, p_enum_name, &enum_values);
+
+ for (const StringName &E : enum_values) {
+ type.enum_values[E] = Variant::get_enum_value(p_type, p_enum_name, E);
+ }
+
+ return type;
+}
+
static GDScriptParser::DataType make_global_enum_type(const StringName &p_enum_name, const StringName &p_base, bool p_meta = true) {
GDScriptParser::DataType type = make_enum_type(p_enum_name, p_base, p_meta);
if (p_meta) {
- type.builtin_type = Variant::NIL; // Native enum types are not Dictionaries.
+ // Global enum types are not dictionaries.
+ type.builtin_type = Variant::NIL;
type.is_pseudo_type = true;
}
@@ -703,8 +724,8 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
if (first == SNAME("Variant")) {
if (p_type->type_chain.size() == 2) {
// May be nested enum.
- StringName enum_name = p_type->type_chain[1]->name;
- StringName qualified_name = String(first) + ENUM_SEPARATOR + String(p_type->type_chain[1]->name);
+ const StringName enum_name = p_type->type_chain[1]->name;
+ const StringName qualified_name = String(first) + ENUM_SEPARATOR + String(p_type->type_chain[1]->name);
if (CoreConstants::is_global_enum(qualified_name)) {
result = make_global_enum_type(enum_name, first, true);
return result;
@@ -719,21 +740,34 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
result.kind = GDScriptParser::DataType::VARIANT;
} else if (GDScriptParser::get_builtin_type(first) < Variant::VARIANT_MAX) {
// Built-in types.
- if (p_type->type_chain.size() > 1) {
- push_error(R"(Built-in types don't contain nested types.)", p_type->type_chain[1]);
+ const Variant::Type builtin_type = GDScriptParser::get_builtin_type(first);
+
+ if (p_type->type_chain.size() == 2) {
+ // May be nested enum.
+ const StringName enum_name = p_type->type_chain[1]->name;
+ if (Variant::has_enum(builtin_type, enum_name)) {
+ result = make_builtin_enum_type(enum_name, builtin_type, true);
+ return result;
+ } else {
+ push_error(vformat(R"(Name "%s" is not a nested type of "%s".)", enum_name, first), p_type->type_chain[1]);
+ return bad_type;
+ }
+ } else if (p_type->type_chain.size() > 2) {
+ push_error(R"(Built-in types only contain enum types, which do not have nested types.)", p_type->type_chain[2]);
return bad_type;
}
+
result.kind = GDScriptParser::DataType::BUILTIN;
- result.builtin_type = GDScriptParser::get_builtin_type(first);
+ result.builtin_type = builtin_type;
- if (result.builtin_type == Variant::ARRAY) {
+ if (builtin_type == Variant::ARRAY) {
GDScriptParser::DataType container_type = type_from_metatype(resolve_datatype(p_type->get_container_type_or_null(0)));
if (container_type.kind != GDScriptParser::DataType::VARIANT) {
container_type.is_constant = false;
result.set_container_element_type(0, container_type);
}
}
- if (result.builtin_type == Variant::DICTIONARY) {
+ if (builtin_type == Variant::DICTIONARY) {
GDScriptParser::DataType key_type = type_from_metatype(resolve_datatype(p_type->get_container_type_or_null(0)));
if (key_type.kind != GDScriptParser::DataType::VARIANT) {
key_type.is_constant = false;
@@ -3970,13 +4004,36 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
if (base.kind == GDScriptParser::DataType::BUILTIN) {
if (base.is_meta_type) {
- bool valid = true;
- Variant result = Variant::get_constant_value(base.builtin_type, name, &valid);
- if (valid) {
+ bool valid = false;
+
+ if (Variant::has_constant(base.builtin_type, name)) {
+ valid = true;
+
+ const Variant constant_value = Variant::get_constant_value(base.builtin_type, name);
+
p_identifier->is_constant = true;
- p_identifier->reduced_value = result;
- p_identifier->set_datatype(type_from_variant(result, p_identifier));
- } else if (base.is_hard_type()) {
+ p_identifier->reduced_value = constant_value;
+ p_identifier->set_datatype(type_from_variant(constant_value, p_identifier));
+ }
+
+ if (!valid) {
+ const StringName enum_name = Variant::get_enum_for_enumeration(base.builtin_type, name);
+ if (enum_name != StringName()) {
+ valid = true;
+
+ p_identifier->is_constant = true;
+ p_identifier->reduced_value = Variant::get_enum_value(base.builtin_type, enum_name, name);
+ p_identifier->set_datatype(make_builtin_enum_type(enum_name, base.builtin_type, false));
+ }
+ }
+
+ if (!valid && Variant::has_enum(base.builtin_type, name)) {
+ valid = true;
+
+ p_identifier->set_datatype(make_builtin_enum_type(name, base.builtin_type, true));
+ }
+
+ if (!valid && base.is_hard_type()) {
#ifdef SUGGEST_GODOT4_RENAMES
String rename_hint;
if (GLOBAL_GET(GDScriptWarning::get_settings_path_from_code(GDScriptWarning::RENAMED_IN_GODOT_4_HINT)).booleanize()) {
@@ -3985,9 +4042,9 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
rename_hint = " " + vformat(R"(Did you mean to use "%s"?)", renamed_identifier_name);
}
}
- push_error(vformat(R"(Cannot find constant "%s" on base "%s".%s)", name, base.to_string(), rename_hint), p_identifier);
+ push_error(vformat(R"(Cannot find member "%s" in base "%s".%s)", name, base.to_string(), rename_hint), p_identifier);
#else
- push_error(vformat(R"(Cannot find constant "%s" on base "%s".)", name, base.to_string()), p_identifier);
+ push_error(vformat(R"(Cannot find member "%s" in base "%s".)", name, base.to_string()), p_identifier);
#endif // SUGGEST_GODOT4_RENAMES
}
} else {
@@ -4029,9 +4086,9 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
rename_hint = " " + vformat(R"(Did you mean to use "%s"?)", renamed_identifier_name);
}
}
- push_error(vformat(R"(Cannot find property "%s" on base "%s".%s)", name, base.to_string(), rename_hint), p_identifier);
+ push_error(vformat(R"(Cannot find member "%s" in base "%s".%s)", name, base.to_string(), rename_hint), p_identifier);
#else
- push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier);
+ push_error(vformat(R"(Cannot find member "%s" in base "%s".)", name, base.to_string()), p_identifier);
#endif // SUGGEST_GODOT4_RENAMES
}
}
@@ -5572,7 +5629,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
} else {
Vector<String> names = String(p_property.class_name).split(ENUM_SEPARATOR);
if (names.size() == 2) {
- result = make_native_enum_type(names[1], names[0], false);
+ result = make_enum_type(names[1], names[0], false);
result.is_constant = false;
}
}
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.gd
new file mode 100644
index 0000000000..6367d50980
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.gd
@@ -0,0 +1,2 @@
+func test():
+ print(Vector3.Axis)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.out
new file mode 100644
index 0000000000..9c476031f3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_builtin_access.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Type "Axis" in base "Vector3" cannot be used on its own.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.gd
new file mode 100644
index 0000000000..badcd3a83c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.gd
@@ -0,0 +1,2 @@
+func test():
+ print(Variant.Operator)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.out
new file mode 100644
index 0000000000..191acade73
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_global_access.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Type "Operator" in base "Variant" cannot be used on its own.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.gd
new file mode 100644
index 0000000000..e07998ddf6
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.gd
@@ -0,0 +1,2 @@
+func test():
+ print(Node.ProcessMode)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.out
new file mode 100644
index 0000000000..83671fc493
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_native_access.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Type "ProcessMode" in base "Node" cannot be used on its own.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.gd b/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.gd
new file mode 100644
index 0000000000..4ccd7de994
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.gd
@@ -0,0 +1,28 @@
+extends Node
+
+@export var test_type_1 := TYPE_BOOL
+@export var test_type_2 := Variant.Type.TYPE_BOOL
+@export var test_type_3: Variant.Type
+
+@export var test_side_1 := SIDE_RIGHT
+@export var test_side_2 := Side.SIDE_RIGHT
+@export var test_side_3: Side
+
+@export var test_axis_1 := Vector3.AXIS_Y
+@export var test_axis_2 := Vector3.Axis.AXIS_Y
+@export var test_axis_3: Vector3.Axis
+
+@export var test_mode_1 := Node.PROCESS_MODE_ALWAYS
+@export var test_mode_2 := Node.ProcessMode.PROCESS_MODE_ALWAYS
+@export var test_mode_3: Node.ProcessMode
+
+func test():
+ for property in get_property_list():
+ if str(property.name).begins_with("test_"):
+ Utils.print_property_extended_info(property, self)
+
+func test_no_exec():
+ # GH-99309
+ var sprite: Sprite3D = $Sprite3D
+ sprite.axis = Vector3.AXIS_Y # No warning.
+ sprite.set_axis(Vector3.AXIS_Y) # No warning.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.out b/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.out
new file mode 100644
index 0000000000..6c45dee323
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/global_builtin_and_native_enums.out
@@ -0,0 +1,25 @@
+GDTEST_OK
+var test_type_1: Variant.Type = 1
+ hint=ENUM hint_string="Type Nil:0,Type Bool:1,Type Int:2,Type Float:3,Type String:4,Type Vector 2:5,Type Vector 2i:6,Type Rect 2:7,Type Rect 2i:8,Type Vector 3:9,Type Vector 3i:10,Type Transform 2d:11,Type Vector 4:12,Type Vector 4i:13,Type Plane:14,Type Quaternion:15,Type Aabb:16,Type Basis:17,Type Transform 3d:18,Type Projection:19,Type Color:20,Type String Name:21,Type Node Path:22,Type Rid:23,Type Object:24,Type Callable:25,Type Signal:26,Type Dictionary:27,Type Array:28,Type Packed Byte Array:29,Type Packed Int 32 Array:30,Type Packed Int 64 Array:31,Type Packed Float 32 Array:32,Type Packed Float 64 Array:33,Type Packed String Array:34,Type Packed Vector 2 Array:35,Type Packed Vector 3 Array:36,Type Packed Color Array:37,Type Packed Vector 4 Array:38,Type Max:39" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Variant.Type"
+var test_type_2: Variant.Type = 1
+ hint=ENUM hint_string="Type Nil:0,Type Bool:1,Type Int:2,Type Float:3,Type String:4,Type Vector 2:5,Type Vector 2i:6,Type Rect 2:7,Type Rect 2i:8,Type Vector 3:9,Type Vector 3i:10,Type Transform 2d:11,Type Vector 4:12,Type Vector 4i:13,Type Plane:14,Type Quaternion:15,Type Aabb:16,Type Basis:17,Type Transform 3d:18,Type Projection:19,Type Color:20,Type String Name:21,Type Node Path:22,Type Rid:23,Type Object:24,Type Callable:25,Type Signal:26,Type Dictionary:27,Type Array:28,Type Packed Byte Array:29,Type Packed Int 32 Array:30,Type Packed Int 64 Array:31,Type Packed Float 32 Array:32,Type Packed Float 64 Array:33,Type Packed String Array:34,Type Packed Vector 2 Array:35,Type Packed Vector 3 Array:36,Type Packed Color Array:37,Type Packed Vector 4 Array:38,Type Max:39" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Variant.Type"
+var test_type_3: Variant.Type = 0
+ hint=ENUM hint_string="Type Nil:0,Type Bool:1,Type Int:2,Type Float:3,Type String:4,Type Vector 2:5,Type Vector 2i:6,Type Rect 2:7,Type Rect 2i:8,Type Vector 3:9,Type Vector 3i:10,Type Transform 2d:11,Type Vector 4:12,Type Vector 4i:13,Type Plane:14,Type Quaternion:15,Type Aabb:16,Type Basis:17,Type Transform 3d:18,Type Projection:19,Type Color:20,Type String Name:21,Type Node Path:22,Type Rid:23,Type Object:24,Type Callable:25,Type Signal:26,Type Dictionary:27,Type Array:28,Type Packed Byte Array:29,Type Packed Int 32 Array:30,Type Packed Int 64 Array:31,Type Packed Float 32 Array:32,Type Packed Float 64 Array:33,Type Packed String Array:34,Type Packed Vector 2 Array:35,Type Packed Vector 3 Array:36,Type Packed Color Array:37,Type Packed Vector 4 Array:38,Type Max:39" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Variant.Type"
+var test_side_1: Side = 2
+ hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side"
+var test_side_2: Side = 2
+ hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side"
+var test_side_3: Side = 0
+ hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side"
+var test_axis_1: Vector3.Axis = 1
+ hint=ENUM hint_string="Axis X:0,Axis Y:1,Axis Z:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Vector3.Axis"
+var test_axis_2: Vector3.Axis = 1
+ hint=ENUM hint_string="Axis X:0,Axis Y:1,Axis Z:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Vector3.Axis"
+var test_axis_3: Vector3.Axis = 0
+ hint=ENUM hint_string="Axis X:0,Axis Y:1,Axis Z:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Vector3.Axis"
+var test_mode_1: Node.ProcessMode = 3
+ hint=ENUM hint_string="Process Mode Inherit:0,Process Mode Pausable:1,Process Mode When Paused:2,Process Mode Always:3,Process Mode Disabled:4" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.ProcessMode"
+var test_mode_2: Node.ProcessMode = 3
+ hint=ENUM hint_string="Process Mode Inherit:0,Process Mode Pausable:1,Process Mode When Paused:2,Process Mode Always:3,Process Mode Disabled:4" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.ProcessMode"
+var test_mode_3: Node.ProcessMode = 0
+ hint=ENUM hint_string="Process Mode Inherit:0,Process Mode Pausable:1,Process Mode When Paused:2,Process Mode Always:3,Process Mode Disabled:4" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.ProcessMode"
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index c54d58d6a0..d0797282de 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -5040,22 +5040,25 @@ void BindingsGenerator::_populate_global_constants() {
}
}
- // HARDCODED
- List<StringName> hardcoded_enums;
- hardcoded_enums.push_back("Vector2.Axis");
- hardcoded_enums.push_back("Vector2I.Axis");
- hardcoded_enums.push_back("Vector3.Axis");
- hardcoded_enums.push_back("Vector3I.Axis");
- for (const StringName &enum_cname : hardcoded_enums) {
- // These enums are not generated and must be written manually (e.g.: Vector3.Axis)
- // Here, we assume core types do not begin with underscore
- TypeInterface enum_itype;
- enum_itype.is_enum = true;
- enum_itype.name = enum_cname.operator String();
- enum_itype.cname = enum_cname;
- enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name);
- TypeInterface::postsetup_enum_type(enum_itype);
- enum_types.insert(enum_itype.cname, enum_itype);
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ if (i == Variant::OBJECT) {
+ continue;
+ }
+
+ const Variant::Type type = Variant::Type(i);
+
+ List<StringName> enum_names;
+ Variant::get_enums_for_type(type, &enum_names);
+
+ for (const StringName &enum_name : enum_names) {
+ TypeInterface enum_itype;
+ enum_itype.is_enum = true;
+ enum_itype.name = Variant::get_type_name(type) + "." + enum_name;
+ enum_itype.cname = enum_itype.name;
+ enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name);
+ TypeInterface::postsetup_enum_type(enum_itype);
+ enum_types.insert(enum_itype.cname, enum_itype);
+ }
}
}
diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h
index 924e93129d..b38d3d3e61 100644
--- a/tests/core/object/test_class_db.h
+++ b/tests/core/object/test_class_db.h
@@ -863,16 +863,19 @@ void add_global_enums(Context &r_context) {
}
}
- // HARDCODED
- List<StringName> hardcoded_enums;
- hardcoded_enums.push_back("Vector2.Axis");
- hardcoded_enums.push_back("Vector2i.Axis");
- hardcoded_enums.push_back("Vector3.Axis");
- hardcoded_enums.push_back("Vector3i.Axis");
- for (const StringName &E : hardcoded_enums) {
- // These enums are not generated and must be written manually (e.g.: Vector3.Axis)
- // Here, we assume core types do not begin with underscore
- r_context.enum_types.push_back(E);
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ if (i == Variant::OBJECT) {
+ continue;
+ }
+
+ const Variant::Type type = Variant::Type(i);
+
+ List<StringName> enum_names;
+ Variant::get_enums_for_type(type, &enum_names);
+
+ for (const StringName &enum_name : enum_names) {
+ r_context.enum_types.push_back(Variant::get_type_name(type) + "." + enum_name);
+ }
}
}