1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix issues found by improved Psalm checks

cc @TysonAndre, found with RedundantCondition checks
This commit is contained in:
Matthew Brown 2017-11-24 12:10:30 -05:00
parent fd3de443b2
commit 4312ef380b
12 changed files with 49 additions and 69 deletions

View File

@ -7606,7 +7606,7 @@ return [
'ReflectionClass::getModifiers' => ['int'],
'ReflectionClass::getNamespaceName' => ['string'],
'ReflectionClass::getName' => ['string'],
'ReflectionClass::getParentClass' => ['ReflectionClass'],
'ReflectionClass::getParentClass' => ['?ReflectionClass'],
'ReflectionClass::getProperties' => ['array', 'filter='=>'int'],
'ReflectionClass::getProperty' => ['ReflectionProperty', 'name'=>'string'],
'ReflectionClass::getShortName' => ['string'],

View File

@ -1562,12 +1562,12 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
$class_storage = $project_checker->classlike_storage_provider->get($declaring_property_class);
$storage = $class_storage->properties[$property_name];
if (!$storage) {
if (!isset($class_storage->properties[$property_name])) {
throw new \UnexpectedValueException('$storage should not be null for ' . $property_id);
}
$storage = $class_storage->properties[$property_name];
switch ($storage->visibility) {
case self::VISIBILITY_PUBLIC:
return null;

View File

@ -934,7 +934,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
}
if (!$return_type) {
if ($inferred_return_type && !$inferred_return_type->isMixed()) {
if (!$inferred_return_type->isMixed()) {
$this->addDocblockReturnType($project_checker, $inferred_return_type);
}
@ -983,7 +983,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
);
}
if ($inferred_return_type && !$declared_return_type->isMixed()) {
if (!$declared_return_type->isMixed()) {
if ($inferred_return_type->isVoid() && $declared_return_type->isVoid()) {
return null;
}

View File

@ -39,9 +39,7 @@ class MethodChecker extends FunctionLikeChecker
if ($method_id = self::getDeclaringMethodId($project_checker, $method_id)) {
$storage = self::getStorage($project_checker, $method_id);
if ($storage) {
return $storage->params;
}
return $storage->params;
}
throw new \UnexpectedValueException('Cannot get method params for ' . $method_id);
@ -84,10 +82,6 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null for ' . $method_id);
}
if ($storage->return_type) {
return $storage->return_type;
}
@ -97,7 +91,7 @@ class MethodChecker extends FunctionLikeChecker
foreach ($class_storage->overridden_method_ids[$method_name] as $overridden_method_id) {
$overridden_storage = self::getStorage($project_checker, $overridden_method_id);
if ($overridden_storage && $overridden_storage->return_type) {
if ($overridden_storage->return_type) {
if ($overridden_storage->return_type->isNull()) {
return Type::getVoid();
}
@ -128,17 +122,13 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null for ' . $method_id);
}
if (!$storage->return_type_location) {
$overridden_method_ids = self::getOverriddenMethodIds($project_checker, $method_id);
foreach ($overridden_method_ids as $overridden_method_id) {
$overridden_storage = self::getStorage($project_checker, $overridden_method_id);
if ($overridden_storage && $overridden_storage->return_type_location) {
if ($overridden_storage->return_type_location) {
$defined_location = $overridden_storage->return_type_location;
break;
}
@ -262,10 +252,6 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null');
}
if (!$storage->is_static) {
if ($self_call) {
if (IssueBuffer::accepts(
@ -496,10 +482,6 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $declaring_method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null for ' . $declaring_method_id);
}
switch ($storage->visibility) {
case ClassLikeChecker::VISIBILITY_PUBLIC:
return true;
@ -583,10 +565,6 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $declaring_method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null for ' . $declaring_method_id);
}
switch ($storage->visibility) {
case ClassLikeChecker::VISIBILITY_PUBLIC:
return null;
@ -772,10 +750,6 @@ class MethodChecker extends FunctionLikeChecker
$storage = self::getStorage($project_checker, $method_id);
if (!$storage) {
throw new \UnexpectedValueException('$storage should not be null for ' . $method_id);
}
list($fq_class_name) = explode('::', $method_id);
return $fq_class_name . '::' . $storage->cased_name;

View File

@ -441,7 +441,6 @@ class ProjectChecker
/**
* @return void
* @psalm-suppress ParadoxicalCondition
*/
public function scanFiles()
{

View File

@ -1146,6 +1146,7 @@ class AssignmentChecker
// First go from the root element up, and go as far as we can to figure out what
// array types there are
while ($child_stmts) {
/** @var PhpParser\Node\Expr\ArrayDimFetch */
$child_stmt = array_shift($child_stmts);
if (count($child_stmts)) {

View File

@ -171,15 +171,13 @@ class CallChecker
if ($var_type_part instanceof Type\Atomic\Fn) {
$function_params = $var_type_part->params;
if ($var_type_part->return_type) {
if (isset($stmt->inferredType)) {
$stmt->inferredType = Type::combineUnionTypes(
$stmt->inferredType,
$var_type_part->return_type
);
} else {
$stmt->inferredType = $var_type_part->return_type;
}
if (isset($stmt->inferredType)) {
$stmt->inferredType = Type::combineUnionTypes(
$stmt->inferredType,
$var_type_part->return_type
);
} else {
$stmt->inferredType = $var_type_part->return_type;
}
$function_exists = true;
@ -2179,7 +2177,7 @@ class CallChecker
$array_arg_types[] = $array_arg_type;
}
/** @var PhpParser\Node\Arg */
/** @var ?PhpParser\Node\Arg */
$closure_arg = isset($args[$closure_index]) ? $args[$closure_index] : null;
/** @var Type\Union|null */
@ -2191,7 +2189,7 @@ class CallChecker
$project_checker = $file_checker->project_checker;
if ($closure_arg_type) {
if ($closure_arg && $closure_arg_type) {
$min_closure_param_count = $max_closure_param_count = count($array_arg_types);
if ($method_id === 'array_filter') {

View File

@ -850,7 +850,8 @@ class FetchChecker
if (!TypeChecker::isContainedBy(
$project_checker,
$offset_type,
$type->type_params[0]
$type->type_params[0],
$offset_type->ignore_nullable_issues
)) {
$invalid_offset_types[] = (string)$type->type_params[0];
} else {
@ -939,7 +940,7 @@ class FetchChecker
$type->properties[$int_key_value]
);
}
} elseif ($string_key_value && $in_assignment && $string_key_value) {
} elseif ($string_key_value && $in_assignment) {
$type->properties[$string_key_value] = new Type\Union([new TEmpty]);
if (!$array_access_type) {
@ -968,7 +969,8 @@ class FetchChecker
} elseif (TypeChecker::isContainedBy(
$project_checker,
$offset_type,
Type::getString()
Type::getString(),
$offset_type->ignore_nullable_issues
)) {
if ($replacement_type) {
$generic_params = Type::combineUnionTypes(

View File

@ -2085,23 +2085,21 @@ class ExpressionChecker
if (isset($stmt->if->inferredType)) {
$lhs_type = $stmt->if->inferredType;
}
} elseif ($stmt->cond) {
if (isset($stmt->cond->inferredType)) {
$if_return_type_reconciled = TypeChecker::reconcileTypes(
'!falsy',
$stmt->cond->inferredType,
'',
$statements_checker,
new CodeLocation($statements_checker->getSource(), $stmt),
$statements_checker->getSuppressedIssues()
);
} elseif (isset($stmt->cond->inferredType)) {
$if_return_type_reconciled = TypeChecker::reconcileTypes(
'!falsy',
$stmt->cond->inferredType,
'',
$statements_checker,
new CodeLocation($statements_checker->getSource(), $stmt),
$statements_checker->getSuppressedIssues()
);
if ($if_return_type_reconciled === false) {
return false;
}
$lhs_type = $if_return_type_reconciled;
if ($if_return_type_reconciled === false) {
return false;
}
$lhs_type = $if_return_type_reconciled;
}
if (!$lhs_type || !isset($stmt->else->inferredType)) {

View File

@ -409,6 +409,12 @@ return [
'phpparser\\node\\expr\\new_' => [
'args' => 'array<int, PhpParser\Node\Arg>',
],
'phpparser\node\expr\array_' => [
'items' => 'array<int, phpparser\node\expr\arrayitem>',
],
'phpparser\node\expr\list_' => [
'items' => 'array<int, phpparser\node\expr\arrayitem|null>',
],
'phpparser\\node\\expr\\methodcall' => [
'args' => 'array<int, PhpParser\Node\Arg>',
],

View File

@ -88,7 +88,8 @@ function array_diff_key(array $arr, array $arr2, array $arr3 = null, array $arr4
* @template TValue
*
* @param array<TKey, TValue> $arr
* @return TValue
* @return ?TValue
* @psalm-ignore-nullable-return
*/
function array_shift(array &$arr) {}
@ -97,7 +98,8 @@ function array_shift(array &$arr) {}
* @template TValue
*
* @param array<TKey, TValue> $arr
* @return TValue
* @return ?TValue
* @psalm-ignore-nullable-return
*/
function array_pop(array &$arr) {}

View File

@ -518,8 +518,8 @@ class ReturnTypeTest extends TestCase
],
'mixedInferredReturnType' => [
'<?php
function fooFoo() : string {
return array_pop([]);
function fooFoo(array $arr) : string {
return array_pop($arr);
}',
'error_message' => 'MixedInferredReturnType',
],