Skip to content
Permalink
Browse files

Improve handling of negated boolean operations

  • Loading branch information...
muglug committed Apr 12, 2019
1 parent b6d0ee0 commit 8751bf232bd8c04b1a7de94915e9e7d9f0e09137
Showing with 68 additions and 23 deletions.
  1. +43 −11 src/Psalm/Type/Algebra.php
  2. +25 −12 tests/TypeAlgebraTest.php
@@ -127,18 +127,50 @@ public static function getFormula(
return self::combineOredClauses($left_clauses, $right_clauses);
}
if ($conditional instanceof PhpParser\Node\Expr\BooleanNot
&& $conditional->expr instanceof PhpParser\Node\Expr\BinaryOp
) {
$negated_clauses = self::getFormula(
$conditional->expr,
$this_class_name,
$source,
$codebase,
!$inside_negation
);
if ($conditional instanceof PhpParser\Node\Expr\BooleanNot) {
if ($conditional->expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
$and_expr = new PhpParser\Node\Expr\BinaryOp\BooleanAnd(
new PhpParser\Node\Expr\BooleanNot(
$conditional->expr->left,
$conditional->getAttributes()
),
new PhpParser\Node\Expr\BooleanNot(
$conditional->expr->right,
$conditional->getAttributes()
),
$conditional->expr->getAttributes()
);
return self::negateFormula($negated_clauses);
return self::getFormula(
$and_expr,
$this_class_name,
$source,
$codebase,
$inside_negation
);
}
if ($conditional->expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
$and_expr = new PhpParser\Node\Expr\BinaryOp\BooleanOr(
new PhpParser\Node\Expr\BooleanNot(
$conditional->expr->left,
$conditional->getAttributes()
),
new PhpParser\Node\Expr\BooleanNot(
$conditional->expr->right,
$conditional->getAttributes()
),
$conditional->expr->getAttributes()
);
return self::getFormula(
$and_expr,
$this_class_name,
$source,
$codebase,
$inside_negation
);
}
}
AssertionFinder::scrapeAssertions(
@@ -904,19 +904,32 @@ function bad(A $x) : void {
],
'invertEquation' => [
'<?php
/**
* @param mixed $width
* @param mixed $height
*
* @throws RuntimeException
*/
function Foo($width, $height) : void {
if (!(is_int($width) || is_float($width)) || !(is_int($height) || is_float($height))) {
throw new RuntimeException("bad");
}
/**
* @param mixed $width
* @param mixed $height
*
* @throws RuntimeException
*/
function Foo($width, $height) : void {
if (!(is_int($width) || is_float($width)) || !(is_int($height) || is_float($height))) {
throw new RuntimeException("bad");
}
echo sprintf("padding-top:%s%%;", 100 * ($height/$width));
}'
],
'invertLogic' => [
'<?php
class A {}
class B extends A {}
echo sprintf("padding-top:%s%%;", 100 * ($height/$width));
}'
function foo(?A $a) : A {
if (!$a || !($a instanceof B && rand(0, 1))) {
throw new Exception();
}
return $a;
}'
],
];
}

0 comments on commit 8751bf2

Please sign in to comment.
You can’t perform that action at this time.