![]() 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/Design/ |
<?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\Design; use PDepend\Source\AST\AbstractASTNode; use PHPMD\AbstractNode; use PHPMD\AbstractRule; use PHPMD\Node\ASTNode; use PHPMD\Node\ClassNode; use PHPMD\Node\EnumNode; use PHPMD\Node\TraitNode; use PHPMD\Rule\ClassAware; use PHPMD\Rule\EnumAware; use PHPMD\Rule\TraitAware; /** * Count In Loop Expression Rule * * Performs a scan to check if loops use * count() or sizeof() in expressions. * * Checks for: * - for() loops * - while() loops * - do-while() loops * * @author Kamil Szymanski <[email protected]> */ class CountInLoopExpression extends AbstractRule implements ClassAware, TraitAware, EnumAware { /** * List of functions to search against * * @var array */ protected $unwantedFunctions = array('count', 'sizeof'); /** * List of already processed functions * * @var array */ protected $processedFunctions = array(); /** * Functions in classes tends to be name-spaced * * @var string */ protected $currentNamespace = ''; /** * Gets a list of loops in a node and iterates over them * * @param AbstractNode $node * @return void */ public function apply(AbstractNode $node) { if ($node instanceof ClassNode || $node instanceof TraitNode || $node instanceof EnumNode) { return $this->applyOnClassMethods($node); } $this->currentNamespace = $node->getNamespaceName() . '\\'; $loops = array_merge( $node->findChildrenOfType('ForStatement'), $node->findChildrenOfType('WhileStatement'), $node->findChildrenOfType('DoWhileStatement') ); /** @var AbstractNode $loop */ foreach ($loops as $loop) { $this->findViolations($loop); } } /** * Scans for expressions and count() or sizeof() functions inside, * if found, triggers a violation * * @param AbstractNode $loop Loop statement to look against */ protected function findViolations(AbstractNode $loop) { foreach ($loop->findChildrenOfType('Expression') as $expression) { if ($this->isDirectChild($loop, $expression)) { continue; } foreach ($expression->findChildrenOfType('FunctionPostfix') as $function) { if (!$this->isUnwantedFunction($function)) { continue; } $hash = $this->getHash($function->getNode()); if (isset($this->processedFunctions[$hash])) { continue; } $this->addViolation($loop, array($function->getImage(), $loop->getImage())); $this->processedFunctions[$hash] = true; } } } /** * Checks whether node in a direct child of the loop * * @param AbstractNode $loop * @param ASTNode $expression * @return bool */ protected function isDirectChild(AbstractNode $loop, ASTNode $expression) { return $this->getHash($expression->getParent()->getNode()) !== $this->getHash($loop->getNode()); } /** * Generates an unique hash for a given node * * PDepend method getChildrenOfType() iterates trough all children of a node. * As one function may be found more than once, we use a hash (which in reality * is a clone of the node's metadata) to check, if a given node hasn't * already been processed. * * Example hash: * 22:22:10:15:PHPMD\count * * @param AbstractASTNode $node * @return string */ protected function getHash(AbstractASTNode $node) { return sprintf( '%s:%s:%s:%s:%s', $node->getStartLine(), $node->getEndLine(), $node->getStartColumn(), $node->getEndColumn(), $node->getImage() ); } /** * Checks the given function against the list of unwanted functions * * @param ASTNode $function * @return bool */ protected function isUnwantedFunction(ASTNode $function) { $functionName = str_replace($this->currentNamespace, '', $function->getImage()); return in_array($functionName, $this->unwantedFunctions); } }