Skip to content

Commit 6b3f2d1

Browse files
committed
Added ConstantConditionInTraitHelper to remaining rules
1 parent 7e4ade3 commit 6b3f2d1

File tree

50 files changed

+1749
-280
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1749
-280
lines changed

src/Rules/Comparison/BooleanAndConstantConditionRule.php

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PHPStan\Rules\Comparison;
44

55
use PhpParser\Node;
6+
use PHPStan\Analyser\CollectedDataEmitter;
7+
use PHPStan\Analyser\NodeCallbackInvoker;
68
use PHPStan\Analyser\Scope;
79
use PHPStan\DependencyInjection\AutowiredParameter;
810
use PHPStan\DependencyInjection\RegisteredRule;
@@ -24,6 +26,7 @@ final class BooleanAndConstantConditionRule implements Rule
2426
public function __construct(
2527
private ConstantConditionRuleHelper $helper,
2628
private PossiblyImpureTipHelper $possiblyImpureTipHelper,
29+
private ConstantConditionInTraitHelper $constantConditionInTraitHelper,
2730
#[AutowiredParameter]
2831
private bool $treatPhpDocTypesAsCertain,
2932
#[AutowiredParameter]
@@ -41,14 +44,16 @@ public function getNodeType(): string
4144

4245
public function processNode(
4346
Node $node,
44-
Scope $scope,
47+
Scope&NodeCallbackInvoker&CollectedDataEmitter $scope,
4548
): array
4649
{
4750
$errors = [];
4851
$originalNode = $node->getOriginalNode();
4952
$nodeText = $originalNode->getOperatorSigil();
5053
$leftType = $this->helper->getBooleanType($scope, $originalNode->left);
5154
$identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'logicalAnd';
55+
$isInTrait = $scope->isInTrait();
56+
$hasLeftOrRightError = false;
5257
if ($leftType instanceof ConstantBooleanType) {
5358
$addTipLeft = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $originalNode): RuleErrorBuilder {
5459
if (!$this->treatPhpDocTypesAsCertain) {
@@ -80,8 +85,18 @@ public function processNode(
8085
if ($leftType->getValue() && $isLast === false && !$this->reportAlwaysTrueInLastCondition) {
8186
$errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.');
8287
}
83-
$errors[] = $errorBuilder->build();
88+
$ruleError = $errorBuilder->build();
89+
$hasLeftOrRightError = true;
90+
if ($isInTrait) {
91+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode->left, $leftType->getValue(), $ruleError);
92+
} else {
93+
$errors[] = $ruleError;
94+
}
95+
} else {
96+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->left);
8497
}
98+
} else {
99+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->left);
85100
}
86101

87102
$rightScope = $node->getRightScope();
@@ -123,11 +138,21 @@ public function processNode(
123138
if ($rightType->getValue() && $isLast === false && !$this->reportAlwaysTrueInLastCondition) {
124139
$errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.');
125140
}
126-
$errors[] = $errorBuilder->build();
141+
$ruleError = $errorBuilder->build();
142+
$hasLeftOrRightError = true;
143+
if ($isInTrait) {
144+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode->right, $rightType->getValue(), $ruleError);
145+
} else {
146+
$errors[] = $ruleError;
147+
}
148+
} else {
149+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->right);
127150
}
151+
} else {
152+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->right);
128153
}
129154

130-
if (count($errors) === 0 && !$scope->isInFirstLevelStatement()) {
155+
if (count($errors) === 0 && !$hasLeftOrRightError && !$scope->isInFirstLevelStatement()) {
131156
$nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($originalNode) : $scope->getNativeType($originalNode);
132157
if ($nodeType instanceof ConstantBooleanType) {
133158
$addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $originalNode): RuleErrorBuilder {
@@ -161,8 +186,17 @@ public function processNode(
161186

162187
$errorBuilder->identifier(sprintf('%s.always%s', $identifierType, $nodeType->getValue() ? 'True' : 'False'));
163188

164-
$errors[] = $errorBuilder->build();
189+
$ruleError = $errorBuilder->build();
190+
if ($isInTrait) {
191+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode, $nodeType->getValue(), $ruleError);
192+
} else {
193+
$errors[] = $ruleError;
194+
}
195+
} else {
196+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode);
165197
}
198+
} else {
199+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode);
166200
}
167201
}
168202

src/Rules/Comparison/BooleanNotConstantConditionRule.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PHPStan\Rules\Comparison;
44

55
use PhpParser\Node;
6+
use PHPStan\Analyser\CollectedDataEmitter;
7+
use PHPStan\Analyser\NodeCallbackInvoker;
68
use PHPStan\Analyser\Scope;
79
use PHPStan\DependencyInjection\AutowiredParameter;
810
use PHPStan\DependencyInjection\RegisteredRule;
@@ -22,6 +24,7 @@ final class BooleanNotConstantConditionRule implements Rule
2224
public function __construct(
2325
private ConstantConditionRuleHelper $helper,
2426
private PossiblyImpureTipHelper $possiblyImpureTipHelper,
27+
private ConstantConditionInTraitHelper $constantConditionInTraitHelper,
2528
#[AutowiredParameter]
2629
private bool $treatPhpDocTypesAsCertain,
2730
#[AutowiredParameter]
@@ -39,7 +42,7 @@ public function getNodeType(): string
3942

4043
public function processNode(
4144
Node $node,
42-
Scope $scope,
45+
Scope&NodeCallbackInvoker&CollectedDataEmitter $scope,
4346
): array
4447
{
4548
$exprType = $this->helper->getBooleanType($scope, $node->expr);
@@ -74,12 +77,17 @@ public function processNode(
7477

7578
$errorBuilder->identifier(sprintf('booleanNot.always%s', $exprType->getValue() ? 'False' : 'True'));
7679

77-
return [
78-
$errorBuilder->build(),
79-
];
80+
$ruleError = $errorBuilder->build();
81+
if ($scope->isInTrait()) {
82+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $node->expr, !$exprType->getValue(), $ruleError);
83+
return [];
84+
}
85+
86+
return [$ruleError];
8087
}
8188
}
8289

90+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $node->expr);
8391
return [];
8492
}
8593

src/Rules/Comparison/BooleanOrConstantConditionRule.php

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PHPStan\Rules\Comparison;
44

55
use PhpParser\Node;
6+
use PHPStan\Analyser\CollectedDataEmitter;
7+
use PHPStan\Analyser\NodeCallbackInvoker;
68
use PHPStan\Analyser\Scope;
79
use PHPStan\DependencyInjection\AutowiredParameter;
810
use PHPStan\DependencyInjection\RegisteredRule;
@@ -24,6 +26,7 @@ final class BooleanOrConstantConditionRule implements Rule
2426
public function __construct(
2527
private ConstantConditionRuleHelper $helper,
2628
private PossiblyImpureTipHelper $possiblyImpureTipHelper,
29+
private ConstantConditionInTraitHelper $constantConditionInTraitHelper,
2730
#[AutowiredParameter]
2831
private bool $treatPhpDocTypesAsCertain,
2932
#[AutowiredParameter]
@@ -41,14 +44,16 @@ public function getNodeType(): string
4144

4245
public function processNode(
4346
Node $node,
44-
Scope $scope,
47+
Scope&NodeCallbackInvoker&CollectedDataEmitter $scope,
4548
): array
4649
{
4750
$originalNode = $node->getOriginalNode();
4851
$nodeText = $originalNode->getOperatorSigil();
4952
$messages = [];
5053
$leftType = $this->helper->getBooleanType($scope, $originalNode->left);
5154
$identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanOr ? 'booleanOr' : 'logicalOr';
55+
$isInTrait = $scope->isInTrait();
56+
$hasLeftOrRightError = false;
5257
if ($leftType instanceof ConstantBooleanType) {
5358
$addTipLeft = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $originalNode): RuleErrorBuilder {
5459
if (!$this->treatPhpDocTypesAsCertain) {
@@ -80,8 +85,18 @@ public function processNode(
8085
if ($leftType->getValue() && $isLast === false && !$this->reportAlwaysTrueInLastCondition) {
8186
$errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.');
8287
}
83-
$messages[] = $errorBuilder->build();
88+
$ruleError = $errorBuilder->build();
89+
$hasLeftOrRightError = true;
90+
if ($isInTrait) {
91+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode->left, $leftType->getValue(), $ruleError);
92+
} else {
93+
$messages[] = $ruleError;
94+
}
95+
} else {
96+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->left);
8497
}
98+
} else {
99+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->left);
85100
}
86101

87102
$rightScope = $node->getRightScope();
@@ -123,11 +138,21 @@ public function processNode(
123138
if ($rightType->getValue() && $isLast === false && !$this->reportAlwaysTrueInLastCondition) {
124139
$errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.');
125140
}
126-
$messages[] = $errorBuilder->build();
141+
$ruleError = $errorBuilder->build();
142+
$hasLeftOrRightError = true;
143+
if ($isInTrait) {
144+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode->right, $rightType->getValue(), $ruleError);
145+
} else {
146+
$messages[] = $ruleError;
147+
}
148+
} else {
149+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->right);
127150
}
151+
} else {
152+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode->right);
128153
}
129154

130-
if (count($messages) === 0 && !$scope->isInFirstLevelStatement()) {
155+
if (count($messages) === 0 && !$hasLeftOrRightError && !$scope->isInFirstLevelStatement()) {
131156
$nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($originalNode) : $scope->getNativeType($originalNode);
132157
if ($nodeType instanceof ConstantBooleanType) {
133158
$addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $originalNode): RuleErrorBuilder {
@@ -161,8 +186,17 @@ public function processNode(
161186

162187
$errorBuilder->identifier(sprintf('%s.always%s', $identifierType, $nodeType->getValue() ? 'True' : 'False'));
163188

164-
$messages[] = $errorBuilder->build();
189+
$ruleError = $errorBuilder->build();
190+
if ($isInTrait) {
191+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $originalNode, $nodeType->getValue(), $ruleError);
192+
} else {
193+
$messages[] = $ruleError;
194+
}
195+
} else {
196+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode);
165197
}
198+
} else {
199+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $originalNode);
166200
}
167201
}
168202

src/Rules/Comparison/ConstantLooseComparisonRule.php

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PHPStan\Rules\Comparison;
44

55
use PhpParser\Node;
6+
use PHPStan\Analyser\CollectedDataEmitter;
7+
use PHPStan\Analyser\NodeCallbackInvoker;
68
use PHPStan\Analyser\Scope;
79
use PHPStan\DependencyInjection\AutowiredParameter;
810
use PHPStan\DependencyInjection\RegisteredRule;
@@ -21,6 +23,7 @@ final class ConstantLooseComparisonRule implements Rule
2123

2224
public function __construct(
2325
private PossiblyImpureTipHelper $possiblyImpureTipHelper,
26+
private ConstantConditionInTraitHelper $constantConditionInTraitHelper,
2427
#[AutowiredParameter]
2528
private bool $treatPhpDocTypesAsCertain,
2629
#[AutowiredParameter]
@@ -36,14 +39,15 @@ public function getNodeType(): string
3639
return Node\Expr\BinaryOp::class;
3740
}
3841

39-
public function processNode(Node $node, Scope $scope): array
42+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
4043
{
4144
if (!$node instanceof Node\Expr\BinaryOp\Equal && !$node instanceof Node\Expr\BinaryOp\NotEqual) {
4245
return [];
4346
}
4447

4548
$nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node) : $scope->getNativeType($node);
4649
if (!$nodeType->isTrue()->yes() && !$nodeType->isFalse()->yes()) {
50+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $node);
4751
return [];
4852
}
4953

@@ -66,18 +70,23 @@ public function processNode(Node $node, Scope $scope): array
6670
};
6771

6872
if ($nodeType->isFalse()->yes()) {
69-
return [
70-
$addTip(RuleErrorBuilder::message(sprintf(
71-
'Loose comparison using %s between %s and %s will always evaluate to false.',
72-
$node->getOperatorSigil(),
73-
$scope->getType($node->left)->describe(VerbosityLevel::value()),
74-
$scope->getType($node->right)->describe(VerbosityLevel::value()),
75-
)))->identifier(sprintf('%s.alwaysFalse', $node instanceof Node\Expr\BinaryOp\Equal ? 'equal' : 'notEqual'))->build(),
76-
];
73+
$ruleError = $addTip(RuleErrorBuilder::message(sprintf(
74+
'Loose comparison using %s between %s and %s will always evaluate to false.',
75+
$node->getOperatorSigil(),
76+
$scope->getType($node->left)->describe(VerbosityLevel::value()),
77+
$scope->getType($node->right)->describe(VerbosityLevel::value()),
78+
)))->identifier(sprintf('%s.alwaysFalse', $node instanceof Node\Expr\BinaryOp\Equal ? 'equal' : 'notEqual'))->build();
79+
if ($scope->isInTrait()) {
80+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $node, false, $ruleError);
81+
return [];
82+
}
83+
84+
return [$ruleError];
7785
}
7886

7987
$isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME);
8088
if ($isLast === true && !$this->reportAlwaysTrueInLastCondition) {
89+
$this->constantConditionInTraitHelper->emitNoError(self::class, $scope, $node);
8190
return [];
8291
}
8392

@@ -93,7 +102,13 @@ public function processNode(Node $node, Scope $scope): array
93102

94103
$errorBuilder->identifier(sprintf('%s.alwaysTrue', $node instanceof Node\Expr\BinaryOp\Equal ? 'equal' : 'notEqual'));
95104

96-
return [$errorBuilder->build()];
105+
$ruleError = $errorBuilder->build();
106+
if ($scope->isInTrait()) {
107+
$this->constantConditionInTraitHelper->emitError(self::class, $scope, $node, true, $ruleError);
108+
return [];
109+
}
110+
111+
return [$ruleError];
97112
}
98113

99114
}

0 commit comments

Comments
 (0)