mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Fixes
This commit is contained in:
parent
7d95f15e30
commit
1c2dd4a26f
@ -36,7 +36,7 @@ class ScopeAnalyzer
|
||||
*/
|
||||
public static function getControlActions(
|
||||
array $stmts,
|
||||
?NodeDataProvider $nodes,
|
||||
NodeDataProvider $nodes,
|
||||
array $break_types,
|
||||
bool $return_is_exit = true
|
||||
): array {
|
||||
@ -83,7 +83,10 @@ class ScopeAnalyzer
|
||||
if ($stmt instanceof PhpParser\Node\Stmt\Continue_) {
|
||||
$count = !$stmt->num
|
||||
? 1
|
||||
: ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
|
||||
: (($cnt_type = $nodes->getType($stmt->num))
|
||||
&& $cnt_type->isSingleIntLiteral()
|
||||
? $cnt_type->getSingleLiteral()->value
|
||||
: null);
|
||||
|
||||
if ($break_types && $count !== null && count($break_types) >= $count) {
|
||||
/** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
|
||||
@ -100,7 +103,10 @@ class ScopeAnalyzer
|
||||
if ($stmt instanceof PhpParser\Node\Stmt\Break_) {
|
||||
$count = !$stmt->num
|
||||
? 1
|
||||
: ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
|
||||
: (($cnt_type = $nodes->getType($stmt->num))
|
||||
&& $cnt_type->isSingleIntLiteral()
|
||||
? $cnt_type->getSingleLiteral()->value
|
||||
: null);
|
||||
|
||||
if ($break_types && $count !== null && count($break_types) >= $count) {
|
||||
/** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
|
||||
|
@ -106,14 +106,15 @@ class ForAnalyzer
|
||||
if (count($stmt->init) === 1
|
||||
&& count($stmt->cond) === 1
|
||||
&& $cond instanceof PhpParser\Node\Expr\BinaryOp
|
||||
&& $cond->right instanceof PhpParser\Node\Scalar\LNumber
|
||||
&& ($cond_value = $statements_analyzer->node_data->getType($cond->right))
|
||||
&& ($cond_value->isSingleIntLiteral() || $cond_value->isSingleStringLiteral())
|
||||
&& $cond->left instanceof PhpParser\Node\Expr\Variable
|
||||
&& is_string($cond->left->name)
|
||||
&& isset($init_var_types[$cond->left->name])
|
||||
&& $init_var_types[$cond->left->name]->isSingleIntLiteral()
|
||||
) {
|
||||
$init_value = $init_var_types[$cond->left->name]->getSingleIntLiteral()->value;
|
||||
$cond_value = $cond->right->value;
|
||||
$init_value = $init_var_types[$cond->left->name]->getSingleLiteral()->value;
|
||||
$cond_value = $cond_value->getSingleLiteral()->value;
|
||||
|
||||
if ($cond instanceof PhpParser\Node\Expr\BinaryOp\Smaller && $init_value < $cond_value) {
|
||||
$always_enters_loop = true;
|
||||
|
@ -27,7 +27,8 @@ class WhileAnalyzer
|
||||
Context $context
|
||||
): ?bool {
|
||||
$while_true = ($stmt->cond instanceof PhpParser\Node\Expr\ConstFetch && $stmt->cond->name->parts === ['true'])
|
||||
|| ($stmt->cond instanceof PhpParser\Node\Scalar\LNumber && $stmt->cond->value > 0);
|
||||
|| (($t = $statements_analyzer->node_data->getType($stmt->cond))
|
||||
&& $t->isAlwaysTruthy());
|
||||
|
||||
$pre_context = null;
|
||||
|
||||
|
@ -333,9 +333,18 @@ class IncludeAnalyzer
|
||||
if (isset($stmt->getArgs()[1])) {
|
||||
if ($stmt->getArgs()[1]->value instanceof PhpParser\Node\Scalar\LNumber) {
|
||||
$dir_level = $stmt->getArgs()[1]->value->value;
|
||||
} else {
|
||||
if ($statements_analyzer) {
|
||||
$t = $statements_analyzer->node_data->getType($stmt->getArgs()[1]->value);
|
||||
if ($t && $t->isSingleIntLiteral()) {
|
||||
$dir_level = $t->getSingleIntLiteral()->value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$evaled_path = self::getPathTo(
|
||||
|
@ -54,15 +54,21 @@ class ArrayRandReturnTypeProvider implements FunctionReturnTypeProviderInterface
|
||||
$key_type = $first_arg_array->getGenericKeyType();
|
||||
}
|
||||
|
||||
if (!$second_arg
|
||||
|| ($second_arg instanceof PhpParser\Node\Scalar\LNumber && $second_arg->value === 1)
|
||||
if (!$second_arg) {
|
||||
return $key_type;
|
||||
}
|
||||
|
||||
$second_arg_type = $statements_source->node_data->getType($second_arg);
|
||||
if ($second_arg_type
|
||||
&& $second_arg_type->isSingleIntLiteral()
|
||||
&& $second_arg_type->getSingleIntLiteral()->value === 1
|
||||
) {
|
||||
return $key_type;
|
||||
}
|
||||
|
||||
$arr_type = Type::getList($key_type);
|
||||
|
||||
if ($second_arg instanceof PhpParser\Node\Scalar\LNumber) {
|
||||
if ($second_arg_type && $second_arg_type->isSingleIntLiteral()) {
|
||||
return $arr_type;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class ExplodeReturnTypeProvider implements FunctionReturnTypeProviderInterface
|
||||
|
||||
if (count($call_args) >= 2) {
|
||||
$second_arg_type = $statements_source->node_data->getType($call_args[1]->value);
|
||||
$third_arg_type = $statements_source->node_data->getType($call_args[2]->value);
|
||||
|
||||
$inner_type = new Union([
|
||||
$second_arg_type && $second_arg_type->hasLowercaseString()
|
||||
@ -47,8 +48,9 @@ class ExplodeReturnTypeProvider implements FunctionReturnTypeProviderInterface
|
||||
|
||||
$can_return_empty = isset($call_args[2])
|
||||
&& (
|
||||
!$call_args[2]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
|| $call_args[2]->value->value < 0
|
||||
!$third_arg_type
|
||||
|| !$third_arg_type->isSingleIntLiteral()
|
||||
|| $third_arg_type->getSingleIntLiteral()->value < 0
|
||||
);
|
||||
|
||||
if ($call_args[0]->value instanceof PhpParser\Node\Scalar\String_) {
|
||||
|
Loading…
Reference in New Issue
Block a user