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

Fix #838 - check assertions, even outside conditionals

This commit is contained in:
Matt Brown 2018-06-25 18:02:05 -04:00
parent f2d96eefe7
commit ffda44c3ba
8 changed files with 1065 additions and 766 deletions

View File

@ -418,9 +418,7 @@ class ClassChecker extends ClassLikeChecker
}
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\ClassConst) {
foreach ($stmt->consts as $consts) {
$member_stmts[] = $stmt;
}
$member_stmts[] = $stmt;
}
}

View File

@ -765,7 +765,9 @@ class FunctionChecker extends FunctionLikeChecker
&& $stmt instanceof PhpParser\Node\Stmt\Return_
&& $stmt->expr
) {
$assertions = AssertionFinder::getAssertions($stmt->expr, null, $statements_checker);
AssertionFinder::scrapeAssertions($stmt->expr, null, $statements_checker);
$assertions = isset($stmt->expr->assertions) ? $stmt->expr->assertions : null;
if (isset($assertions['$' . $first_param->var->name])) {
$changed_var_ids = [];

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ use Psalm\Checker\CommentChecker;
use Psalm\Checker\FunctionLikeChecker;
use Psalm\Checker\ProjectChecker;
use Psalm\Checker\Statements\Expression\ArrayChecker;
use Psalm\Checker\Statements\Expression\AssertionFinder;
use Psalm\Checker\Statements\Expression\AssignmentChecker;
use Psalm\Checker\Statements\Expression\BinaryOpChecker;
use Psalm\Checker\Statements\Expression\Call\FunctionCallChecker;
@ -532,6 +533,22 @@ class ExpressionChecker
}
}
if (!$context->inside_conditional
&& ($stmt instanceof PhpParser\Node\Expr\BinaryOp
|| $stmt instanceof PhpParser\Node\Expr\Instanceof_
|| $stmt instanceof PhpParser\Node\Expr\Assign
|| $stmt instanceof PhpParser\Node\Expr\BooleanNot
|| $stmt instanceof PhpParser\Node\Expr\Empty_
|| $stmt instanceof PhpParser\Node\Expr\Isset_
|| $stmt instanceof PhpParser\Node\Expr\FuncCall)
) {
AssertionFinder::scrapeAssertions(
$stmt,
$context->self,
$statements_checker
);
}
$project_checker = $statements_checker->getFileChecker()->project_checker;
$plugin_classes = $project_checker->config->after_expression_checks;

View File

@ -396,6 +396,7 @@ return [
],
'phpparser\\node\\expr' => [
'inferredType' => 'Psalm\\Type\\Union|null',
'assertions' => 'array<string, array<int, array<int, string>>>|null',
],
'phpparser\\node\\name' => [
'inferredType' => 'Psalm\\Type\\Union|null',

View File

@ -118,13 +118,15 @@ class Algebra
return self::combineOredClauses($left_clauses, $right_clauses);
}
$assertions = AssertionFinder::getAssertions(
AssertionFinder::scrapeAssertions(
$conditional,
$this_class_name,
$source
);
if ($assertions) {
if (isset($conditional->assertions) && $conditional->assertions) {
$assertions = $conditional->assertions;
$clauses = [];
foreach ($assertions as $var => $anded_types) {

View File

@ -730,6 +730,30 @@ class RedundantConditionTest extends TestCase
}',
'error_message' => 'RedundantCondition',
],
'impossibleNullEquality' => [
'<?php
$i = 5;
echo $i !== null;',
'error_message' => 'RedundantCondition',
],
'impossibleTrueEquality' => [
'<?php
$i = 5;
echo $i !== true;',
'error_message' => 'RedundantCondition',
],
'impossibleFalseEquality' => [
'<?php
$i = 5;
echo $i !== false;',
'error_message' => 'RedundantCondition',
],
'impossibleNumberEquality' => [
'<?php
$i = 5;
echo $i !== 3;',
'error_message' => 'RedundantCondition',
],
];
}
}

View File

@ -1070,6 +1070,30 @@ class TypeReconciliationTest extends TestCase
}',
'error_message' => 'TypeDoesNotContainType',
],
'impossibleNullEquality' => [
'<?php
$i = 5;
echo $i === null;',
'error_message' => 'TypeDoesNotContainNull',
],
'impossibleTrueEquality' => [
'<?php
$i = 5;
echo $i === true;',
'error_message' => 'TypeDoesNotContainType',
],
'impossibleFalseEquality' => [
'<?php
$i = 5;
echo $i === false;',
'error_message' => 'TypeDoesNotContainType',
],
'impossibleNumberEquality' => [
'<?php
$i = 5;
echo $i === 3;',
'error_message' => 'TypeDoesNotContainType',
],
];
}
}