1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-11 16:59:45 +01:00

Prevent error on string array assignment

This commit is contained in:
Matthew Brown 2016-10-02 10:13:35 -04:00
parent a141ffe3cf
commit 91ea6844ba

View File

@ -2295,6 +2295,7 @@ class StatementsChecker
$nesting = 0;
$var_id = self::getVarId($stmt->var, $nesting);
$is_object = $var_id && isset($context->vars_in_scope[$var_id]) && $context->vars_in_scope[$var_id]->hasObjectType();
$is_string = $var_id && isset($context->vars_in_scope[$var_id]) && $context->vars_in_scope[$var_id]->hasString();
if ($this->checkExpression($stmt->var, $context, !$is_object, $assignment_key_type, $assignment_value_type) === false) {
return false;
@ -2305,6 +2306,36 @@ class StatementsChecker
? $array_var_id . '[\'' . $stmt->dim->value . '\']'
: null;
if (isset($stmt->var->inferredType)) {
$return_type = $stmt->var->inferredType;
if ($is_object) {
// do nothing
}
elseif ($is_string) {
foreach ($assignment_value_type->types as $value_type) {
if (!$value_type->isString()) {
if ($value_type->isMixed()) {
// @todo emit Mixed issue
}
else {
if (IssueBuffer::accepts(
new InvalidArrayAssignment(
'Cannot assign string offset value $' . $var_id . ' of type ' . $value_type . ' that does not implement ArrayAccess',
$this->checked_file_name,
$stmt->getLine()
),
$this->suppressed_issues
)) {
return false;
}
break;
}
}
}
}
else {
// we want to support multiple array types:
// - Dictionaries (which have the type array<string,T>)
// - pseudo-objects (which have the type array<string,mixed>)
@ -2313,10 +2344,7 @@ class StatementsChecker
//
// When making assignments, we generally only know the shape of the array
// as it is being created.
if (isset($stmt->var->inferredType)) {
$return_type = $stmt->var->inferredType;
if ($keyed_array_var_id && !$is_object) {
if ($keyed_array_var_id) {
// when we have a pattern like
// $a = [];
// $a['b']['c']['d'] = 1;
@ -2334,7 +2362,7 @@ class StatementsChecker
$stmt->inferredType = $assignment_value_type;
}
if (!$nesting && !$is_object) {
if (!$nesting) {
$assignment_type = new Type\Union([
new Type\Generic(
'array',
@ -2355,6 +2383,8 @@ class StatementsChecker
$context->vars_in_scope[$var_id] = $assignment_type;
}
}
}
else {
$context->vars_in_scope[$var_id] = Type::getMixed();
}