From fff50de2fb97bda73af82114e660b0311cb69fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20Magyar?= <14284867+xHeaven@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:15:38 +0100 Subject: [PATCH] Extract property hook bodies properly (#172) --- src/PhpGenerator/Extractor.php | 23 +++++++++++++++++++++++ src/PhpGenerator/Factory.php | 9 +++++++++ 2 files changed, 32 insertions(+) diff --git a/src/PhpGenerator/Extractor.php b/src/PhpGenerator/Extractor.php index 97d2f732..43bd976e 100644 --- a/src/PhpGenerator/Extractor.php +++ b/src/PhpGenerator/Extractor.php @@ -79,6 +79,29 @@ public function extractMethodBodies(string $className): array } + /** @return array> */ + public function extractPropertyHookBodies(string $className): array + { + $nodeFinder = new NodeFinder(); + $classNode = $nodeFinder->findFirst( + $this->statements, + fn(Node $node) => $node instanceof Node\Stmt\ClassLike && $node->namespacedName->toString() === $className, + ); + + $res = []; + foreach ($nodeFinder->findInstanceOf($classNode, Node\Stmt\Property::class) as $propertyNode) { + foreach ($propertyNode->props as $propNode) { + $propName = $propNode->name->toString(); + foreach ($propertyNode->hooks as $hookNode) { + $hookType = $hookNode->name->toString(); + $res[$propName][$hookType] = $this->getReformattedContents([$hookNode->body], 1); + } + } + } + return $res; + } + + public function extractFunctionBody(string $name): ?string { $functionNode = (new NodeFinder)->findFirst( diff --git a/src/PhpGenerator/Factory.php b/src/PhpGenerator/Factory.php index 12a5687d..0e182fc0 100644 --- a/src/PhpGenerator/Factory.php +++ b/src/PhpGenerator/Factory.php @@ -124,6 +124,15 @@ public function fromClassReflection( $resolutions = []; } + if ($withBodies) { + $hookBodies = $this->getExtractor($declaringClass->getFileName())->extractPropertyHookBodies($declaringClass->name); + foreach ($class->getProperties() as $property) { + foreach ($hookBodies[$property->getName()] ?? [] as $hookType => $body) { + $property->getHook($hookType)?->setBody($body, short: true); + } + } + } + $consts = $cases = []; foreach ($from->getReflectionConstants() as $const) { if ($class->isEnum() && $from->hasCase($const->name)) {