GDScript: Fix false positive CONFUSABLE_CAPTURE_REASSIGNMENT warnings

This commit is contained in:
Danil Alexeev 2024-06-28 09:35:04 +03:00
parent ac9181c666
commit d15ed0bcbb
No known key found for this signature in database
GPG key ID: 124453E157DA8DC7
3 changed files with 45 additions and 43 deletions

View file

@ -2665,17 +2665,40 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
{ {
bool is_subscript = false;
GDScriptParser::ExpressionNode *base = p_assignment->assignee; GDScriptParser::ExpressionNode *base = p_assignment->assignee;
while (base && base->type == GDScriptParser::Node::SUBSCRIPT) { while (base && base->type == GDScriptParser::Node::SUBSCRIPT) {
is_subscript = true;
base = static_cast<GDScriptParser::SubscriptNode *>(base)->base; base = static_cast<GDScriptParser::SubscriptNode *>(base)->base;
} }
if (base && base->type == GDScriptParser::Node::IDENTIFIER) { if (base && base->type == GDScriptParser::Node::IDENTIFIER) {
GDScriptParser::IdentifierNode *id = static_cast<GDScriptParser::IdentifierNode *>(base); GDScriptParser::IdentifierNode *id = static_cast<GDScriptParser::IdentifierNode *>(base);
if (current_lambda && current_lambda->captures_indices.has(id->name)) { if (current_lambda && current_lambda->captures_indices.has(id->name)) {
bool need_warn = false;
if (is_subscript) {
const GDScriptParser::DataType &id_type = id->datatype;
if (id_type.is_hard_type()) {
switch (id_type.kind) {
case GDScriptParser::DataType::BUILTIN:
// TODO: Change `Variant::is_type_shared()` to include packed arrays?
need_warn = !Variant::is_type_shared(id_type.builtin_type) && id_type.builtin_type < Variant::PACKED_BYTE_ARRAY;
break;
case GDScriptParser::DataType::ENUM:
need_warn = true;
break;
default:
break;
}
}
} else {
need_warn = true;
}
if (need_warn) {
parser->push_warning(p_assignment, GDScriptWarning::CONFUSABLE_CAPTURE_REASSIGNMENT, id->name); parser->push_warning(p_assignment, GDScriptWarning::CONFUSABLE_CAPTURE_REASSIGNMENT, id->name);
} }
} }
} }
}
#endif #endif
if (p_assignment->assigned_value == nullptr || p_assignment->assignee == nullptr) { if (p_assignment->assigned_value == nullptr || p_assignment->assignee == nullptr) {

View file

@ -5,23 +5,19 @@ func test():
var string := "1" var string := "1"
var vector := Vector2i(1, 0) var vector := Vector2i(1, 0)
var array_assign := [1] var array_assign := [1]
var array_append := [1] var array_index := [1]
var f := func (): var dictionary := { x = 0 }
member = 2
number = 2 var lambda := func ():
string += "2" member = 2 # Member variable, not captured.
vector.x = 2 number = 2 # Local variable, captured.
array_assign = [2] string += "2" # Test compound assignment operator.
array_append.append(2) vector.x = 2 # Test subscript assignment.
var g := func (): array_assign = [2] # Pass-by-reference type, reassignment.
member = 3 array_index[0] = 2 # Pass-by-reference type, index access.
number = 3 dictionary.x = 2 # Pass-by-reference type, attribute access.
string += "3"
vector.x = 3 prints("lambda", member, number, string, vector, array_assign, array_index, dictionary)
array_assign = [3]
array_append.append(3) lambda.call()
prints("g", member, number, string, vector, array_assign, array_append) prints("outer", member, number, string, vector, array_assign, array_index, dictionary)
g.call()
prints("f", member, number, string, vector, array_assign, array_append)
f.call()
prints("test", member, number, string, vector, array_assign, array_append)

View file

@ -1,36 +1,19 @@
GDTEST_OK GDTEST_OK
>> WARNING >> WARNING
>> Line: 11
>> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "number".
>> WARNING
>> Line: 12
>> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "string".
>> WARNING
>> Line: 13 >> Line: 13
>> CONFUSABLE_CAPTURE_REASSIGNMENT >> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "vector". >> Reassigning lambda capture does not modify the outer local variable "number".
>> WARNING >> WARNING
>> Line: 14 >> Line: 14
>> CONFUSABLE_CAPTURE_REASSIGNMENT >> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "array_assign".
>> WARNING
>> Line: 18
>> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "number".
>> WARNING
>> Line: 19
>> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "string". >> Reassigning lambda capture does not modify the outer local variable "string".
>> WARNING >> WARNING
>> Line: 20 >> Line: 15
>> CONFUSABLE_CAPTURE_REASSIGNMENT >> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "vector". >> Reassigning lambda capture does not modify the outer local variable "vector".
>> WARNING >> WARNING
>> Line: 21 >> Line: 16
>> CONFUSABLE_CAPTURE_REASSIGNMENT >> CONFUSABLE_CAPTURE_REASSIGNMENT
>> Reassigning lambda capture does not modify the outer local variable "array_assign". >> Reassigning lambda capture does not modify the outer local variable "array_assign".
g 3 3 123 (3, 0) [3] [1, 2, 3] lambda 2 2 12 (2, 0) [2] [2] { "x": 2 }
f 3 2 12 (2, 0) [2] [1, 2, 3] outer 2 1 1 (1, 0) [1] [2] { "x": 2 }
test 3 1 1 (1, 0) [1] [1, 2, 3]