1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #39 by checking for ArrayAcces interface

This commit is contained in:
Matthew Brown 2017-01-20 00:23:58 -05:00
parent 894b25487f
commit 374dc65de1
2 changed files with 44 additions and 14 deletions

View File

@ -867,22 +867,35 @@ class AssignmentChecker
$statements_checker
);
$is_string = isset($stmt->var->inferredType)
&& $stmt->var->inferredType->hasString();
$has_scalar = isset($stmt->var->inferredType)
&& $stmt->var->inferredType->hasScalarType();
$keyed_array_var_id = $array_var_id && $stmt->dim instanceof PhpParser\Node\Scalar\String_
? $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) {
$keyed_array_var_id = $array_var_id && $stmt->dim instanceof PhpParser\Node\Scalar\String_
? $array_var_id . '[\'' . $stmt->dim->value . '\']'
: null;
if ($return_type->hasObjectType()) {
foreach ($return_type->types as $left_type_part) {
if ($left_type_part instanceof TNamedObject &&
(strtolower($left_type_part->value) !== 'simplexmlelement' &&
ClassChecker::classExists($left_type_part->value, $statements_checker->getFileChecker()) &&
!ClassChecker::classImplements($left_type_part->value, 'ArrayAccess')
)
) {
if (IssueBuffer::accepts(
new InvalidArrayAssignment(
'Cannot assign array value on non-array variable ' .
$array_var_id . ' of type ' . $return_type,
new CodeLocation($statements_checker->getSource(), $stmt)
),
$statements_checker->getSuppressedIssues()
)) {
$stmt->inferredType = Type::getMixed();
break;
}
}
}
} elseif ($return_type->hasString()) {
foreach ($assignment_value_type->types as $value_type) {
if (!$value_type instanceof TString) {
if ($value_type instanceof TMixed) {
@ -912,7 +925,7 @@ class AssignmentChecker
break;
}
}
} elseif ($has_scalar) {
} elseif ($return_type->hasScalarType()) {
if (IssueBuffer::accepts(
new InvalidArrayAssignment(
'Cannot assign value on variable ' . $var_id . ' of scalar type ' . $context->vars_in_scope[$var_id],

View File

@ -612,6 +612,23 @@ class ArrayAssignmentTest extends PHPUnit_Framework_TestCase
$this->assertFalse(isset($context->vars_in_scope['$a[\'bar\']']));
}
/**
* @expectedException \Psalm\Exception\CodeException
* @expectedExceptionMessage InvalidArrayAssignment
* @return void
*/
public function testObjectAssignment()
{
$context = new Context();
$stmts = self::$parser->parse('<?php
class A {}
(new A)["b"] = 1;
');
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
$file_checker->visitAndAnalyzeMethods($context);
}
/**
* @return void
*/