Skip to content

Commit

Permalink
Merge pull request #13 from nextcloud-libraries/feat/add-rule-for-oc-…
Browse files Browse the repository at this point in the history
…legacy-getters

Add rule for OC legacy getters
  • Loading branch information
come-nc authored Sep 18, 2024
2 parents f88640d + ac5c03a commit 41f383d
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 0 deletions.
99 changes: 99 additions & 0 deletions src/Rector/LegacyGetterToOcpServerGetRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

/*
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace Nextcloud\Rector\Rector;

use InvalidArgumentException;
use Nextcloud\Rector\ValueObject\LegacyGetterToOcpServerGet;
use PHPStan\Type\ObjectType;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

final class LegacyGetterToOcpServerGetRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var LegacyGetterToOcpServerGet[]
*/
private array $legacyGetterToOcpServerGet = [];

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Replace legacy getter calls on \OC::$server to desired static call on \OCP\Server',
[
new ConfiguredCodeSample(<<<'CODE_SAMPLE'
\OC::$server->getLogger()->debug('debug log');
CODE_SAMPLE
, <<<'CODE_SAMPLE'
\OCP::Server::get(\Psr\Log\LoggerInterface::class)->debug('debug log');
CODE_SAMPLE
, [new LegacyGetterToOcpServerGet('getLogger', '\Psr\Log\LoggerInterface')]),
],
);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}

public function refactor(Node $node): ?Node
{
if (!($node instanceof MethodCall)) {
return null;
}
foreach ($this->legacyGetterToOcpServerGet as $config) {
if (!$node->var instanceof StaticPropertyFetch) {
continue;
}
if (!$this->isName($node->var->name, 'server')) {
continue;
}
if (!$this->isName($node->name, $config->getOldMethod())) {
continue;
}
if (!$this->isObjectType($node->var->class, new ObjectType('OC'))) {
continue;
}

return $this->nodeFactory->createStaticCall(
'OCP\Server',
'get',
[$this->nodeFactory->createClassConstReference($config->getNewClass())],
);
}

return null;
}

/**
* @param mixed[] $configuration
*/
public function configure(array $configuration): void
{
foreach ($configuration as $config) {
if (!$config instanceof LegacyGetterToOcpServerGet) {
throw new InvalidArgumentException('Only supports LegacyGetterToOcpServerGet configurations');
}
}
/**
* @psalm-suppress MixedPropertyTypeCoercion
* @phpstan-ignore assign.propertyType
*/
$this->legacyGetterToOcpServerGet = $configuration;
}
}
33 changes: 33 additions & 0 deletions src/ValueObject/LegacyGetterToOcpServerGet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

/*
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace Nextcloud\Rector\ValueObject;

use Rector\Validation\RectorAssert;

final class LegacyGetterToOcpServerGet
{
public function __construct(
private string $oldMethod,
private string $newClass,
) {
RectorAssert::className($oldMethod);
RectorAssert::className($newClass);
}

public function getOldMethod(): string
{
return $this->oldMethod;
}

public function getNewClass(): string
{
return $this->newClass;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Nextcloud\Rector\Test\Rector\OcServerToOcpServerRector\Fixture;

use OC;

class SomeClass
{
public function foo()
{
$request1 = OC::$server->getRequest();
$request2 = \OC::$server->getRequest();
}
}

?>
-----
<?php

namespace Nextcloud\Rector\Test\Rector\OcServerToOcpServerRector\Fixture;

use OC;

class SomeClass
{
public function foo()
{
$request1 = \OCP\Server::get(\OCP\IRequest::class);
$request2 = \OCP\Server::get(\OCP\IRequest::class);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Nextcloud\Rector\Test\Rector\LegacyGetterToOcpServerGetRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class LegacyGetterToOcpServerGetRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/config.php';
}
}
17 changes: 17 additions & 0 deletions tests/Rector/LegacyGetterToOcpServerGetRector/config/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use Nextcloud\Rector\Rector\LegacyGetterToOcpServerGetRector;
use Nextcloud\Rector\ValueObject\LegacyGetterToOcpServerGet;
use OCP\IRequest;
use Rector\Config\RectorConfig;

return RectorConfig::configure()
->withConfiguredRule(
LegacyGetterToOcpServerGetRector::class,
[
/** @phpstan-ignore class.notFound */
new LegacyGetterToOcpServerGet('getRequest', IRequest::class),
],
);

0 comments on commit 41f383d

Please sign in to comment.