Created
September 21, 2021 05:59
-
-
Save nulpatrol/1eb05c7f785980de300d032e3bd05fa3 to your computer and use it in GitHub Desktop.
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
<?php | |
declare(strict_types=1); | |
namespace Rost\Rules; | |
use PhpParser\Node; | |
use PHPStan\Analyser\Scope; | |
use PHPStan\Rules\Rule; | |
class DetectCopyOnWrite implements Rule | |
{ | |
public function getNodeType(): string | |
{ | |
return Node\Expr\Assign::class; | |
} | |
public function processNode(Node $node, Scope $scope): array | |
{ | |
$messages = []; | |
/** @var Node\Expr\Assign $node */ | |
$assignAcceptor = $node->var; | |
if ($assignAcceptor instanceof Node\Expr\ArrayDimFetch) { | |
/** @var Node\Expr\Variable $variable */ | |
$variable = $assignAcceptor->var; | |
$currentFunctionParameters = $this->getCurrentFunctionParameters($scope); | |
if (in_array($variable->name, $currentFunctionParameters)) { | |
$messages[] = 'Function argument mutation found. It can cause memory problems, because of copy on write principle'; | |
} | |
} | |
return $messages; | |
} | |
private function getCurrentFunctionParameters(Scope $scope): array | |
{ | |
$parameters = []; | |
if ($scope->isInAnonymousFunction()) { | |
$functionParameters = $scope->getAnonymousFunctionReflection()->getParameters(); | |
foreach ($functionParameters as $parameter) { | |
$parameters[] = $parameter->getName(); | |
} | |
} else { | |
$functionVariants = $scope->getFunction()->getVariants(); | |
foreach ($functionVariants as $functionVariant) { | |
foreach ($functionVariant->getParameters() as $functionParameter) { | |
$parameters[] = $functionParameter->getName(); | |
} | |
} | |
} | |
return $parameters; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment