GDScript: Warn when enum variable has no default
The default will always be set to `0`, so if it's not a valid value in the enum, the warning is shown.
This commit is contained in:
parent
658e97c93a
commit
f9048fcd7d
7 changed files with 38 additions and 0 deletions
|
@ -488,6 +488,9 @@
|
|||
<member name="debug/gdscript/warnings/enable" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], enables specific GDScript warnings (see [code]debug/gdscript/warnings/*[/code] settings). If [code]false[/code], disables all GDScript warnings.
|
||||
</member>
|
||||
<member name="debug/gdscript/warnings/enum_variable_without_default" type="int" setter="" getter="" default="1">
|
||||
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a variable has an enum type but no explicit default value, but only if the enum does not contain [code]0[/code] as a valid value.
|
||||
</member>
|
||||
<member name="debug/gdscript/warnings/exclude_addons" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], scripts in the [code]res://addons[/code] folder will not generate warnings.
|
||||
</member>
|
||||
|
|
|
@ -1957,6 +1957,18 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
|
|||
} else {
|
||||
parser->push_warning(p_assignable, GDScriptWarning::UNTYPED_DECLARATION, declaration_type, p_assignable->identifier->name);
|
||||
}
|
||||
} else if (specified_type.kind == GDScriptParser::DataType::ENUM && p_assignable->initializer == nullptr) {
|
||||
// Warn about enum variables without default value. Unless the enum defines the "0" value, then it's fine.
|
||||
bool has_zero_value = false;
|
||||
for (const KeyValue<StringName, int64_t> &kv : specified_type.enum_values) {
|
||||
if (kv.value == 0) {
|
||||
has_zero_value = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_zero_value) {
|
||||
parser->push_warning(p_assignable, GDScriptWarning::ENUM_VARIABLE_WITHOUT_DEFAULT, p_assignable->identifier->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -126,6 +126,9 @@ String GDScriptWarning::get_message() const {
|
|||
case INT_AS_ENUM_WITHOUT_MATCH:
|
||||
CHECK_SYMBOLS(3);
|
||||
return vformat(R"(Cannot %s %s as Enum "%s": no enum member has matching value.)", symbols[0], symbols[1], symbols[2]);
|
||||
case ENUM_VARIABLE_WITHOUT_DEFAULT:
|
||||
CHECK_SYMBOLS(1);
|
||||
return vformat(R"(The variable "%s" has an enum type and does not set an explicit default value. The default will be set to "0".)", symbols[0]);
|
||||
case EMPTY_FILE:
|
||||
return "Empty script file.";
|
||||
case DEPRECATED_KEYWORD:
|
||||
|
@ -221,6 +224,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
|||
"NARROWING_CONVERSION",
|
||||
"INT_AS_ENUM_WITHOUT_CAST",
|
||||
"INT_AS_ENUM_WITHOUT_MATCH",
|
||||
"ENUM_VARIABLE_WITHOUT_DEFAULT",
|
||||
"EMPTY_FILE",
|
||||
"DEPRECATED_KEYWORD",
|
||||
"RENAMED_IN_GODOT_4_HINT",
|
||||
|
|
|
@ -78,6 +78,7 @@ public:
|
|||
NARROWING_CONVERSION, // Float value into an integer slot, precision is lost.
|
||||
INT_AS_ENUM_WITHOUT_CAST, // An integer value was used as an enum value without casting.
|
||||
INT_AS_ENUM_WITHOUT_MATCH, // An integer value was used as an enum value without matching enum member.
|
||||
ENUM_VARIABLE_WITHOUT_DEFAULT, // A variable with an enum type does not have a default value. The default will be set to `0` instead of the first enum value.
|
||||
EMPTY_FILE, // A script file is empty.
|
||||
DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced.
|
||||
RENAMED_IN_GODOT_4_HINT, // A variable or function that could not be found has been renamed in Godot 4.
|
||||
|
@ -129,6 +130,7 @@ public:
|
|||
WARN, // NARROWING_CONVERSION
|
||||
WARN, // INT_AS_ENUM_WITHOUT_CAST
|
||||
WARN, // INT_AS_ENUM_WITHOUT_MATCH
|
||||
WARN, // ENUM_VARIABLE_WITHOUT_DEFAULT
|
||||
WARN, // EMPTY_FILE
|
||||
WARN, // DEPRECATED_KEYWORD
|
||||
WARN, // RENAMED_IN_GODOT_4_HINT
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
enum HasZero { A = 0, B = 1 }
|
||||
enum HasNoZero { A = 1, B = 2 }
|
||||
var has_zero: HasZero # No warning, because the default `0` is valid.
|
||||
var has_no_zero: HasNoZero # Warning, because there is no `0` in the enum.
|
||||
|
||||
|
||||
func test():
|
||||
print(has_zero)
|
||||
print(has_no_zero)
|
|
@ -0,0 +1,7 @@
|
|||
GDTEST_OK
|
||||
>> WARNING
|
||||
>> Line: 4
|
||||
>> ENUM_VARIABLE_WITHOUT_DEFAULT
|
||||
>> The variable "has_no_zero" has an enum type and does not set an explicit default value. The default will be set to "0".
|
||||
0
|
||||
0
|
|
@ -23,6 +23,7 @@ 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]
|
||||
|
|
Loading…
Reference in a new issue