Skip to content

Commit

Permalink
Check for boolean in while conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Jan 22, 2025
1 parent 8b88b5f commit a48f7f2
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
10 changes: 10 additions & 0 deletions rules.neon
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ conditionalTags:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInBooleanOrRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\Cast\UselessCastRule:
phpstan.rules.rule: %strictRules.uselessCast%
PHPStan\Rules\Classes\RequireParentConstructCallRule:
Expand Down Expand Up @@ -163,6 +167,9 @@ services:
-
class: PHPStan\Rules\BooleansInConditions\BooleanInBooleanOrRule

-
class: PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule

-
class: PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule

Expand All @@ -172,6 +179,9 @@ services:
-
class: PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule

-
class: PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule

-
class: PHPStan\Rules\Cast\UselessCastRule
arguments:
Expand Down
47 changes: 47 additions & 0 deletions src/Rules/BooleansInConditions/BooleanInDoWhileConditionRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\BooleansInConditions;

use PhpParser\Node;
use PhpParser\Node\Stmt\Do_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\VerbosityLevel;
use function sprintf;

/**
* @implements Rule<Do_>
*/
class BooleanInDoWhileConditionRule implements Rule
{

private BooleanRuleHelper $helper;

public function __construct(BooleanRuleHelper $helper)
{
$this->helper = $helper;
}

public function getNodeType(): string
{
return Do_::class;
}

public function processNode(Node $node, Scope $scope): array
{
if ($this->helper->passesAsBoolean($scope, $node->cond)) {
return [];
}

$conditionExpressionType = $scope->getType($node->cond);

return [
RuleErrorBuilder::message(sprintf(
'Only booleans are allowed in a do-while condition, %s given.',
$conditionExpressionType->describe(VerbosityLevel::typeOnly()),
))->identifier('doWhile.condNotBoolean')->build(),
];
}

}
47 changes: 47 additions & 0 deletions src/Rules/BooleansInConditions/BooleanInWhileConditionRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\BooleansInConditions;

use PhpParser\Node;
use PhpParser\Node\Stmt\While_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\VerbosityLevel;
use function sprintf;

/**
* @implements Rule<While_>
*/
class BooleanInWhileConditionRule implements Rule
{

private BooleanRuleHelper $helper;

public function __construct(BooleanRuleHelper $helper)
{
$this->helper = $helper;
}

public function getNodeType(): string
{
return While_::class;
}

public function processNode(Node $node, Scope $scope): array
{
if ($this->helper->passesAsBoolean($scope, $node->cond)) {
return [];
}

$conditionExpressionType = $scope->getType($node->cond);

return [
RuleErrorBuilder::message(sprintf(
'Only booleans are allowed in a while condition, %s given.',
$conditionExpressionType->describe(VerbosityLevel::typeOnly()),
))->identifier('while.condNotBoolean')->build(),
];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php declare(strict_types = 1);

namespace Rules\BooleansInConditions;

use PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule;
use PHPStan\Rules\BooleansInConditions\BooleanRuleHelper;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleLevelHelper;
use PHPStan\Testing\RuleTestCase;

/**
* @extends RuleTestCase<BooleanInDoWhileConditionRule>
*/
class BooleanInDoWhileConditionRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new BooleanInDoWhileConditionRule(

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.
new BooleanRuleHelper(

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.
self::getContainer()->getByType(RuleLevelHelper::class),
),
);
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/conditions.php'], [
[
'Only booleans are allowed in a do-while condition, string given.',
60,
],
]);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php declare(strict_types = 1);

namespace Rules\BooleansInConditions;

use PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule;
use PHPStan\Rules\BooleansInConditions\BooleanRuleHelper;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleLevelHelper;
use PHPStan\Testing\RuleTestCase;

/**
* @extends RuleTestCase<BooleanInWhileConditionRule>
*/
class BooleanInWhileConditionRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new BooleanInWhileConditionRule(

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 19 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule is not covered by backward compatibility promise. The class might change in a minor PHPStan version.
new BooleanRuleHelper(

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, highest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.

Check failure on line 20 in tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, lowest)

Creating new PHPStan\Rules\BooleansInConditions\BooleanRuleHelper is not covered by backward compatibility promise. The class might change in a minor PHPStan version.
self::getContainer()->getByType(RuleLevelHelper::class),
),
);
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/conditions.php'], [
[
'Only booleans are allowed in a while condition, string given.',
55,
],
]);
}

}
10 changes: 10 additions & 0 deletions tests/Rules/BooleansInConditions/data/conditions.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,13 @@
$explicitMixed and $bool;
$bool or $explicitMixed;
$explicitMixed or $bool;

$someBool = true;
$someString = 'string';
while ($someBool) { $someBool = !$someBool; }
while ($someString) { $someString = ''; }

$someBool = true;
$someString = 'string';
do { $someBool = !$someBool; } while ($someBool);
do { $someString = ''; } while ($someString);

0 comments on commit a48f7f2

Please sign in to comment.