Merge pull request #99424 from dalexeev/core-fix-builtin-enum-const-binds
Core: Fix built-in enum constant bindings
This commit is contained in:
commit
ea3154a0d4
24 changed files with 279 additions and 109 deletions
|
|
@ -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);
|
||||
|
||||
if (result.builtin_type == Variant::ARRAY) {
|
||||
result.kind = GDScriptParser::DataType::BUILTIN;
|
||||
result.builtin_type = builtin_type;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
func test():
|
||||
print(Vector3.Axis)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
Type "Axis" in base "Vector3" cannot be used on its own.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
func test():
|
||||
print(Variant.Operator)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
Type "Operator" in base "Variant" cannot be used on its own.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
func test():
|
||||
print(Node.ProcessMode)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
Type "ProcessMode" in base "Node" cannot be used on its own.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue