summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-04-17 10:59:07 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-04-17 10:59:07 +0200
commit82b36cccc7b99df18314c12df3815d168621352a (patch)
tree69d65563fda46f5fb3aadc539208e8749bf00f52 /modules
parent01eb81ba481317e0112caea16aae60c419af480c (diff)
parentf9048fcd7d2bee9cc0a23a76269c52d637b6a5bf (diff)
downloadredot-engine-82b36cccc7b99df18314c12df3815d168621352a.tar.gz
Merge pull request #90756 from vnen/gdscript-warning-enum-without-default
GDScript: Warn when enum variable has no default
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp12
-rw-r--r--modules/gdscript/gdscript_warning.cpp4
-rw-r--r--modules/gdscript/gdscript_warning.h2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.out7
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/member_info.gd1
6 files changed, 35 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index b198338ff0..cd19887d82 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -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
diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp
index 708966a0a8..48a0abe617 100644
--- a/modules/gdscript/gdscript_warning.cpp
+++ b/modules/gdscript/gdscript_warning.cpp
@@ -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",
diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h
index 93c232a0f8..3ad9488138 100644
--- a/modules/gdscript/gdscript_warning.h
+++ b/modules/gdscript/gdscript_warning.h
@@ -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
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd
new file mode 100644
index 0000000000..13e3edf93f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd
@@ -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)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.out b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.out
new file mode 100644
index 0000000000..ae40e0bc8c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.out
@@ -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
diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info.gd b/modules/gdscript/tests/scripts/runtime/features/member_info.gd
index d7485f49e6..42b29eee43 100644
--- a/modules/gdscript/tests/scripts/runtime/features/member_info.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/member_info.gd
@@ -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]