Skip to content

Commit

Permalink
GDScript: Do not produce UNUSED_SIGNAL warning for common implicit …
Browse files Browse the repository at this point in the history
…uses
  • Loading branch information
dalexeev committed Mar 19, 2024
1 parent fe01776 commit d1e2afa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 8 deletions.
34 changes: 34 additions & 0 deletions modules/gdscript/gdscript_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,26 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
push_error(vformat(R"(No constructor of "%s" matches the signature "%s".)", Variant::get_type_name(builtin_type), signature), p_call);
}
}

#ifdef DEBUG_ENABLED
// Consider `Signal(self, "my_signal")` as an implicit use of the signal.
if (builtin_type == Variant::SIGNAL && p_call->arguments.size() >= 2) {
const GDScriptParser::ExpressionNode *object_arg = p_call->arguments[0];
if (object_arg && object_arg->type == GDScriptParser::Node::SELF) {
const GDScriptParser::ExpressionNode *signal_arg = p_call->arguments[1];
if (signal_arg && signal_arg->is_constant) {
const StringName &signal_name = signal_arg->reduced_value;
if (parser->current_class->has_member(signal_name)) {
const GDScriptParser::ClassNode::Member &member = parser->current_class->get_member(signal_name);
if (member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
member.signal->usages++;
}
}
}
}
}
#endif

p_call->set_datatype(call_type);
return;
} else if (GDScriptUtilityFunctions::function_exists(function_name)) {
Expand Down Expand Up @@ -3345,6 +3365,20 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a

parser->push_warning(p_call, GDScriptWarning::STATIC_CALLED_ON_INSTANCE, p_call->function_name, caller_type);
}

// Consider `emit_signal()`, `connect()`, and `disconnect()` as implicit uses of the signal.
if (is_self && (p_call->function_name == SNAME("emit_signal") || p_call->function_name == SNAME("connect") || p_call->function_name == SNAME("disconnect")) && !p_call->arguments.is_empty()) {
const GDScriptParser::ExpressionNode *signal_arg = p_call->arguments[0];
if (signal_arg && signal_arg->is_constant) {
const StringName &signal_name = signal_arg->reduced_value;
if (parser->current_class->has_member(signal_name)) {
const GDScriptParser::ClassNode::Member &member = parser->current_class->get_member(signal_name);
if (member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
member.signal->usages++;
}
}
}
}
#endif // DEBUG_ENABLED

call_type = return_type;
Expand Down
29 changes: 23 additions & 6 deletions modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
signal s1()
signal s2()
signal s3()
# Doesn't produce the warning:
signal used_as_first_class_signal()
signal used_with_signal_constructor()
signal used_with_signal_emit()
signal used_with_object_emit_signal()
signal used_with_object_connect()
signal used_with_object_disconnect()
signal used_with_self_prefix()

# Produce the warning:
signal used_with_dynamic_name()
signal just_unused()
@warning_ignore("unused_signal")
signal s4()
signal unused_but_ignored()

func no_exec():
s1.emit()
print(s2)
print(used_as_first_class_signal)
print(Signal(self, "used_with_signal_constructor"))
used_with_signal_emit.emit()
print(emit_signal("used_with_object_emit_signal"))
print(connect("used_with_object_connect", Callable()))
disconnect("used_with_object_disconnect", Callable())
print(self.emit_signal("used_with_self_prefix"))

var dynamic_name := "used_with_dynamic_name"
print(emit_signal(dynamic_name))

func test():
pass
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
GDTEST_OK
>> WARNING
>> Line: 3
>> Line: 11
>> UNUSED_SIGNAL
>> The signal "s3" is declared but never explicitly used in the class.
>> The signal "used_with_dynamic_name" is declared but never explicitly used in the class.
>> WARNING
>> Line: 12
>> UNUSED_SIGNAL
>> The signal "just_unused" is declared but never explicitly used in the class.

0 comments on commit d1e2afa

Please sign in to comment.