diff --git a/packages/documentator/src/Processor/Metadata/PhpDocBlock.php b/packages/documentator/src/Processor/Metadata/PhpDocBlock.php new file mode 100644 index 00000000..1095406f --- /dev/null +++ b/packages/documentator/src/Processor/Metadata/PhpDocBlock.php @@ -0,0 +1,69 @@ + + */ +class PhpDocBlock implements Metadata { + public function __construct( + protected readonly PhpClass $class, + ) { + // empty + } + + /** + * @inheritDoc + */ + #[Override] + public function __invoke(File $file): mixed { + // Class? + $class = $file->getMetadata($this->class); + + if (!$class) { + return null; + } + + // Parse + $content = (new PhpDoc($class->class->getDocComment()?->getText()))->getText(); + $content = $this->preprocess($class->context, $content); + $content = trim($content); + + if (!$content) { + return new Document('', $file->getPath()); + } + + // Create + return new Document($content, $file->getPath()); + } + + private function preprocess(NameContext $context, string $string): string { + return (string) preg_replace_callback( + pattern : '/\{@(?:see|link)\s+(?P[^}\s\/:]+)(?:::(?P[^(]+\(\)))?\s?\}/imu', + callback: static function (array $matches) use ($context): string { + $class = (string) $context->getResolvedClassName(new Name($matches['class'])); + $method = $matches['method'] ?? null; + $result = $method + ? "`{$class}::{$method}`" + : "`{$class}`"; + + return $result; + }, + subject : $string, + flags : PREG_UNMATCHED_AS_NULL, + ); + } +} diff --git a/packages/documentator/src/Processor/Metadata/PhpDocBlockTest.php b/packages/documentator/src/Processor/Metadata/PhpDocBlockTest.php new file mode 100644 index 00000000..24bf190c --- /dev/null +++ b/packages/documentator/src/Processor/Metadata/PhpDocBlockTest.php @@ -0,0 +1,75 @@ +getPathname()), + false, + ); + $factory = new PhpDocBlock(new PhpClass()); + $metadata = $factory($file); + + self::assertNotNull($metadata); + self::assertEquals( + <<<'MARKDOWN' + Description. + + Summary `stdClass` and `LastDragon_ru\LaraASP\Documentator\Processor\Metadata\PhpClass`. + MARKDOWN, + (string) $metadata, + ); + } + + public function testInvokeEmpty(): void { + $file = new File(Path::normalize(__FILE__), false); + $factory = new PhpDocBlock(new PhpClass()); + $metadata = $factory($file); + + self::assertNotNull($metadata); + self::assertTrue($metadata->isEmpty()); + } + + public function testInvokeNotPhp(): void { + $file = new File(Path::normalize(__FILE__), false); + $factory = new PhpDocBlock( + new class() extends PhpClass { + #[Override] + public function __invoke(File $file): mixed { + return null; + } + }, + ); + $metadata = $factory($file); + + self::assertNull($metadata); + } +}