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

Fix issue reconciling mixed vars inside loop

This commit is contained in:
Matthew Brown 2019-02-18 11:39:05 -05:00
parent faae9fda3b
commit 12f1ffca11
6 changed files with 41 additions and 9 deletions

View File

@ -350,7 +350,7 @@ class LoopAnalyzer
}
foreach ($loop_scope->loop_parent_context->vars_in_scope as $var_id => $type) {
if ($type->hasMixed() || !isset($loop_scope->loop_context->vars_in_scope[$var_id])) {
if (!isset($loop_scope->loop_context->vars_in_scope[$var_id])) {
continue;
}
@ -366,10 +366,6 @@ class LoopAnalyzer
if (!$does_always_break) {
foreach ($loop_scope->loop_parent_context->vars_in_scope as $var_id => $type) {
if ($type->hasMixed()) {
continue;
}
if (!isset($inner_context->vars_in_scope[$var_id])) {
unset($loop_scope->loop_parent_context->vars_in_scope[$var_id]);
continue;

View File

@ -128,6 +128,7 @@ class VariableFetchAnalyzer
'_SESSION',
'_REQUEST',
'_ENV',
'http_response_header'
],
true
)

View File

@ -828,6 +828,10 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
$root_type->addType(
new Type\Atomic\TArray($atomic_root_type->type_params)
);
} elseif ($atomic_root_type instanceof Type\Atomic\TNonEmptyMixed) {
$root_type->addType(
new Type\Atomic\TMixed()
);
}
}

View File

@ -9354,7 +9354,7 @@ return [
'Phar::decompressFiles' => ['bool'],
'Phar::delete' => ['bool', 'entry'=>'string'],
'Phar::delMetadata' => ['bool'],
'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array', 'overwrite='=>'bool'],
'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
'Phar::getAlias' => ['string'],
'Phar::getMetadata' => ['mixed'],
'Phar::getModified' => ['bool'],
@ -9390,7 +9390,7 @@ return [
'Phar::uncompressAllFiles' => ['bool'],
'Phar::unlinkArchive' => ['bool', 'archive'=>'string'],
'Phar::webPhar' => ['', 'alias='=>'string', 'index='=>'string', 'f404='=>'string', 'mimetypes='=>'array', 'rewrites='=>'array'],
'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string', 'format='=>'int'],
'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'int|null', 'alias='=>'string|null', 'format='=>'int'],
'PharData::addEmptyDir' => ['bool', 'dirname'=>'string'],
'PharData::addFile' => ['void', 'file'=>'string', 'localname='=>'string'],
'PharData::addFromString' => ['bool', 'localname'=>'string', 'contents'=>'string'],
@ -9405,7 +9405,7 @@ return [
'PharData::decompressFiles' => ['bool'],
'PharData::delete' => ['bool', 'entry'=>'string'],
'PharData::delMetadata' => ['bool'],
'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array', 'overwrite='=>'bool'],
'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
'PharData::isWritable' => ['bool'],
'PharData::offsetSet' => ['void', 'offset'=>'string', 'value'=>'string'],
'PharData::offsetUnset' => ['bool', 'offset'=>'string'],

View File

@ -443,7 +443,7 @@ class ForeachTest extends \Psalm\Tests\TestCase
}
}',
'assignments' => [
'$a' => 'null|mixed',
'$a' => 'mixed',
],
'error_levels' => [
'MixedAssignment',

View File

@ -518,6 +518,37 @@ class RedundantConditionTest extends TestCase
if ($i) {}',
],
'emptyWithoutKnowingArrayType' => [
'<?php
function foo(array $a) : void {
if (!empty($a["foo"])) {
foreach ($a["foo"] as $key => $_) {
if (rand(0, 1)) {
unset($a["foo"][$key]);
}
}
if (empty($a["foo"])) {}
}
}',
[],
['MixedAssignment', 'MixedArrayAccess', 'MixedArrayOffset']
],
'emptyKnowingArrayType' => [
'<?php
/**
* @param array<string, array<string, int>> $a
*/
function foo(array $a) : void {
if (!empty($a["foo"])) {
foreach ($a["foo"] as $key => $_) {
if (rand(0, 1)) {
unset($a["foo"][$key]);
}
}
if (empty($a["foo"])) {}
}
}',
],
];
}