From 2cb90df5349bb906e463fabacf067ff5d622a3b8 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms Date: Thu, 12 Dec 2024 10:56:43 +0100 Subject: add rector and provide initial set of rectors for stud.ip 6.0 --- composer.json | 4 +- composer.lock | 71 ++++++++++++++++++++-- lib/Rectors/Studip-6.0-Set.php | 51 ++++++++++++++++ lib/Rectors/Studip60/RemoveFunctionCallRector.php | 43 +++++++++++++ lib/Rectors/Studip60/RemoveGetConfigRector.php | 59 ++++++++++++++++++ lib/Rectors/Studip60/RemoveIncludesRector.php | 60 ++++++++++++++++++ .../Studip60/RemoveSidebarMethodsRector.php | 61 +++++++++++++++++++ rector-test.php | 53 ++++++++++++++++ rector.php | 29 +++++++++ 9 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 lib/Rectors/Studip-6.0-Set.php create mode 100644 lib/Rectors/Studip60/RemoveFunctionCallRector.php create mode 100644 lib/Rectors/Studip60/RemoveGetConfigRector.php create mode 100644 lib/Rectors/Studip60/RemoveIncludesRector.php create mode 100644 lib/Rectors/Studip60/RemoveSidebarMethodsRector.php create mode 100644 rector-test.php create mode 100644 rector.php diff --git a/composer.json b/composer.json index d79607d..02322a1 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "Studip\\Cache\\": "lib/classes/cache/", "Studip\\Calendar\\": "lib/classes/calendar/", "Studip\\Forms\\": "lib/classes/forms/", + "Studip\\Rectors\\": "lib/Rectors/", "Studip\\": [ "lib/classes/", "lib/exceptions/", @@ -77,7 +78,8 @@ "symfony/var-dumper": "6.4.7", "maximebf/debugbar": "1.22.3", "codeception/specify": "^2.0", - "zorac/phpstan-php-di": "^1.0" + "zorac/phpstan-php-di": "^1.0", + "rector/rector": "2.0.9" }, "require": { "php": "^8.1", diff --git a/composer.lock b/composer.lock index 059497a..df20aec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2d334aeeaac9b0c0745b0936f7f82913", + "content-hash": "7c64c5e3fd7a6fceb0d4347b3f1fb3fb", "packages": [ { "name": "algo26-matthias/idna-convert", @@ -7414,16 +7414,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.0.2", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "6c98c7600fc717b2c78c11ef60040d5b1e359c82" + "reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6c98c7600fc717b2c78c11ef60040d5b1e359c82", - "reference": "6c98c7600fc717b2c78c11ef60040d5b1e359c82", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f99e18eb775dbaf6460c95fa0b65312da9c746a", + "reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a", "shasum": "" }, "require": { @@ -7468,7 +7468,7 @@ "type": "github" } ], - "time": "2024-11-17T14:17:00+00:00" + "time": "2025-02-10T08:25:21+00:00" }, { "name": "phpunit/php-code-coverage", @@ -7943,6 +7943,65 @@ "time": "2019-01-08T18:20:26+00:00" }, { + "name": "rector/rector", + "version": "2.0.9", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "4393230e478c0006795770fe74c223b5c64ed68c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/4393230e478c0006795770fe74c223b5c64ed68c", + "reference": "4393230e478c0006795770fe74c223b5c64ed68c", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "phpstan/phpstan": "^2.1.3" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/2.0.9" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2025-02-10T08:14:01+00:00" + }, + { "name": "sebastian/cli-parser", "version": "1.0.2", "source": { diff --git a/lib/Rectors/Studip-6.0-Set.php b/lib/Rectors/Studip-6.0-Set.php new file mode 100644 index 0000000..ca019b2 --- /dev/null +++ b/lib/Rectors/Studip-6.0-Set.php @@ -0,0 +1,51 @@ +withRules([ + Studip\Rectors\Studip60\RemoveGetConfigRector::class, + Studip\Rectors\Studip60\RemoveSidebarMethodsRector::class + ]) + ->withConfiguredRule(RenameFunctionRector::class, [ + 'studip_json_decode' => 'json_decode', + 'studip_json_encode' => 'json_encode', + ]) + ->withConfiguredRule(RemoveIncludesRector::class, [ + 'vendor/flexi', + 'vendor/trails', + 'app/controllers/authenticated_controller.php', + 'app/controllers/plugin_controller.php', + 'app/controllers/studip_controller.php', + 'app/controllers/studip_controller_properties_trait.php', + 'app/controllers/studip_response.php', + ]) + ->withConfiguredRule(RemoveFunctionCallRector::class, [ + 'smile', + 'transformBeforeSave', + ]) + ->withConfiguredRule(RenameClassRector::class, [ + 'Flexi_PhpTemplate' => 'Flexi\PhpTemplate', + 'Flexi_Template' => 'Flexi\Template', + 'Flexi_TemplateFactory' => 'Flexi\Factory', + + 'StudipCacheFactory' => 'Studip\Cache\Factory', + 'StudipCache' => 'Studip\Cache\Cache', + 'StudipDbCache' => 'Studip\Cache\DbCache', + + 'Trails_Controller' => 'Trails\Controller', + 'Trails_Dispatcher' => 'Trails\Dispatcher', + 'Trails_Exception' => 'Trails\Exception', + 'Trails_Flash' => 'Trails\Flash', + 'Trails_Inflector' => 'Trails\Inflector', + 'Trails_Response' => 'Trails\Response', + 'Trails_DoubleRenderError' => 'Trails\Exceptions\DoubleRenderError', + 'Trails_MissingFile' => 'Trails\Exceptions\MissingFile', + 'Trails_RoutingError' => 'Trails\Exceptions\RoutingError', + 'Trails_SessionRequired' => 'Trails\Exceptions\SessionRequiredException', + 'Trails_UnknownAction' => 'Trails\Exceptions\UnknownAction', + 'Trails_UnknownController' => 'Trails\Exceptions\UnknownController', + ]); diff --git a/lib/Rectors/Studip60/RemoveFunctionCallRector.php b/lib/Rectors/Studip60/RemoveFunctionCallRector.php new file mode 100644 index 0000000..1ee6180 --- /dev/null +++ b/lib/Rectors/Studip60/RemoveFunctionCallRector.php @@ -0,0 +1,43 @@ +isNames($node, $this->removes)) { + return null; + } + + if (!isset($node->args[0])) { + return null; + } + + return $node->args[0]->value; + } + + /** + * @param mixed[] $configuration + */ + public function configure(array $configuration): void + { + Assert::allString($configuration); + Assert::isList($configuration); + $this->removes = $configuration; + } +} diff --git a/lib/Rectors/Studip60/RemoveGetConfigRector.php b/lib/Rectors/Studip60/RemoveGetConfigRector.php new file mode 100644 index 0000000..da77a26 --- /dev/null +++ b/lib/Rectors/Studip60/RemoveGetConfigRector.php @@ -0,0 +1,59 @@ +valueResolver = $valueResolver; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Replace calls to function "get_config()" with calls to "Config::get()->getValue()', + [ + new CodeSample( + '$value = get_config(\'FOO_BAR\');', + '$value = Config::get()->getValue(\'FOO_BAR\');' + ) + ] + ); + } + + public function getNodeTypes(): array + { + return [FuncCall::class]; + } + + /** + * @param FuncCall $node + */ + public function refactor(Node $node) + { + if (!$this->isName($node->name, 'get_config')) { + return $node; + } + + return $this->nodeFactory->createMethodCall( + $this->nodeFactory->createStaticCall( + \Config::class, + 'get' + ), + 'getValue', + array_map( + fn($arg) => $this->valueResolver->getValue($arg), + $node->getArgs() + ) + ); + } +} diff --git a/lib/Rectors/Studip60/RemoveIncludesRector.php b/lib/Rectors/Studip60/RemoveIncludesRector.php new file mode 100644 index 0000000..8ba8f92 --- /dev/null +++ b/lib/Rectors/Studip60/RemoveIncludesRector.php @@ -0,0 +1,60 @@ +expr instanceof Include_) { + return null; + } + + if (!$this->matches($node->expr->expr)) { + return null; + } + + return self::REMOVE_NODE; + } + + /** + * @param mixed[] $configuration + */ + public function configure(array $configuration): void + { + Assert::allString($configuration); + Assert::isList($configuration); + $this->removeIncludes = $configuration; + } + + private function matches(String_ $expr): bool + { + foreach ($this->removeIncludes as $removeInclude) { + if (str_contains($expr->value, $removeInclude)) { + return true; + } + } + + return false; + } +} diff --git a/lib/Rectors/Studip60/RemoveSidebarMethodsRector.php b/lib/Rectors/Studip60/RemoveSidebarMethodsRector.php new file mode 100644 index 0000000..5225688 --- /dev/null +++ b/lib/Rectors/Studip60/RemoveSidebarMethodsRector.php @@ -0,0 +1,61 @@ +expr; + if (!$expr instanceof StaticCall) { + return null; + } + + if (!$this->isName($expr->class, 'Sidebar')) { + return null; + } + + $methodsToRemove = ['setImage', 'getImage', 'removeImage']; + if ($this->isNames($expr->name, $methodsToRemove)) { + return NodeVisitor::REMOVE_NODE; + } + + return null; + } +} diff --git a/rector-test.php b/rector-test.php new file mode 100644 index 0000000..046b79a --- /dev/null +++ b/rector-test.php @@ -0,0 +1,53 @@ +open('foo.php'); +if ($template instanceof Flexi_PhpTemplate) { + echo 'Template is php'; +} + +try { + $dispatcher = new Trails_Dispatcher('', '', ''); + $controller = new Trails_Controller($dispatcher); + $flash = new Trails_Flash(); + $inflector = new Trails_Inflector(); +} catch (Trails_DoubleRenderError $e) { + echo 'double render'; +} catch (Trails_MissingFile $e) { + echo 'missing file'; +} catch (Trails_RoutingError $e) { + echo 'routing error'; +} catch (Trails_SessionRequiredException $e) { + echo 'session required'; +} catch (Trails_UnknownAction $e) { + echo 'unknown action'; +} catch (Trails_UnknownController $e) { + echo 'unknown controller'; +} catch (Trails_Exception $e) { + echo 'some exception'; +} + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..4f02574 --- /dev/null +++ b/rector.php @@ -0,0 +1,29 @@ +withPaths([ + __DIR__ . '/app/controllers', + __DIR__ . '/cli', + __DIR__ . '/config', + __DIR__ . '/db', + __DIR__ . '/lib', + __DIR__ . '/public/*.php', + __DIR__ . '/tests', + ]) + ->withSkip([ + __DIR__ . '/tests/_data', + __DIR__ . '/tests/_support', + ]) + ->withSets([ + __DIR__ . '/lib/Rectors/Studip-6.0-Set.php' + ]) + // uncomment to reach your current PHP version + ->withPhpSets() +// ->withTypeCoverageLevel(0) +// ->withDeadCodeLevel(0) +// ->withCodeQualityLevel(0) +; -- cgit v1.0