Skip to content

Commit d892c34

Browse files
committed
ConstantLooseComparisonRule - tip about treatPhpDocTypesAsCertain
1 parent 72472dd commit d892c34

4 files changed

Lines changed: 40 additions & 6 deletions

File tree

phpstan-baseline.neon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ parameters:
457457

458458
-
459459
message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantBooleanType is error\\-prone and deprecated\\. Use Type\\:\\:isTrue\\(\\) or Type\\:\\:isFalse\\(\\) instead\\.$#"
460-
count: 1
460+
count: 2
461461
path: src/Rules/Comparison/ConstantLooseComparisonRule.php
462462

463463
-
@@ -515,7 +515,7 @@ parameters:
515515

516516
-
517517
message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantBooleanType is error\\-prone and deprecated\\. Use Type\\:\\:isTrue\\(\\) or Type\\:\\:isFalse\\(\\) instead\\.$#"
518-
count: 1
518+
count: 2
519519
path: src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php
520520

521521
-

src/Rules/Comparison/ConstantLooseComparisonRule.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,40 @@ public function processNode(Node $node, Scope $scope): array
4141
return [];
4242
}
4343

44+
$addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $node): RuleErrorBuilder {
45+
if (!$this->treatPhpDocTypesAsCertain) {
46+
return $ruleErrorBuilder;
47+
}
48+
49+
$instanceofTypeWithoutPhpDocs = $scope->getNativeType($node);
50+
if ($instanceofTypeWithoutPhpDocs instanceof ConstantBooleanType) {
51+
return $ruleErrorBuilder;
52+
}
53+
54+
return $ruleErrorBuilder->tip('Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.');
55+
};
56+
4457
if (!$nodeType->getValue()) {
4558
return [
46-
RuleErrorBuilder::message(sprintf(
59+
$addTip(RuleErrorBuilder::message(sprintf(
4760
'Loose comparison using %s between %s and %s will always evaluate to false.',
4861
$node instanceof Node\Expr\BinaryOp\Equal ? '==' : '!=',
4962
$scope->getType($node->left)->describe(VerbosityLevel::value()),
5063
$scope->getType($node->right)->describe(VerbosityLevel::value()),
51-
))->build(),
64+
)))->build(),
5265
];
5366
} elseif ($this->checkAlwaysTrueLooseComparison) {
5467
$isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME);
5568
if ($isLast === true && !$this->reportAlwaysTrueInLastCondition) {
5669
return [];
5770
}
5871

59-
$errorBuilder = RuleErrorBuilder::message(sprintf(
72+
$errorBuilder = $addTip(RuleErrorBuilder::message(sprintf(
6073
'Loose comparison using %s between %s and %s will always evaluate to true.',
6174
$node instanceof Node\Expr\BinaryOp\Equal ? '==' : '!=',
6275
$scope->getType($node->left)->describe(VerbosityLevel::value()),
6376
$scope->getType($node->right)->describe(VerbosityLevel::value()),
64-
));
77+
)));
6578
if ($isLast === false && !$this->reportAlwaysTrueInLastCondition) {
6679
$errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.');
6780
}

tests/PHPStan/Rules/Comparison/ConstantLooseComparisonRuleTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public function testRule(): void
3939
"Loose comparison using == between 0 and '1' will always evaluate to false.",
4040
33,
4141
],
42+
[
43+
'Loose comparison using != between 3 and 3 will always evaluate to false.',
44+
48,
45+
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
46+
],
4247
]);
4348
}
4449

@@ -67,6 +72,11 @@ public function testRuleAlwaysTrue(): void
6772
35,
6873
'Remove remaining cases below this one and this error will disappear too.',
6974
],
75+
[
76+
'Loose comparison using != between 3 and 3 will always evaluate to false.',
77+
48,
78+
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
79+
],
7080
]);
7181
}
7282

@@ -140,6 +150,7 @@ public function dataTreatPhpDocTypesAsCertain(): iterable
140150
[
141151
'Loose comparison using == between 3 and 3 will always evaluate to true.',
142152
14,
153+
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
143154
],
144155
]];
145156
}

tests/PHPStan/Rules/Comparison/data/loose-comparison.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,14 @@ public function doFooBar(): void
4040

4141
}
4242

43+
/**
44+
* @param 3 $i
45+
*/
46+
public function doLiteralIntInPhpDoc(int $i)
47+
{
48+
if ($i != 3) {
49+
throw new \LogicException();
50+
}
51+
}
52+
4353
}

0 commit comments

Comments
 (0)