Add STATIC_CALLED_ON_INSTANCE warning to highlight

when static functions are called directly from objects
This commit is contained in:
clayjohn 2022-10-13 12:42:11 -07:00
parent 39534a7aec
commit 0a51bb4ca5
6 changed files with 31 additions and 0 deletions

View File

@ -413,6 +413,9 @@
<member name="debug/gdscript/warnings/standalone_ternary" type="int" setter="" getter="" default="1"> <member name="debug/gdscript/warnings/standalone_ternary" type="int" setter="" getter="" default="1">
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling a ternary expression that has no effect on the surrounding code, such as writing [code]42 if active else 0[/code] as a statement. When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling a ternary expression that has no effect on the surrounding code, such as writing [code]42 if active else 0[/code] as a statement.
</member> </member>
<member name="debug/gdscript/warnings/static_called_on_instance" type="int" setter="" getter="" default="1">
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling a static method from an instance of a class instead of from the class directly.
</member>
<member name="debug/gdscript/warnings/treat_warnings_as_errors" type="bool" setter="" getter="" default="false"> <member name="debug/gdscript/warnings/treat_warnings_as_errors" type="bool" setter="" getter="" default="false">
If [code]true[/code], all warnings will be reported as if they are errors. If [code]true[/code], all warnings will be reported as if they are errors.
</member> </member>

View File

@ -2552,6 +2552,10 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
if (p_is_root && return_type.kind != GDScriptParser::DataType::UNRESOLVED && return_type.builtin_type != Variant::NIL) { if (p_is_root && return_type.kind != GDScriptParser::DataType::UNRESOLVED && return_type.builtin_type != Variant::NIL) {
parser->push_warning(p_call, GDScriptWarning::RETURN_VALUE_DISCARDED, p_call->function_name); parser->push_warning(p_call, GDScriptWarning::RETURN_VALUE_DISCARDED, p_call->function_name);
} }
if (is_static && !base_type.is_meta_type && !(callee_type != GDScriptParser::Node::SUBSCRIPT && parser->current_function != nullptr && parser->current_function->is_static)) {
parser->push_warning(p_call, GDScriptWarning::STATIC_CALLED_ON_INSTANCE, p_call->function_name, base_type.to_string());
}
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
call_type = return_type; call_type = return_type;

View File

@ -155,6 +155,10 @@ String GDScriptWarning::get_message() const {
case INT_ASSIGNED_TO_ENUM: { case INT_ASSIGNED_TO_ENUM: {
return "Integer used when an enum value is expected. If this is intended cast the integer to the enum type."; return "Integer used when an enum value is expected. If this is intended cast the integer to the enum type.";
} }
case STATIC_CALLED_ON_INSTANCE: {
CHECK_SYMBOLS(2);
return vformat(R"(The function '%s()' is a static function but was called from an instance. Instead, it should be directly called from the type: '%s.%s()'.)", symbols[0], symbols[1], symbols[0]);
}
case WARNING_MAX: case WARNING_MAX:
break; // Can't happen, but silences warning break; // Can't happen, but silences warning
} }
@ -215,6 +219,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"EMPTY_FILE", "EMPTY_FILE",
"SHADOWED_GLOBAL_IDENTIFIER", "SHADOWED_GLOBAL_IDENTIFIER",
"INT_ASSIGNED_TO_ENUM", "INT_ASSIGNED_TO_ENUM",
"STATIC_CALLED_ON_INSTANCE",
}; };
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names."); static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");

View File

@ -78,6 +78,7 @@ public:
EMPTY_FILE, // A script file is empty. EMPTY_FILE, // A script file is empty.
SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable. SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable.
INT_ASSIGNED_TO_ENUM, // An integer value was assigned to an enum-typed variable without casting. INT_ASSIGNED_TO_ENUM, // An integer value was assigned to an enum-typed variable without casting.
STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
WARNING_MAX, WARNING_MAX,
}; };

View File

@ -0,0 +1,11 @@
class Player:
var x = 3
func test():
# These should not emit a warning.
var _player = Player.new()
print(String.num_uint64(8589934592)) # 2 ^ 33
# This should emit a warning.
var some_string = String()
print(some_string.num_uint64(8589934592)) # 2 ^ 33

View File

@ -0,0 +1,7 @@
GDTEST_OK
>> WARNING
>> Line: 11
>> STATIC_CALLED_ON_INSTANCE
>> The function 'num_uint64()' is a static function but was called from an instance. Instead, it should be directly called from the type: 'String.num_uint64()'.
8589934592
8589934592