From 93dffbea5678ba66d8517ac8a2e520a160181f0e Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Fri, 24 Apr 2020 14:00:49 +0200 Subject: [PATCH] [PHP 8.0] Add Stringable --- config/set/php/php80.yaml | 1 + docs/AllRectorsOverview.md | 23 ++++- .../Class_/StringableForToStringRector.php | 99 +++++++++++++++++++ .../Fixture/fixture.php.inc | 27 +++++ .../StringableForToStringRectorTest.php | 30 ++++++ 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 rules/php80/src/Rector/Class_/StringableForToStringRector.php create mode 100644 rules/php80/tests/Rector/Class_/StringableForToStringRector/Fixture/fixture.php.inc create mode 100644 rules/php80/tests/Rector/Class_/StringableForToStringRector/StringableForToStringRectorTest.php diff --git a/config/set/php/php80.yaml b/config/set/php/php80.yaml index 9c954f19c8f..48908e8f551 100644 --- a/config/set/php/php80.yaml +++ b/config/set/php/php80.yaml @@ -3,3 +3,4 @@ services: Rector\Php80\Rector\NotIdentical\StrContainsRector: null Rector\Php80\Rector\Identical\StrStartsWithRector: null Rector\Php80\Rector\Identical\StrEndsWithRector: null + Rector\Php80\Rector\Class_\StringableForToStringRector: null diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index 5abb5d6144c..38faff3a76c 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -1,4 +1,4 @@ -# All 501 Rectors Overview +# All 502 Rectors Overview - [Projects](#projects) - [General](#general) @@ -7915,6 +7915,27 @@ Change helper functions to str_starts_with()
+### `StringableForToStringRector` + +- class: [`Rector\Php80\Rector\Class_\StringableForToStringRector`](/../master/rules/php80/src/Rector/Class_/StringableForToStringRector.php) +- [test fixtures](/../master/rules/php80/tests/Rector/Class_/StringableForToStringRector/Fixture) + +Add `Stringable` interface to classes with `__toString()` method + +```diff +-class SomeClass ++class SomeClass implements Stringable + { +- public function __toString() ++ public function __toString(): string + { + return 'I can stringz'; + } + } +``` + +
+ ### `UnionTypesRector` - class: [`Rector\Php80\Rector\FunctionLike\UnionTypesRector`](/../master/rules/php80/src/Rector/FunctionLike/UnionTypesRector.php) diff --git a/rules/php80/src/Rector/Class_/StringableForToStringRector.php b/rules/php80/src/Rector/Class_/StringableForToStringRector.php new file mode 100644 index 00000000000..889deea5edc --- /dev/null +++ b/rules/php80/src/Rector/Class_/StringableForToStringRector.php @@ -0,0 +1,99 @@ +classManipulator = $classManipulator; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Add `Stringable` interface to classes with `__toString()` method', [ + new CodeSample( + <<<'PHP' +class SomeClass +{ + public function __toString() + { + return 'I can stringz'; + } +} +PHP +, + <<<'PHP' +class SomeClass implements Stringable +{ + public function __toString(): string + { + return 'I can stringz'; + } +} +PHP + + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Node + { + $toStringClassMethod = $node->getMethod('__toString'); + if ($toStringClassMethod === null) { + return null; + } + + if ($this->classManipulator->hasInterface($node, self::STRINGABLE)) { + return null; + } + + // add interface + $node->implements[] = new FullyQualified(self::STRINGABLE); + + // add return type + + if ($toStringClassMethod->returnType === null) { + $toStringClassMethod->returnType = new Name('string'); + } + + return $node; + } +} diff --git a/rules/php80/tests/Rector/Class_/StringableForToStringRector/Fixture/fixture.php.inc b/rules/php80/tests/Rector/Class_/StringableForToStringRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..ae2495e6767 --- /dev/null +++ b/rules/php80/tests/Rector/Class_/StringableForToStringRector/Fixture/fixture.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules/php80/tests/Rector/Class_/StringableForToStringRector/StringableForToStringRectorTest.php b/rules/php80/tests/Rector/Class_/StringableForToStringRector/StringableForToStringRectorTest.php new file mode 100644 index 00000000000..8591e5c3013 --- /dev/null +++ b/rules/php80/tests/Rector/Class_/StringableForToStringRector/StringableForToStringRectorTest.php @@ -0,0 +1,30 @@ +doTestFile($file); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return StringableForToStringRector::class; + } +}