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

Fix bad comparisons

This commit is contained in:
Matt Brown 2018-05-08 17:42:02 -04:00
parent 03ea65cff8
commit 4f678f5f99
3 changed files with 69 additions and 39 deletions

View File

@ -201,13 +201,11 @@ class ExpressionChecker
$stmt->inferredType = clone $stmt->var->inferredType;
$stmt->inferredType->from_calculation = true;
if ($context->inside_loop) {
foreach ($stmt->inferredType->getTypes() as $atomic_type) {
if ($atomic_type instanceof Type\Atomic\TLiteralInt) {
$stmt->inferredType->addType(new Type\Atomic\TInt);
} elseif ($atomic_type instanceof Type\Atomic\TLiteralFloat) {
$stmt->inferredType->addType(new Type\Atomic\TFloat);
}
foreach ($stmt->inferredType->getTypes() as $atomic_type) {
if ($atomic_type instanceof Type\Atomic\TLiteralInt) {
$stmt->inferredType->addType(new Type\Atomic\TInt);
} elseif ($atomic_type instanceof Type\Atomic\TLiteralFloat) {
$stmt->inferredType->addType(new Type\Atomic\TFloat);
}
}
@ -868,7 +866,7 @@ class ExpressionChecker
Context $context
) {
foreach ($stmt->uses as $use) {
if (!$use->var->name instanceof PhpParser\Node\Identifier) {
if (!is_string($use->var->name)) {
continue;
}
@ -890,7 +888,40 @@ class ExpressionChecker
return;
}
if (!isset($context->vars_possibly_in_scope[$use_var_id])) {
if ($use_var_id !== '$argv' && $use_var_id !== '$argc') {
if (!isset($context->vars_possibly_in_scope[$use_var_id])) {
if ($context->check_variables) {
if (IssueBuffer::accepts(
new UndefinedVariable(
'Cannot find referenced variable ' . $use_var_id,
new CodeLocation($statements_checker->getSource(), $use->var)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
return null;
}
}
$first_appearance = $statements_checker->getFirstAppearance($use_var_id);
if ($first_appearance) {
if (IssueBuffer::accepts(
new PossiblyUndefinedVariable(
'Possibly undefined variable ' . $use_var_id . ', first seen on line ' .
$first_appearance->getLineNumber(),
new CodeLocation($statements_checker->getSource(), $use->var)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
continue;
}
if ($context->check_variables) {
if (IssueBuffer::accepts(
new UndefinedVariable(
@ -902,39 +933,18 @@ class ExpressionChecker
return false;
}
return null;
continue;
}
}
$first_appearance = $statements_checker->getFirstAppearance($use_var_id);
if ($first_appearance) {
if (IssueBuffer::accepts(
new PossiblyUndefinedVariable(
'Possibly undefined variable ' . $use_var_id . ', first seen on line ' .
$first_appearance->getLineNumber(),
new CodeLocation($statements_checker->getSource(), $use->var)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
} else {
foreach ($context->vars_in_scope[$use_var_id]->getTypes() as $atomic_type) {
if ($atomic_type instanceof Type\Atomic\TLiteralInt) {
$context->vars_in_scope[$use_var_id]->addType(new Type\Atomic\TInt);
} elseif ($atomic_type instanceof Type\Atomic\TLiteralFloat) {
$context->vars_in_scope[$use_var_id]->addType(new Type\Atomic\TFloat);
} elseif ($atomic_type instanceof Type\Atomic\TLiteralString) {
$context->vars_in_scope[$use_var_id]->addType(new Type\Atomic\TString);
}
continue;
}
if ($context->check_variables) {
if (IssueBuffer::accepts(
new UndefinedVariable(
'Cannot find referenced variable ' . $use_var_id,
new CodeLocation($statements_checker->getSource(), $use->var)
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
continue;
}
}
}

View File

@ -775,6 +775,11 @@ class CallableTest extends TestCase
}',
'error_message' => 'LessSpecificReturnStatement',
],
'undefinedVariable' => [
'<?php
$a = function() use ($i) {};',
'error_message' => 'UndefinedVariable',
],
];
}
}

View File

@ -205,6 +205,21 @@ class ValueTest extends TestCase
return "hello";
}',
],
'incrementAndCheck' => [
'<?php
$i = 0;
if (rand(0, 1)) $i++;
if ($i === 1) {}'
],
'incrementInClosureAndCheck' => [
'<?php
$i = 0;
$a = function() use (&$i) : void {
if (rand(0, 1)) $i++;
};
$a();
if ($i === 0) {}',
],
];
}