-
Notifications
You must be signed in to change notification settings - Fork 461
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bleeding edge - NoopRule - take advantage of impure points
- Loading branch information
1 parent
d7579c4
commit a647052
Showing
13 changed files
with
360 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Node; | ||
|
||
use PhpParser\Node\Expr; | ||
use PhpParser\NodeAbstract; | ||
|
||
class NoopExpressionNode extends NodeAbstract implements VirtualNode | ||
{ | ||
|
||
public function __construct(private Expr $originalExpr) | ||
{ | ||
parent::__construct($this->originalExpr->getAttributes()); | ||
} | ||
|
||
public function getOriginalExpr(): Expr | ||
{ | ||
return $this->originalExpr; | ||
} | ||
|
||
public function getType(): string | ||
{ | ||
return 'PHPStan_Node_NoopExpressionNode'; | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
public function getSubNodeNames(): array | ||
{ | ||
return []; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\DeadCode; | ||
|
||
use PhpParser\Node; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Node\NoopExpressionNode; | ||
use PHPStan\Node\Printer\ExprPrinter; | ||
use PHPStan\Rules\Rule; | ||
use PHPStan\Rules\RuleErrorBuilder; | ||
use function sprintf; | ||
|
||
/** | ||
* @implements Rule<NoopExpressionNode> | ||
*/ | ||
class BetterNoopRule implements Rule | ||
{ | ||
|
||
public function __construct(private ExprPrinter $exprPrinter) | ||
{ | ||
} | ||
|
||
public function getNodeType(): string | ||
{ | ||
return NoopExpressionNode::class; | ||
} | ||
|
||
public function processNode(Node $node, Scope $scope): array | ||
{ | ||
$expr = $node->getOriginalExpr(); | ||
if ($expr instanceof Node\Expr\BinaryOp\LogicalXor) { | ||
return [ | ||
RuleErrorBuilder::message( | ||
'Unused result of "xor" operator.', | ||
)->line($expr->getStartLine()) | ||
->tip('This operator has unexpected precedence, try disambiguating the logic with parentheses ().') | ||
->identifier('logicalXor.resultUnused') | ||
->build(), | ||
]; | ||
} | ||
if ($expr instanceof Node\Expr\BinaryOp\LogicalAnd || $expr instanceof Node\Expr\BinaryOp\LogicalOr) { | ||
$identifierType = $expr instanceof Node\Expr\BinaryOp\LogicalAnd ? 'logicalAnd' : 'logicalOr'; | ||
|
||
return [ | ||
RuleErrorBuilder::message(sprintf( | ||
'Unused result of "%s" operator.', | ||
$expr->getOperatorSigil(), | ||
))->line($expr->getStartLine()) | ||
->tip('This operator has unexpected precedence, try disambiguating the logic with parentheses ().') | ||
->identifier(sprintf('%s.resultUnused', $identifierType)) | ||
->build(), | ||
]; | ||
} | ||
|
||
if ($expr instanceof Node\Expr\BinaryOp\BooleanAnd || $expr instanceof Node\Expr\BinaryOp\BooleanOr) { | ||
$identifierType = $expr instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'booleanOr'; | ||
|
||
return [ | ||
RuleErrorBuilder::message(sprintf( | ||
'Unused result of "%s" operator.', | ||
$expr->getOperatorSigil(), | ||
))->line($expr->getStartLine()) | ||
->identifier(sprintf('%s.resultUnused', $identifierType)) | ||
->build(), | ||
]; | ||
} | ||
|
||
if ($expr instanceof Node\Expr\Ternary) { | ||
return [ | ||
RuleErrorBuilder::message('Unused result of ternary operator.') | ||
->line($expr->getStartLine()) | ||
->identifier('ternary.resultUnused') | ||
->build(), | ||
]; | ||
} | ||
|
||
if ( | ||
$expr instanceof Node\Expr\FuncCall | ||
|| $expr instanceof Node\Expr\NullsafeMethodCall | ||
|| $expr instanceof Node\Expr\MethodCall | ||
|| $expr instanceof Node\Expr\New_ | ||
|| $expr instanceof Node\Expr\StaticCall | ||
) { | ||
// handled by *WithoutSideEffectsRule rules | ||
return []; | ||
} | ||
|
||
if ( | ||
$expr instanceof Node\Expr\Assign | ||
|| $expr instanceof Node\Expr\AssignOp | ||
|| $expr instanceof Node\Expr\AssignRef | ||
) { | ||
return []; | ||
} | ||
|
||
if ($expr instanceof Node\Expr\Closure) { | ||
return []; | ||
} | ||
|
||
return [ | ||
RuleErrorBuilder::message(sprintf( | ||
'Expression "%s" on a separate line does not do anything.', | ||
$this->exprPrinter->printExpr($expr), | ||
))->line($expr->getStartLine()) | ||
->identifier('expr.resultUnused') | ||
->build(), | ||
]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.