File manager - Edit - /var/www/payraty/helpdesk/vendor/rector/rector/vendor/rector/rector-nette/src/NodeAnalyzer/TemplatePropertyAssignCollector.php
Back
<?php declare (strict_types=1); namespace Rector\Nette\NodeAnalyzer; use PhpParser\Node; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Match_; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; use PhpParser\Node\Stmt\Case_; use PhpParser\Node\Stmt\Catch_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Do_; use PhpParser\Node\Stmt\Else_; use PhpParser\Node\Stmt\Foreach_; use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\Return_; use PhpParser\Node\Stmt\Switch_; use PhpParser\Node\Stmt\While_; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Node\BetterNodeFinder; use Rector\Nette\ValueObject\AlwaysTemplateParameterAssign; use Rector\Nette\ValueObject\ParameterAssign; use Rector\Nette\ValueObject\TemplateParametersAssigns; use Rector\NodeNestingScope\ScopeNestingComparator; final class TemplatePropertyAssignCollector { /** * @var array<class-string<Node>> */ private const NODE_TYPES = [ // these situations happens only if condition is met If_::class, While_::class, Do_::class, Catch_::class, Case_::class, Match_::class, Switch_::class, Foreach_::class, // FunctionLike must be last, so we know the variable is defined in main stmt FunctionLike::class, ]; /** * @var \PhpParser\Node\Stmt\Return_|null */ private $lastReturn; /** * @var AlwaysTemplateParameterAssign[] */ private $alwaysTemplateParameterAssigns = []; /** * @var AlwaysTemplateParameterAssign[] */ private $defaultChangeableTemplateParameterAssigns = []; /** * @var ParameterAssign[] */ private $conditionalTemplateParameterAssigns = []; /** * @readonly * @var \Rector\NodeNestingScope\ScopeNestingComparator */ private $scopeNestingComparator; /** * @readonly * @var \Rector\Core\PhpParser\Node\BetterNodeFinder */ private $betterNodeFinder; /** * @readonly * @var \Rector\Nette\NodeAnalyzer\ThisTemplatePropertyFetchAnalyzer */ private $thisTemplatePropertyFetchAnalyzer; /** * @readonly * @var \Rector\Nette\NodeAnalyzer\ReturnAnalyzer */ private $returnAnalyzer; public function __construct(ScopeNestingComparator $scopeNestingComparator, BetterNodeFinder $betterNodeFinder, \Rector\Nette\NodeAnalyzer\ThisTemplatePropertyFetchAnalyzer $thisTemplatePropertyFetchAnalyzer, \Rector\Nette\NodeAnalyzer\ReturnAnalyzer $returnAnalyzer) { $this->scopeNestingComparator = $scopeNestingComparator; $this->betterNodeFinder = $betterNodeFinder; $this->thisTemplatePropertyFetchAnalyzer = $thisTemplatePropertyFetchAnalyzer; $this->returnAnalyzer = $returnAnalyzer; } public function collect(ClassMethod $classMethod) : TemplateParametersAssigns { $this->alwaysTemplateParameterAssigns = []; $this->conditionalTemplateParameterAssigns = []; $this->defaultChangeableTemplateParameterAssigns = []; $this->lastReturn = $this->returnAnalyzer->findLastClassMethodReturn($classMethod); $assignsOfPropertyFetches = $this->findAssignToPropertyFetches($classMethod); $this->collectVariableFromAssign($assignsOfPropertyFetches); return new TemplateParametersAssigns($this->alwaysTemplateParameterAssigns, $this->conditionalTemplateParameterAssigns, $this->defaultChangeableTemplateParameterAssigns); } /** * @return Node[] */ private function getFoundParents(PropertyFetch $propertyFetch) : array { $foundParents = []; /** @var class-string<Node> $nodeType */ foreach (self::NODE_TYPES as $nodeType) { $parentType = $this->betterNodeFinder->findParentType($propertyFetch->var, $nodeType); if ($parentType instanceof Node) { $foundParents[] = $parentType; $parentParentType = $this->betterNodeFinder->findParentType($parentType, $nodeType); if ($parentParentType instanceof Node) { $foundParents[] = $parentParentType; } } } return $foundParents; } /** * @param Assign[] $assigns */ private function collectVariableFromAssign(array $assigns) : void { if ($assigns === []) { return; } $fistAssign = $assigns[0]; /** @var PropertyFetch $propertyFetch */ $propertyFetch = $fistAssign->var; $foundParents = $this->getFoundParents($propertyFetch); $isDefaultValueDefined = $this->isDefaultValueDefined($foundParents); foreach ($assigns as $assign) { $this->processAssign($assign, $isDefaultValueDefined); } } /** * @param Node[] $nodes */ private function isDefaultValueDefined(array $nodes) : bool { if (!isset($nodes[0])) { return \false; } return $nodes[0] instanceof ClassMethod; } private function processAssign(Assign $assign, bool $isDefaultValueDefined) : void { $parameterName = $this->thisTemplatePropertyFetchAnalyzer->resolveTemplateParameterNameFromAssign($assign); if ($parameterName === null) { return; } $propertyFetch = $assign->var; if (!$propertyFetch instanceof PropertyFetch) { throw new ShouldNotHappenException(); } $foundParents = $this->getFoundParents($propertyFetch); // nested conditions, unreliable, might not be defined if (\count($foundParents) >= 3) { return; } foreach ($foundParents as $foundParent) { if ($this->scopeNestingComparator->isInBothIfElseBranch($foundParent, $propertyFetch)) { $this->conditionalTemplateParameterAssigns[] = new ParameterAssign($assign, $parameterName); return; } if ($foundParent instanceof If_) { if ($isDefaultValueDefined) { $this->defaultChangeableTemplateParameterAssigns[] = new AlwaysTemplateParameterAssign($assign, $parameterName, new Variable($parameterName)); // remove it from always template variables foreach ($this->alwaysTemplateParameterAssigns as $key => $alwaysTemplateParameterAssigns) { if ($alwaysTemplateParameterAssigns->getParameterName() === $parameterName) { unset($this->alwaysTemplateParameterAssigns[$key]); } } } return; } // only defined in else branch, nothing we can do if ($foundParent instanceof Else_) { return; } } // there is a return before this assign, to do not remove it and keep ti if (!$this->returnAnalyzer->isBeforeLastReturn($assign, $this->lastReturn)) { return; } $this->alwaysTemplateParameterAssigns[] = new AlwaysTemplateParameterAssign($assign, $parameterName, $assign->expr); } /** * @return Assign[] */ private function findAssignToPropertyFetches(ClassMethod $classMethod) : array { /** @var Assign[] $assigns */ $assigns = $this->betterNodeFinder->findInstanceOf((array) $classMethod->stmts, Assign::class); $assignsOfPropertyFetches = []; foreach ($assigns as $assign) { if (!$assign->var instanceof PropertyFetch) { continue; } $assignsOfPropertyFetches[] = $assign; } // re-index from 0 return \array_values($assignsOfPropertyFetches); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings