![]() 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\AbstractASTNode; use PDepend\Source\AST\ASTLiteral; use PDepend\Source\AST\ASTNode as PDependASTNode; use PHPMD\AbstractNode; use PHPMD\AbstractRule; use PHPMD\Node\ASTNode; use PHPMD\Rule\FunctionAware; use PHPMD\Rule\MethodAware; /** * Duplicated Array Key Rule * * This rule detects duplicated array keys. * * @author RafaĆ Wrzeszcz <[email protected]> * @author Kamil Szymanaski <[email protected]> */ class DuplicatedArrayKey extends AbstractRule implements MethodAware, FunctionAware { /** * Retrieves all arrays from single node and performs comparison logic on it * * @param AbstractNode $node * @return void */ public function apply(AbstractNode $node) { foreach ($node->findChildrenOfType('Array') as $arrayNode) { /** @var ASTNode $arrayNode */ $this->checkForDuplicatedArrayKeys($arrayNode); } } /** * This method checks if a given function or method contains an array literal * with duplicated entries for any key and emits a rule violation if so. * * @param ASTNode $node Array node. * @return void */ protected function checkForDuplicatedArrayKeys(ASTNode $node) { $keys = array(); /** @var ASTArrayElement $arrayElement */ foreach ($node->getChildren() as $index => $arrayElement) { $arrayElement = $this->normalizeKey($arrayElement, $index); if (null === $arrayElement) { // skip everything that can't be resolved easily continue; } $key = $arrayElement->getImage(); if (isset($keys[$key])) { $this->addViolation($node, array($key, $arrayElement->getStartLine())); continue; } $keys[$key] = $arrayElement; } } /** * Changes key name to its string format. * * To compare keys, we have to cast them to string. * Non-associative keys have to use index as its key, * while boolean and nulls have to be casted respectively. * As current logic doesn't evaluate expressions nor constants, * statics, globals, etc. we simply skip them. * * @param AbstractASTNode $node Array key to evaluate. * @param int $index Fallback in case of non-associative arrays * @return AbstractASTNode Key name */ protected function normalizeKey(AbstractASTNode $node, $index) { $childCount = count($node->getChildren()); // Skip, if there is no array key, just an array value if ($childCount === 1) { return null; } // non-associative - key name equals to its index if ($childCount === 0) { $node->setImage((string)$index); return $node; } $node = $node->getChild(0); if (!($node instanceof ASTLiteral)) { // skip expressions, method calls, globals and constants return null; } $node->setImage($this->castStringFromLiteral($node)); return $node; } /** * Cleans string literals and casts boolean and null values as PHP engine does * * @param PDependASTNode $key * @return string */ protected function castStringFromLiteral(PDependASTNode $key) { $value = $key->getImage(); switch ($value) { case 'false': return '0'; case 'true': return '1'; case 'null': return ''; default: return trim($value, '\'""'); } } }