Merge pull request #89675 from dalexeev/gds-correct-unused-signal-warning
GDScript: Do not produce `UNUSED_SIGNAL` warning for common implicit uses
This commit is contained in:
commit
d3be91e6ab
|
@ -3245,6 +3245,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);
|
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);
|
p_call->set_datatype(call_type);
|
||||||
return;
|
return;
|
||||||
} else if (GDScriptUtilityFunctions::function_exists(function_name)) {
|
} else if (GDScriptUtilityFunctions::function_exists(function_name)) {
|
||||||
|
@ -3479,6 +3499,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);
|
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
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
call_type = return_type;
|
call_type = return_type;
|
||||||
|
|
|
@ -1,12 +1,29 @@
|
||||||
signal s1()
|
# Doesn't produce the warning:
|
||||||
signal s2()
|
signal used_as_first_class_signal()
|
||||||
signal s3()
|
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")
|
@warning_ignore("unused_signal")
|
||||||
signal s4()
|
signal unused_but_ignored()
|
||||||
|
|
||||||
func no_exec():
|
func no_exec():
|
||||||
s1.emit()
|
print(used_as_first_class_signal)
|
||||||
print(s2)
|
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():
|
func test():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
>> WARNING
|
>> WARNING
|
||||||
>> Line: 3
|
>> Line: 11
|
||||||
>> UNUSED_SIGNAL
|
>> 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.
|
||||||
|
|
Loading…
Reference in New Issue