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

Fix #230 - invalidate root vars on $arr[]= assignment

This commit is contained in:
Matthew Brown 2017-10-10 23:01:52 -04:00
parent b43c2d5f0c
commit 862d22e83c
3 changed files with 76 additions and 1 deletions

View File

@ -139,6 +139,20 @@ class AssignmentChecker
$assign_value_type,
$statements_checker
);
} else {
$root_var_id = ExpressionChecker::getRootVarId(
$assign_var,
$statements_checker->getFQCLN(),
$statements_checker
);
if ($root_var_id && isset($context->vars_in_scope[$root_var_id])) {
$context->removeVarFromConflictingClauses(
$root_var_id,
$context->vars_in_scope[$root_var_id],
$statements_checker
);
}
}
if ($assign_value_type->isMixed()) {

View File

@ -1642,6 +1642,39 @@ class ExpressionChecker
return null;
}
/**
* @param PhpParser\Node\Expr $stmt
* @param string|null $this_class_name
* @param StatementsSource|null $source
*
* @return string|null
*/
public static function getRootVarId(
PhpParser\Node\Expr $stmt,
$this_class_name,
StatementsSource $source = null
) {
if ($stmt instanceof PhpParser\Node\Expr\Variable
|| $stmt instanceof PhpParser\Node\Expr\StaticPropertyFetch
) {
return self::getVarId($stmt, $this_class_name, $source);
}
if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch && is_string($stmt->name)) {
$property_root = self::getRootVarId($stmt->var, $this_class_name, $source);
if ($property_root) {
return $property_root . '->' . $stmt->name;
}
}
if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
return self::getRootVarId($stmt->var, $this_class_name, $source);
}
return null;
}
/**
* @param PhpParser\Node\Expr $stmt
* @param string|null $this_class_name

View File

@ -334,7 +334,35 @@ class TypeAlgebraTest extends TestCase
}
return true;
}'
]
],
'noParadoxAfterArrayAppending' => [
'<?php
/** @return array|false */
function array_append2(array $errors) {
if ($errors) {
return $errors;
}
$errors[] = "deterministic";
if ($errors) {
return false;
}
return $errors;
}
/** @return array|false */
function array_append(array $errors) {
if ($errors) {
return $errors;
}
if (rand() % 2 > 0) {
$errors[] = "unlucky";
}
if ($errors) {
return false;
}
return $errors;
}'
],
];
}