Skip to content

Commit

Permalink
Fix #2940 - fix array offset assignment under ??=
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Mar 9, 2020
1 parent aa8d7be commit 04bcc32
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,45 @@ public static function analyzeAssignmentOperation(
PhpParser\Node\Expr\AssignOp $stmt,
Context $context
) {
$array_var_id = ExpressionAnalyzer::getArrayVarId(
$stmt->var,
$statements_analyzer->getFQCLN(),
$statements_analyzer
);

if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Coalesce) {
$old_data_provider = $statements_analyzer->node_data;

$statements_analyzer->node_data = clone $statements_analyzer->node_data;

$fake_coalesce_expr = new PhpParser\Node\Expr\BinaryOp\Coalesce(
$stmt->var,
$stmt->expr,
$stmt->getAttributes()
);

$fake_coalesce_type = AssignmentAnalyzer::analyze(
$statements_analyzer,
$stmt->var,
$fake_coalesce_expr,
null,
$context,
$stmt->getDocComment()
);

$statements_analyzer->node_data = $old_data_provider;

if ($fake_coalesce_type) {
if ($array_var_id) {
$context->vars_in_scope[$array_var_id] = $fake_coalesce_type;
}

$statements_analyzer->node_data->setType($stmt, $fake_coalesce_type);
}

return;
}

$was_in_assignment = $context->inside_assignment;

$context->inside_assignment = true;
Expand All @@ -872,12 +911,6 @@ public static function analyzeAssignmentOperation(
return false;
}

$array_var_id = ExpressionAnalyzer::getArrayVarId(
$stmt->var,
$statements_analyzer->getFQCLN(),
$statements_analyzer
);

if ($array_var_id
&& $context->mutation_free
&& $stmt->var instanceof PhpParser\Node\Expr\PropertyFetch
Expand Down Expand Up @@ -1030,38 +1063,6 @@ public static function analyzeAssignmentOperation(
);
}

if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Coalesce) {
$old_data_provider = $statements_analyzer->node_data;

$statements_analyzer->node_data = clone $statements_analyzer->node_data;

$fake_coalesce_expr = new PhpParser\Node\Expr\BinaryOp\Coalesce(
$stmt->var,
$stmt->expr,
$stmt->getAttributes()
);

if (BinaryOpAnalyzer::analyze(
$statements_analyzer,
$fake_coalesce_expr,
$context
) === false) {
return false;
}

$fake_coalesce_type = $statements_analyzer->node_data->getType($fake_coalesce_expr);

$statements_analyzer->node_data = $old_data_provider;

if ($fake_coalesce_type) {
if ($array_var_id) {
$context->vars_in_scope[$array_var_id] = $fake_coalesce_type;
}

$statements_analyzer->node_data->setType($stmt, $fake_coalesce_type);
}
}

if (!$was_in_assignment) {
$context->inside_assignment = false;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/BinaryOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,19 @@ function foo(?string $s): string {
return $s;
}'
],
'nullCoalescingArrayAssignment' => [
'<?php
/**
* @param array<string> $arr
*/
function foo(array $arr) : void {
$b = [];
foreach ($arr as $a) {
$b[0] ??= $a;
}
}'
],
];
}

Expand Down

0 comments on commit 04bcc32

Please sign in to comment.