You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-10 13:00:37 +00:00
Merge pull request #82139 from dalexeev/gds-add-inferred-declaration-warning
GDScript: Add `INFERRED_DECLARATION` warning
This commit is contained in:
@@ -472,6 +472,10 @@
|
|||||||
<member name="debug/gdscript/warnings/inference_on_variant" type="int" setter="" getter="" default="2">
|
<member name="debug/gdscript/warnings/inference_on_variant" type="int" setter="" getter="" default="2">
|
||||||
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a static inferred type uses a [Variant] as initial value, which makes the static type to also be Variant.
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a static inferred type uses a [Variant] as initial value, which makes the static type to also be Variant.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="debug/gdscript/warnings/inferred_declaration" type="int" setter="" getter="" default="0">
|
||||||
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a variable, constant, or parameter has an implicitly inferred static type.
|
||||||
|
[b]Note:[/b] This warning is recommended [i]in addition[/i] to [member debug/gdscript/warnings/untyped_declaration] if you want to always specify the type explicitly. Having [code]INFERRED_DECLARATION[/code] warning level higher than [code]UNTYPED_DECLARATION[/code] warning level makes little sense and is not recommended.
|
||||||
|
</member>
|
||||||
<member name="debug/gdscript/warnings/int_as_enum_without_cast" type="int" setter="" getter="" default="1">
|
<member name="debug/gdscript/warnings/int_as_enum_without_cast" type="int" setter="" getter="" default="1">
|
||||||
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when trying to use an integer as an enum without an explicit cast.
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when trying to use an integer as an enum without an explicit cast.
|
||||||
</member>
|
</member>
|
||||||
|
|||||||
@@ -1936,9 +1936,14 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (!has_specified_type && !p_assignable->infer_datatype && !is_constant) {
|
if (!has_specified_type) {
|
||||||
const bool is_parameter = p_assignable->type == GDScriptParser::Node::PARAMETER;
|
const bool is_parameter = p_assignable->type == GDScriptParser::Node::PARAMETER;
|
||||||
parser->push_warning(p_assignable, GDScriptWarning::UNTYPED_DECLARATION, is_parameter ? "Parameter" : "Variable", p_assignable->identifier->name);
|
const String declaration_type = is_constant ? "Constant" : (is_parameter ? "Parameter" : "Variable");
|
||||||
|
if (p_assignable->infer_datatype || is_constant) {
|
||||||
|
parser->push_warning(p_assignable, GDScriptWarning::INFERRED_DECLARATION, declaration_type, p_assignable->identifier->name);
|
||||||
|
} else {
|
||||||
|
parser->push_warning(p_assignable, GDScriptWarning::UNTYPED_DECLARATION, declaration_type, p_assignable->identifier->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2152,7 +2157,9 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
|
|||||||
} else {
|
} else {
|
||||||
p_for->variable->set_datatype(variable_type);
|
p_for->variable->set_datatype(variable_type);
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (!variable_type.is_hard_type()) {
|
if (variable_type.is_hard_type()) {
|
||||||
|
parser->push_warning(p_for->variable, GDScriptWarning::INFERRED_DECLARATION, R"("for" iterator variable)", p_for->variable->name);
|
||||||
|
} else {
|
||||||
parser->push_warning(p_for->variable, GDScriptWarning::UNTYPED_DECLARATION, R"("for" iterator variable)", p_for->variable->name);
|
parser->push_warning(p_for->variable, GDScriptWarning::UNTYPED_DECLARATION, R"("for" iterator variable)", p_for->variable->name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ String GDScriptWarning::get_message() const {
|
|||||||
return vformat(R"*(%s "%s()" has no static return type.)*", symbols[0], symbols[1]);
|
return vformat(R"*(%s "%s()" has no static return type.)*", symbols[0], symbols[1]);
|
||||||
}
|
}
|
||||||
return vformat(R"(%s "%s" has no static type.)", symbols[0], symbols[1]);
|
return vformat(R"(%s "%s" has no static type.)", symbols[0], symbols[1]);
|
||||||
|
case INFERRED_DECLARATION:
|
||||||
|
CHECK_SYMBOLS(2);
|
||||||
|
return vformat(R"(%s "%s" has an implicitly inferred static type.)", symbols[0], symbols[1]);
|
||||||
case UNSAFE_PROPERTY_ACCESS:
|
case UNSAFE_PROPERTY_ACCESS:
|
||||||
CHECK_SYMBOLS(2);
|
CHECK_SYMBOLS(2);
|
||||||
return vformat(R"(The property "%s" is not present on the inferred type "%s" (but may be present on a subtype).)", symbols[0], symbols[1]);
|
return vformat(R"(The property "%s" is not present on the inferred type "%s" (but may be present on a subtype).)", symbols[0], symbols[1]);
|
||||||
@@ -207,6 +210,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
|||||||
"CONSTANT_USED_AS_FUNCTION",
|
"CONSTANT_USED_AS_FUNCTION",
|
||||||
"FUNCTION_USED_AS_PROPERTY",
|
"FUNCTION_USED_AS_PROPERTY",
|
||||||
"UNTYPED_DECLARATION",
|
"UNTYPED_DECLARATION",
|
||||||
|
"INFERRED_DECLARATION",
|
||||||
"UNSAFE_PROPERTY_ACCESS",
|
"UNSAFE_PROPERTY_ACCESS",
|
||||||
"UNSAFE_METHOD_ACCESS",
|
"UNSAFE_METHOD_ACCESS",
|
||||||
"UNSAFE_CAST",
|
"UNSAFE_CAST",
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ public:
|
|||||||
PROPERTY_USED_AS_FUNCTION, // Function not found, but there's a property with the same name.
|
PROPERTY_USED_AS_FUNCTION, // Function not found, but there's a property with the same name.
|
||||||
CONSTANT_USED_AS_FUNCTION, // Function not found, but there's a constant with the same name.
|
CONSTANT_USED_AS_FUNCTION, // Function not found, but there's a constant with the same name.
|
||||||
FUNCTION_USED_AS_PROPERTY, // Property not found, but there's a function with the same name.
|
FUNCTION_USED_AS_PROPERTY, // Property not found, but there's a function with the same name.
|
||||||
UNTYPED_DECLARATION, // Variable/parameter/function has no static type, explicitly specified or inferred (`:=`).
|
UNTYPED_DECLARATION, // Variable/parameter/function has no static type, explicitly specified or implicitly inferred.
|
||||||
|
INFERRED_DECLARATION, // Variable/constant/parameter has an implicitly inferred static type.
|
||||||
UNSAFE_PROPERTY_ACCESS, // Property not found in the detected type (but can be in subtypes).
|
UNSAFE_PROPERTY_ACCESS, // Property not found in the detected type (but can be in subtypes).
|
||||||
UNSAFE_METHOD_ACCESS, // Function not found in the detected type (but can be in subtypes).
|
UNSAFE_METHOD_ACCESS, // Function not found in the detected type (but can be in subtypes).
|
||||||
UNSAFE_CAST, // Cast used in an unknown type.
|
UNSAFE_CAST, // Cast used in an unknown type.
|
||||||
@@ -113,6 +114,7 @@ public:
|
|||||||
WARN, // CONSTANT_USED_AS_FUNCTION
|
WARN, // CONSTANT_USED_AS_FUNCTION
|
||||||
WARN, // FUNCTION_USED_AS_PROPERTY
|
WARN, // FUNCTION_USED_AS_PROPERTY
|
||||||
IGNORE, // UNTYPED_DECLARATION // Static typing is optional, we don't want to spam warnings.
|
IGNORE, // UNTYPED_DECLARATION // Static typing is optional, we don't want to spam warnings.
|
||||||
|
IGNORE, // INFERRED_DECLARATION // Static typing is optional, we don't want to spam warnings.
|
||||||
IGNORE, // UNSAFE_PROPERTY_ACCESS // Too common in untyped scenarios.
|
IGNORE, // UNSAFE_PROPERTY_ACCESS // Too common in untyped scenarios.
|
||||||
IGNORE, // UNSAFE_METHOD_ACCESS // Too common in untyped scenarios.
|
IGNORE, // UNSAFE_METHOD_ACCESS // Too common in untyped scenarios.
|
||||||
IGNORE, // UNSAFE_CAST // Too common in untyped scenarios.
|
IGNORE, // UNSAFE_CAST // Too common in untyped scenarios.
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l
|
|||||||
// Set all warning levels to "Warn" in order to test them properly, even the ones that default to error.
|
// Set all warning levels to "Warn" in order to test them properly, even the ones that default to error.
|
||||||
ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true);
|
ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true);
|
||||||
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
|
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
|
||||||
if (i == GDScriptWarning::UNTYPED_DECLARATION) {
|
if (i == GDScriptWarning::UNTYPED_DECLARATION || i == GDScriptWarning::INFERRED_DECLARATION) {
|
||||||
// TODO: Add ability for test scripts to specify which warnings to enable/disable for testing.
|
// TODO: Add ability for test scripts to specify which warnings to enable/disable for testing.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user