1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Add PossiblyUndefinedVariable warning when using possibly undefined array key

This commit is contained in:
Matthew Brown 2018-03-17 17:35:36 -04:00
parent 61af2a924c
commit 4175d1a887
4 changed files with 56 additions and 2 deletions

View File

@ -23,6 +23,8 @@ use Psalm\Issue\PossiblyInvalidArrayOffset;
use Psalm\Issue\PossiblyNullArrayAccess;
use Psalm\Issue\PossiblyNullArrayAssignment;
use Psalm\Issue\PossiblyNullArrayOffset;
use Psalm\Issue\PossiblyUndefinedGlobalVariable;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\ObjectLike;
@ -130,6 +132,30 @@ class ArrayFetchChecker
if (!isset($stmt->inferredType)) {
$stmt->inferredType = Type::getMixed();
} else {
if ($stmt->inferredType->possibly_undefined && !$context->inside_isset && !$context->inside_unset) {
if ($context->is_global) {
if (IssueBuffer::accepts(
new PossiblyUndefinedGlobalVariable(
'Possibly undefined array key ' . $keyed_array_var_id,
new CodeLocation($statements_checker->getSource(), $stmt)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
} else {
if (IssueBuffer::accepts(
new PossiblyUndefinedVariable(
'Possibly undefined array key ' . $keyed_array_var_id,
new CodeLocation($statements_checker->getSource(), $stmt)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
}
}
}
return null;

View File

@ -361,8 +361,9 @@ class Context
$redefined_var_ids = [];
foreach ($new_context->vars_in_scope as $var_id => $context_type) {
if (!isset($original_context->vars_in_scope[$var_id]) ||
$original_context->vars_in_scope[$var_id]->getId() !== $context_type->getId()
if (!isset($original_context->vars_in_scope[$var_id])
|| $original_context->vars_in_scope[$var_id]->getId() !== $context_type->getId()
|| $original_context->vars_in_scope[$var_id]->possibly_undefined !== $context_type->possibly_undefined
) {
$redefined_var_ids[] = $var_id;
}

View File

@ -92,6 +92,7 @@ class Reconciler
$failed_reconciliation = false;
$from_docblock = $result_type && $result_type->from_docblock;
$possibly_undefined = $result_type && $result_type->possibly_undefined;
foreach ($new_type_parts as $new_type_part) {
$new_type_part_parts = explode('|', $new_type_part);
@ -123,6 +124,7 @@ class Reconciler
if ($result_type->getId() !== $before_adjustment
|| $result_type->from_docblock !== $from_docblock
|| $result_type->possibly_undefined !== $possibly_undefined
|| $failed_reconciliation
) {
$changed_var_ids[] = $key;
@ -482,6 +484,8 @@ class Reconciler
return Type::getMixed();
}
$existing_var_type->possibly_undefined = false;
return $existing_var_type;
}

View File

@ -838,6 +838,18 @@ class ArrayAssignmentTest extends TestCase
'MixedArrayAccess', 'MixedAssignment', 'MixedArrayOffset', 'MixedArrayAssignment', 'MixedArgument',
],
],
'possiblyUndefinedArrayAccessWithIsset' => [
'<?php
if (rand(0,1)) {
$a = ["a" => 1];
} else {
$a = [2, 3];
}
if (isset($a[0])) {
echo $a[0];
}',
],
];
}
@ -859,6 +871,17 @@ class ArrayAssignmentTest extends TestCase
$a[0] = 5;',
'error_message' => 'InvalidArrayAssignment',
],
'possiblyUndefinedArrayAccess' => [
'<?php
if (rand(0,1)) {
$a = ["a" => 1];
} else {
$a = [2, 3];
}
echo $a[0];',
'error_message' => 'PossiblyUndefinedGlobalVariable',
],
'mixedStringOffsetAssignment' => [
'<?php
/** @var mixed */