diff --git a/scoper.php b/scoper.php index e9af1de3cfe..d6da45ea9e7 100644 --- a/scoper.php +++ b/scoper.php @@ -107,6 +107,28 @@ static function (string $filePath, string $prefix, string $content): string { ); }, + // keep public documentation examples readable + static function (string $filePath, string $prefix, string $content): string { + if (! \str_contains($filePath, 'rules/')) { + return $content; + } + + if (! \str_ends_with($filePath, 'Rector.php')) { + return $content; + } + + return Strings::replace( + $content, + '#(public function getRuleDefinition\(\): RuleDefinition\s+\{\R)(.*?)(\R \})#s', + static function (array $match) use ($prefix): string { + $body = str_replace($prefix . '\\', '', $match[2]); + $body = Strings::replace($body, '#^\s*namespace ' . preg_quote($prefix, '#') . ';\R\R?#m', ''); + + return $match[1] . $body . $match[3]; + } + ); + }, + // un-prefix composer plugin static function (string $filePath, string $prefix, string $content): string { if (! \str_ends_with($filePath, 'vendor/rector/extension-installer/src/Plugin.php')) { diff --git a/tests/Scoper/ScoperPatchersTest.php b/tests/Scoper/ScoperPatchersTest.php new file mode 100644 index 00000000000..860db4d4a63 --- /dev/null +++ b/tests/Scoper/ScoperPatchersTest.php @@ -0,0 +1,131 @@ +provideScoperConfig(); + + $content = <<<'PHP' +__invoke( + __DIR__ . '/../../rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php', + 'RectorPrefix202607', + $content + ); + } + + $this->assertStringContainsString('use Webmozart\Assert\Assert;', (string) $content); + $this->assertStringContainsString('use RectorPrefix202607\Webmozart\Assert\Assert;', (string) $content); + $this->assertStringContainsString(Assert::class . '::allString($items);', (string) $content); + $this->assertStringContainsString("'SomeVendor\ValueObject::class'", (string) $content); + $this->assertStringContainsString("'new SomeVendor\ValueObject()'", (string) $content); + $this->assertStringContainsString('$metadata = \'Webmozart\Assert\Assert\';', (string) $content); + $this->assertStringContainsString('\RectorPrefix202607\SomeVendor\Runtime::class;', (string) $content); + $this->assertStringNotContainsString('namespace RectorPrefix202607;', (string) $content); + } + + public function testRemovesPrefixedNamespaceInGetRuleDefinitionWithWindowsLineEndings(): void + { + $scoperConfig = $this->provideScoperConfig(); + + $content = str_replace( + "\n", + "\r\n", + <<<'PHP' +__invoke( + __DIR__ . '/../../rules/Some/Rector/SomeRector.php', + 'RectorPrefix202607', + $content + ); + } + + $this->assertStringNotContainsString('namespace RectorPrefix202607;', (string) $content); + $this->assertStringContainsString('SomeVendor\ValueObject::class;', (string) $content); + } + + /** + * @return array{patchers: list} + */ + private function provideScoperConfig(): array + { + if (! self::$isFinderAliased) { + class_alias(Finder::class, 'Isolated\Symfony\Component\Finder\Finder'); + self::$isFinderAliased = true; + } + + return require __DIR__ . '/../../scoper.php'; + } +}