Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tv misc #49

Merged
merged 3 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 6 additions & 20 deletions src/Command/PrivatizeConstantsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@

use Nette\Utils\FileSystem;
use Nette\Utils\Strings;
use PhpParser\NodeTraverser;
use Rector\SwissKnife\Contract\ClassConstantFetchInterface;
use Rector\SwissKnife\Finder\PhpFilesFinder;
use Rector\SwissKnife\PhpParser\CachedPhpParser;
use Rector\SwissKnife\PhpParser\ClassConstantFetchFinder;
use Rector\SwissKnife\PhpParser\NodeTraverserFactory;
use Rector\SwissKnife\PhpParser\NodeVisitor\FindNonPrivateClassConstNodeVisitor;
use Rector\SwissKnife\PhpParser\Finder\ClassConstantFetchFinder;
use Rector\SwissKnife\PhpParser\Finder\ClassConstFinder;
use Rector\SwissKnife\ValueObject\ClassConstant;
use Rector\SwissKnife\ValueObject\ClassConstantFetch\CurrentClassConstantFetch;
use Symfony\Component\Console\Command\Command;
Expand All @@ -27,8 +24,8 @@ final class PrivatizeConstantsCommand extends Command
{
public function __construct(
private readonly SymfonyStyle $symfonyStyle,
private readonly CachedPhpParser $cachedPhpParser,
private readonly ClassConstantFetchFinder $classConstantFetchFinder,
private readonly ClassConstFinder $classConstFinder,
) {
parent::__construct();
}
Expand Down Expand Up @@ -87,28 +84,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::SUCCESS;
}

private function parseAndTraverseFile(SplFileInfo $phpFileInfo, NodeTraverser $nodeTraverser): void
{
$fileStmts = $this->cachedPhpParser->parseFile($phpFileInfo->getRealPath());
$nodeTraverser->traverse($fileStmts);
}

/**
* @param ClassConstantFetchInterface[] $classConstantFetches
*/
private function processFileInfo(SplFileInfo $phpFileInfo, array $classConstantFetches): void
{
$findNonPrivateClassConstNodeVisitor = new FindNonPrivateClassConstNodeVisitor();
$nodeTraverser = NodeTraverserFactory::create($findNonPrivateClassConstNodeVisitor);

$this->parseAndTraverseFile($phpFileInfo, $nodeTraverser);

// nothing found
if ($findNonPrivateClassConstNodeVisitor->getClassConstants() === []) {
$classConstants = $this->classConstFinder->find($phpFileInfo->getRealPath());
if ($classConstants === []) {
return;
}

foreach ($findNonPrivateClassConstNodeVisitor->getClassConstants() as $classConstant) {
foreach ($classConstants as $classConstant) {
if ($this->isClassConstantUsedPublicly($classConstantFetches, $classConstant)) {
$changedFileContents = Strings::replace(
$phpFileInfo->getContents(),
Expand Down
35 changes: 35 additions & 0 deletions src/PhpParser/Finder/ClassConstFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\PhpParser\Finder;

use Rector\SwissKnife\PhpParser\CachedPhpParser;
use Rector\SwissKnife\PhpParser\NodeTraverserFactory;
use Rector\SwissKnife\PhpParser\NodeVisitor\FindNonPrivateClassConstNodeVisitor;
use Rector\SwissKnife\ValueObject\ClassConstant;

/**
* @see \Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstFinder\ClassConstFinderTest
*/
final class ClassConstFinder
{
public function __construct(
private CachedPhpParser $cachedPhpParser
) {
}

/**
* @return ClassConstant[]
*/
public function find(string $filePath): array
{
$findNonPrivateClassConstNodeVisitor = new FindNonPrivateClassConstNodeVisitor();
$nodeTraverser = NodeTraverserFactory::create($findNonPrivateClassConstNodeVisitor);

$fileStmts = $this->cachedPhpParser->parseFile($filePath);
$nodeTraverser->traverse($fileStmts);

return $findNonPrivateClassConstNodeVisitor->getClassConstants();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

declare(strict_types=1);

namespace Rector\SwissKnife\PhpParser;
namespace Rector\SwissKnife\PhpParser\Finder;

use Rector\SwissKnife\Contract\ClassConstantFetchInterface;
use Rector\SwissKnife\Exception\NotImplementedYetException;
use Rector\SwissKnife\Exception\ShouldNotHappenException;
use Rector\SwissKnife\PhpParser\CachedPhpParser;
use Rector\SwissKnife\PhpParser\NodeTraverserFactory;
use Rector\SwissKnife\PhpParser\NodeVisitor\FindClassConstFetchNodeVisitor;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Style\SymfonyStyle;
Expand Down
25 changes: 23 additions & 2 deletions src/PhpParser/NodeVisitor/FindNonPrivateClassConstNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\NodeVisitorAbstract;
use Rector\SwissKnife\ValueObject\ClassConstant;
use ReflectionClass;
use Webmozart\Assert\Assert;

final class FindNonPrivateClassConstNodeVisitor extends NodeVisitorAbstract
Expand All @@ -24,14 +25,13 @@ public function enterNode(Node $node): ?Node
return null;
}

if ($node->isAnonymous()) {
if ($node->isAnonymous() || $node->isAbstract()) {
return null;
}

Assert::isInstanceOf($node->namespacedName, Name::class);

$className = $node->namespacedName->toString();

foreach ($node->getConstants() as $classConst) {
foreach ($classConst->consts as $constConst) {
$constantName = $constConst->name->toString();
Expand All @@ -41,6 +41,10 @@ public function enterNode(Node $node): ?Node
continue;
}

if ($this->isConstantDefinedInParentClassAlso($node, $constantName)) {
continue;
}

$this->classConstants[] = new ClassConstant($className, $constantName, $classConst->getLine());
}
}
Expand All @@ -55,4 +59,21 @@ public function getClassConstants(): array
{
return $this->classConstants;
}

private function isConstantDefinedInParentClassAlso(Class_ $class, string $constantName): bool
{
if (! $class->extends instanceof Node) {
return false;
}

$parentClassName = $class->extends->toString();
if (! class_exists($parentClassName)) {
return false;
}

$parentReflectionClass = new ReflectionClass($parentClassName);
$parentClassConstantNames = array_keys($parentReflectionClass->getConstants());

return in_array($constantName, $parentClassConstantNames);
}
}
34 changes: 34 additions & 0 deletions tests/PhpParser/Finder/ClassConstFinder/ClassConstFinderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstFinder;

use Rector\SwissKnife\PhpParser\Finder\ClassConstFinder;
use Rector\SwissKnife\Tests\AbstractTestCase;

final class ClassConstFinderTest extends AbstractTestCase
{
private ClassConstFinder $classConstFinder;

protected function setUp(): void
{
parent::setUp();

$this->classConstFinder = $this->make(ClassConstFinder::class);
}

public function testSkipParentConstant(): void
{
$classConstants = $this->classConstFinder->find(__DIR__ . '/Fixture/SomeClassWithConstants.php');

$this->assertCount(1, $classConstants);
}

public function testSkipAbstract(): void
{
$classConstants = $this->classConstFinder->find(__DIR__ . '/Fixture/AbstractParentClass.php');

$this->assertCount(0, $classConstants);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstFinder\Fixture;

abstract class AbstractParentClass
{
public const NAME = 'some name';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstFinder\Fixture;

final class SomeClassWithConstants extends AbstractParentClass
{
public const NAME = 'som_value';

public const SOME_CONST = 'som_value';
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder;

use Rector\SwissKnife\Contract\ClassConstantFetchInterface;
use Rector\SwissKnife\Finder\PhpFilesFinder;
use Rector\SwissKnife\PhpParser\ClassConstantFetchFinder;
use Rector\SwissKnife\PhpParser\Finder\ClassConstantFetchFinder;
use Rector\SwissKnife\Tests\AbstractTestCase;
use Rector\SwissKnife\ValueObject\ClassConstantFetch\CurrentClassConstantFetch;
use Rector\SwissKnife\ValueObject\ClassConstantFetch\ExternalClassAccessConstantFetch;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder\Fixture\Skip;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder\Fixture\Skip;

enum SomeEnum
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder\Fixture\Skip;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder\Fixture\Skip;

interface SomeInterface
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder\Fixture\Skip;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder\Fixture\Skip;

trait SomeTrait
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder\Fixture\Standard;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder\Fixture\Standard;

final class AnotherClassWithConstant
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\PhpParser\ClassConstantFetchFinder\Fixture\Standard;
namespace Rector\SwissKnife\Tests\PhpParser\Finder\ClassConstantFetchFinder\Fixture\Standard;

final class SomeFileWithConstants
{
Expand Down
Loading