Skip to content

Commit

Permalink
Create Seeker utility to delegate AST finding
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed Feb 27, 2024
1 parent deade45 commit 609b314
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 47 deletions.
3 changes: 2 additions & 1 deletion src/main/php/PHPMD/AbstractNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ public function __call($name, array $args)
* Returns the parent of this node or <b>null</b> when no parent node
* exists.
*
* @return ASTNode
* @return ASTNode|null
*/
public function getParent()
{
$node = $this->node->getParent();

if ($node === null) {
return null;
}
Expand Down
34 changes: 7 additions & 27 deletions src/main/php/PHPMD/Rule/UnusedPrivateMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

namespace PHPMD\Rule;

use OutOfBoundsException;
use PDepend\Source\AST\AbstractASTCombinationType;
use PDepend\Source\AST\ASTClassOrInterfaceReference;
use PDepend\Source\AST\ASTType;
Expand All @@ -27,6 +26,7 @@
use PHPMD\Node\ClassNode;
use PHPMD\Node\MethodNode;
use PHPMD\Utility\LastVariableWriting;
use PHPMD\Utility\Seeker;
use SplObjectStorage;

/**
Expand Down Expand Up @@ -244,11 +244,7 @@ protected function calculateInstanceOfTheCurrentClass(ClassNode $class, ASTNode
return true;
}

$scope = $variable->getParent();

while ($scope && !$scope->isInstanceOf('Scope')) {
$scope = $scope->getParent();
}
$scope = Seeker::fromNode($variable)->getParentOfType('Scope');

if (!$scope) {
return false;
Expand All @@ -269,30 +265,27 @@ protected function calculateInstanceOfTheCurrentClass(ClassNode $class, ASTNode
return $this->canBeCurrentClassInstance($class, $lastWriting);
}

return $this->isWritingOfSelfType($class, $name, $lastWriting);
return ($lastWriting instanceof ASTNode)
&& $this->isWritingOfSelfType($class, $name, $lastWriting);
}

/**
* @param string $name
*
* @return bool
*/
protected function isWritingOfSelfType(ClassNode $class, $name, $lastWriting)
protected function isWritingOfSelfType(ClassNode $class, $name, ASTNode $lastWriting)
{
if (!($lastWriting instanceof ASTNode)) {
return false;
}

if ($lastWriting->isInstanceOf('CloneExpression')) {
$cloned = $this->getChildIfExist($lastWriting, 0);
$cloned = Seeker::fromNode($lastWriting)->getChildIfExist(0);

return $cloned
&& $cloned->isInstanceOf('Variable')
&& $this->isInstanceOfTheCurrentClass($class, $cloned);
}

if ($lastWriting->isInstanceOf('AllocationExpression')) {
$value = $this->getChildIfExist($lastWriting, 0);
$value = Seeker::fromNode($lastWriting)->getChildIfExist(0);

return $value
&& ($value->isInstanceOf('SelfReference') || $value->isInstanceOf('StaticReference'));
Expand Down Expand Up @@ -333,17 +326,4 @@ protected function representCurrentClassName(ClassNode $class, $name)
$class->getFullQualifiedName(),
), true);
}

private function getChildIfExist($parent, $index)
{
try {
if ($parent instanceof ASTNode) {
return $parent->getChild($index);
}
} catch (OutOfBoundsException $e) {
// fallback to null
}

return null;
}
}
22 changes: 3 additions & 19 deletions src/main/php/PHPMD/Utility/LastVariableWriting.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@

namespace PHPMD\Utility;

use InvalidArgumentException;
use OutOfBoundsException;
use PDepend\Source\AST\ASTFormalParameter;
use PDepend\Source\AST\ASTFormalParameters;
use PDepend\Source\AST\ASTType;
use PHPMD\Node\ASTNode;

/**
* Utility class to provide string checks and manipulations
* Utility class to find the last time a variable was written before an occurrence of it.
*/
final class LastVariableWriting
{
Expand Down Expand Up @@ -56,10 +54,10 @@ public function findInScope(ASTNode $scope)
$parent = $occurrence->getParent();

if ($parent->isInstanceOf('AssignmentExpression')) {
$assigned = $this->getChildIfExist($parent, 0);
$assigned = Seeker::fromNode($parent)->getChildIfExist(0);

if ($assigned && $assigned->getImage() === $name) {
$lastWriting = $this->getChildIfExist($parent, 1);
$lastWriting = Seeker::fromNode($parent)->getChildIfExist(1);
}
}
}
Expand All @@ -81,18 +79,4 @@ public function findInParameters(ASTFormalParameters $parameters)

return null;
}

/** @return ASTNode|null */
private function getChildIfExist($parent, $index)
{
try {
if ($parent instanceof ASTNode) {
return $parent->getChild($index);
}
} catch (OutOfBoundsException $e) {
// fallback to null
}

return null;
}
}
68 changes: 68 additions & 0 deletions src/main/php/PHPMD/Utility/Seeker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) Manuel Pichler <mapi@phpmd.org>.
* 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 <mapi@phpmd.org>
* @copyright Manuel Pichler. All rights reserved.
* @license https://opensource.org/licenses/bsd-license.php BSD License
* @link http://phpmd.org/
*/

namespace PHPMD\Utility;

use InvalidArgumentException;
use OutOfBoundsException;
use PDepend\Source\AST\ASTFormalParameter;
use PDepend\Source\AST\ASTFormalParameters;
use PDepend\Source\AST\ASTType;
use PHPMD\Node\ASTNode;

/**
* Utility class to do some more advanced searches from an ASTNode.
*/
final class Seeker
{
private $node;

private function __construct(ASTNode $node)
{
$this->node = $node;
}

/** @return self */
public static function fromNode(ASTNode $node)
{
return new self($node);
}

/** @return ASTNode|null */
public function getParentOfType($type)
{
$scope = $this->node->getParent();

while ($scope && !$scope->isInstanceOf($type)) {
$scope = $scope->getParent();
}

return $scope;
}

/** @return ASTNode|null */
public function getChildIfExist($index)
{
try {
return $this->node->getChild($index);
} catch (OutOfBoundsException $e) {
// fallback to null
}

return null;
}
}

0 comments on commit 609b314

Please sign in to comment.