![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/phpmd/phpmd/src/main/php/PHPMD/Rule/CleanCode/ |
<?php /** * This file is part of PHP Mess Detector. * * Copyright (c) Manuel Pichler <[email protected]>. * All rights reserved. * * Licensed under BSD License * For full copyright and license information, please see the LICENSE file. * Redistributions of files must retain the above copyright notice. * * @author Manuel Pichler <[email protected]> * @copyright Manuel Pichler. All rights reserved. * @license https://opensource.org/licenses/bsd-license.php BSD License * @link http://phpmd.org/ */ namespace PHPMD\Rule\CleanCode; use PDepend\Source\AST\ASTArray; use PDepend\Source\AST\ASTClass; use PDepend\Source\AST\ASTPropertyPostfix; use PDepend\Source\AST\ASTUnaryExpression; use PDepend\Source\AST\ASTVariable; use PDepend\Source\AST\ASTVariableDeclarator; use PDepend\Source\AST\State; use PHPMD\AbstractNode; use PHPMD\Node\AbstractCallableNode; use PHPMD\Node\ASTNode; use PHPMD\Node\MethodNode; use PHPMD\Rule\AbstractLocalVariable; use PHPMD\Rule\FunctionAware; use PHPMD\Rule\MethodAware; /** * This rule collects all undefined variables within a given function or method * that are used by any code in the analyzed source artifact. */ class UndefinedVariable extends AbstractLocalVariable implements FunctionAware, MethodAware { /** * Found variable images within a single method or function. * * @var array(string) */ protected $images = array(); /** * This method checks that all local variables within the given function or * method are used at least one time. * * @param \PHPMD\AbstractNode $node * @return void */ public function apply(AbstractNode $node) { $this->images = array(); if ($node instanceof MethodNode) { $this->collectProperties($this->getNode($node->getNode()->getParent())); } $this->collect($node); foreach ($node->findChildrenOfType('Class') as $class) { /** @var ASTClass $class */ $this->collectProperties($class); foreach ($class->getMethods() as $method) { $this->collect(new MethodNode($method)); } } foreach ($node->findChildrenOfTypeVariable() as $variable) { if ($this->isSuperGlobal($variable) || $this->isPassedByReference($variable)) { $this->addVariableDefinition($variable); } elseif (!$this->checkVariableDefined($variable, $node)) { $this->addViolation($variable, array($this->getVariableImage($variable))); } } } /** * Collect variables defined inside a PHPMD entry node (such as MethodNode). * * @param AbstractNode $node */ protected function collect(AbstractNode $node) { $this->collectPropertyPostfix($node); $this->collectClosureParameters($node); $this->collectForeachStatements($node); $this->collectListExpressions($node); $this->collectAssignments($node); $this->collectParameters($node); $this->collectExceptionCatches($node); $this->collectGlobalStatements($node); } protected function collectProperties($node) { if (!($node instanceof ASTClass)) { return; } foreach ($node->getProperties() as $property) { if ($property->isStatic()) { $this->images['::'.$property->getName()] = $property; } } } /** * Stores the given literal node in an global of found variables. * * @param \PHPMD\Node\AbstractNode $node * @return void */ protected function collectGlobalStatements(AbstractNode $node) { foreach ($node->findChildrenWithParentType('GlobalStatement') as $variable) { $this->addVariableDefinition($variable); } } /** * Stores the given literal node in an catch of found variables. * * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ protected function collectExceptionCatches(AbstractCallableNode $node) { foreach ($node->findChildrenWithParentType('CatchStatement') as $child) { if ($child instanceof ASTVariable) { $this->addVariableDefinition($child); } } } /** * Stores the given literal node in an internal list of found variables. * * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ protected function collectListExpressions(AbstractCallableNode $node) { foreach ($node->findChildrenWithParentType('ListExpression') as $variable) { $this->addVariableDefinition($variable); } } /** * Stores the given literal node in an internal foreach of found variables. * * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ protected function collectForeachStatements(AbstractCallableNode $node) { foreach ($node->findChildrenWithParentType('ForeachStatement') as $child) { if ($child instanceof ASTVariable) { $this->addVariableDefinition($child); } if (!($child instanceof ASTUnaryExpression)) { continue; } foreach ($child->getChildren() as $refChildren) { if ($refChildren instanceof ASTVariable) { $this->addVariableDefinition($refChildren); } } } } /** * Stores the given literal node in an internal closure of found variables. * * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ protected function collectClosureParameters(AbstractCallableNode $node) { $closures = $node->findChildrenOfType('Closure'); foreach ($closures as $closure) { $this->collectParameters($closure); } } /** * Check if the given variable was defined in the current context before usage. * * @param \PHPMD\Node\ASTNode $variable * @param \PHPMD\Node\AbstractCallableNode $parentNode * @return bool */ protected function checkVariableDefined(ASTNode $variable, AbstractCallableNode $parentNode) { $image = $this->getVariableImage($variable); return isset($this->images[$image]) || $this->isNameAllowedInContext($parentNode, $variable); } /** * Collect parameter names of method/function. * * @param \PHPMD\Node\AbstractNode $node * @return void */ protected function collectParameters(AbstractNode $node) { // Get formal parameter container $parameters = $node->getFirstChildOfType('FormalParameters'); // Now get all declarators in the formal parameters container $declarators = $parameters->findChildrenOfType('VariableDeclarator'); foreach ($declarators as $declarator) { $this->addVariableDefinition($declarator); } } /** * Collect assignments of variables. * * @param \PHPMD\Node\AbstractCallableNode $node * @return void */ protected function collectAssignments(AbstractCallableNode $node) { foreach ($node->findChildrenOfType('AssignmentExpression') as $assignment) { $variable = $assignment->getChild(0); if ($variable->getNode() instanceof ASTArray) { foreach ($variable->findChildrenOfTypeVariable() as $unpackedVariable) { $this->addVariableDefinition($unpackedVariable); } continue; } $this->addVariableDefinition($variable); } foreach ($node->findChildrenOfType('StaticVariableDeclaration') as $static) { $variable = $static->getChild(0); $this->addVariableDefinition($variable); } } /** * Collect postfix property. * * @param \PHPMD\Node\AbstractNode $node * @return void */ protected function collectPropertyPostfix(AbstractNode $node) { foreach ($node->findChildrenWithParentType('PropertyPostfix') as $child) { if ($child instanceof ASTVariable) { $this->addVariableDefinition($child); } } } /** * Add the variable to images. * * @param ASTVariable|ASTPropertyPostfix|ASTVariableDeclarator $variable * @return void */ protected function addVariableDefinition($variable) { $image = $this->getVariableImage($variable); if (!isset($this->images[$image])) { $this->images[$image] = $variable; } } /** * Checks if a short name is acceptable in the current context. * * @param \PHPMD\Node\AbstractCallableNode $node * @param \PHPMD\Node\ASTNode $variable * * @return boolean */ protected function isNameAllowedInContext(AbstractCallableNode $node, ASTNode $variable) { return ( $node instanceof MethodNode && $variable->getImage() === '$this' && ($node->getModifiers() & State::IS_STATIC) === 0 ); } }