Skip to content

Commit

Permalink
Merge pull request #7622 from orklah/assertions
Browse files Browse the repository at this point in the history
consistency in AssertionFinder
  • Loading branch information
orklah committed Feb 9, 2022
2 parents 2eca28c + 5111775 commit 9984397
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 73 deletions.
171 changes: 99 additions & 72 deletions src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php
Expand Up @@ -378,30 +378,31 @@ private static function scrapeEqualityAssertions(
);
}

$true_position = self::hasTrueVariable($conditional);
$false_position = self::hasFalseVariable($conditional);

if ($true_position) {
return self::getTrueEqualityAssertions(
if ($false_position) {
return self::getFalseEqualityAssertions(
$conditional,
$this_class_name,
$source,
$codebase,
$false_position,
$cache,
$true_position
$inside_conditional
);
}

$false_position = self::hasFalseVariable($conditional);
$true_position = self::hasTrueVariable($conditional);

if ($false_position) {
return self::getFalseEqualityAssertions(
if ($true_position) {
return self::getTrueEqualityAssertions(
$conditional,
$this_class_name,
$source,
$codebase,
$true_position,
$cache,
$inside_conditional,
$false_position
$inside_conditional
);
}

Expand Down Expand Up @@ -439,9 +440,7 @@ private static function scrapeEqualityAssertions(
);
}

if (!$source instanceof StatementsAnalyzer) {
return [];
}


$count = null;
$count_equality_position = self::hasCountEqualityCheck($conditional, $count);
Expand All @@ -464,22 +463,24 @@ private static function scrapeEqualityAssertions(
$source
);

$var_type = $source->node_data->getType($conditional->left);
$other_type = $source->node_data->getType($conditional->right);
if ($source instanceof StatementsAnalyzer) {
$var_type = $source->node_data->getType($conditional->left);
$other_type = $source->node_data->getType($conditional->right);

if ($codebase
&& $other_type
&& $var_type
&& $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical
) {
self::handleParadoxicalAssertions(
$source,
$var_type,
$this_class_name,
$other_type,
$codebase,
$conditional
);
if ($codebase
&& $other_type
&& $var_type
&& $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical
) {
self::handleParadoxicalAssertions(
$source,
$var_type,
$this_class_name,
$other_type,
$codebase,
$conditional
);
}
}

if ($var_name) {
Expand All @@ -493,6 +494,10 @@ private static function scrapeEqualityAssertions(
return $if_types ? [$if_types] : [];
}

if (!$source instanceof StatementsAnalyzer) {
return [];
}

$getclass_position = self::hasGetClassCheck($conditional, $source);

if ($getclass_position) {
Expand Down Expand Up @@ -601,61 +606,29 @@ private static function scrapeInequalityAssertions(
if ($false_position) {
return self::getFalseInequalityAssertions(
$conditional,
$cache,
$this_class_name,
$source,
$inside_conditional,
$codebase,
$false_position
$false_position,
$cache,
$inside_conditional
);
}

$true_position = self::hasTrueVariable($conditional);

if ($true_position) {
return self::getTrueInequalityAssertions(
$true_position,
$conditional,
$this_class_name,
$source,
$codebase,
$true_position,
$cache,
$inside_conditional
);
}

$count = null;
$count_inequality_position = self::hasCountEqualityCheck($conditional, $count);

if ($count_inequality_position) {
$if_types = [];

if ($count_inequality_position === self::ASSIGNMENT_TO_RIGHT) {
$count_expr = $conditional->left;
} elseif ($count_inequality_position === self::ASSIGNMENT_TO_LEFT) {
$count_expr = $conditional->right;
} else {
throw new UnexpectedValueException('$count_equality_position value');
}

/** @var PhpParser\Node\Expr\FuncCall $count_expr */
$var_name = ExpressionIdentifier::getExtendedVarId(
$count_expr->getArgs()[0]->value,
$this_class_name,
$source
);

if ($var_name) {
if ($count > 0) {
$if_types[$var_name] = [[new DoesNotHaveExactCount($count)]];
} else {
$if_types[$var_name] = [[new NonEmptyCountable(true)]];
}
}

return $if_types ? [$if_types] : [];
}

$empty_array_position = self::hasEmptyArrayVariable($conditional);

if ($empty_array_position !== null) {
Expand Down Expand Up @@ -690,6 +663,58 @@ private static function scrapeInequalityAssertions(
);
}

$count = null;
$count_inequality_position = self::hasCountEqualityCheck($conditional, $count);

if ($count_inequality_position) {
$if_types = [];

if ($count_inequality_position === self::ASSIGNMENT_TO_RIGHT) {
$count_expr = $conditional->left;
} elseif ($count_inequality_position === self::ASSIGNMENT_TO_LEFT) {
$count_expr = $conditional->right;
} else {
throw new UnexpectedValueException('$count_inequality_position value');
}

/** @var PhpParser\Node\Expr\FuncCall $count_expr */
$var_name = ExpressionIdentifier::getExtendedVarId(
$count_expr->getArgs()[0]->value,
$this_class_name,
$source
);

if ($source instanceof StatementsAnalyzer) {
$var_type = $source->node_data->getType($conditional->left);
$other_type = $source->node_data->getType($conditional->right);

if ($codebase
&& $other_type
&& $var_type
&& $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical
) {
self::handleParadoxicalAssertions(
$source,
$var_type,
$this_class_name,
$other_type,
$codebase,
$conditional
);
}
}

if ($var_name) {
if ($count > 0) {
$if_types[$var_name] = [[new DoesNotHaveExactCount($count)]];
} else {
$if_types[$var_name] = [[new NonEmptyCountable(true)]];
}
}

return $if_types ? [$if_types] : [];
}

if (!$source instanceof StatementsAnalyzer) {
return [];
}
Expand Down Expand Up @@ -1782,7 +1807,7 @@ protected static function hasReconcilableNonEmptyCountEqualityCheck(
}

/**
* @param Identical|Equal|Smaller|SmallerOrEqual|NotIdentical|NotEqual $conditional
* @param Identical|Equal|NotIdentical|NotEqual $conditional
* @return false|int
*/
protected static function hasTypedValueComparison(
Expand Down Expand Up @@ -2118,12 +2143,12 @@ private static function getNullInequalityAssertions(
*/
private static function getFalseInequalityAssertions(
PhpParser\Node\Expr\BinaryOp $conditional,
bool $cache,
?string $this_class_name,
FileSource $source,
bool $inside_conditional,
?Codebase $codebase,
int $false_position
int $false_position,
bool $cache,
bool $inside_conditional
): array {
$if_types = [];

Expand Down Expand Up @@ -2235,11 +2260,11 @@ private static function getFalseInequalityAssertions(
* @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
*/
private static function getTrueInequalityAssertions(
int $true_position,
PhpParser\Node\Expr\BinaryOp $conditional,
?string $this_class_name,
FileSource $source,
?Codebase $codebase,
int $true_position,
bool $cache,
bool $inside_conditional
): array {
Expand Down Expand Up @@ -2811,8 +2836,9 @@ private static function getTrueEqualityAssertions(
?string $this_class_name,
FileSource $source,
?Codebase $codebase,
int $true_position,
bool $cache,
int $true_position
bool $inside_conditional
): array {
$if_types = [];

Expand Down Expand Up @@ -2861,7 +2887,8 @@ private static function getTrueEqualityAssertions(
$source,
$codebase,
false,
$cache
$cache,
$inside_conditional
);

if ($source instanceof StatementsAnalyzer && $cache) {
Expand Down Expand Up @@ -2935,9 +2962,9 @@ private static function getFalseEqualityAssertions(
?string $this_class_name,
FileSource $source,
?Codebase $codebase,
int $false_position,
bool $cache,
bool $inside_conditional,
int $false_position
bool $inside_conditional
): array {
$if_types = [];

Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Type/NegatedAssertionReconciler.php
Expand Up @@ -179,7 +179,7 @@ public static function reconcile(
clone $iterable->type_params[1],
]
));
} elseif ($assertion_type instanceof TInt
} elseif ($assertion_type !== null && get_class($assertion_type) === TInt::class
&& isset($existing_var_type->getAtomicTypes()['array-key'])
&& !$is_equality
) {
Expand Down

0 comments on commit 9984397

Please sign in to comment.