diff --git a/src/Analyzer/FileVisitor.php b/src/Analyzer/FileVisitor.php index 7ffedda9..0dbc605f 100644 --- a/src/Analyzer/FileVisitor.php +++ b/src/Analyzer/FileVisitor.php @@ -67,6 +67,9 @@ public function enterNode(Node $node): void // handles attribute definition like #[MyAttribute] $this->handleAttributeNode($node); + + // handles property hooks like public string $name { get => ...; set { ... } } + $this->handlePropertyHookNode($node); } public function getClassDescriptions(): array @@ -349,4 +352,16 @@ private function addParamDependency(Node\Param $node): void $this->classDescriptionBuilder ->addDependency(new ClassDependency($type->toString(), $node->getLine())); } + + private function handlePropertyHookNode(Node $node): void + { + if (!($node instanceof Node\PropertyHook)) { + return; + } + + // Handle parameters in set hooks (e.g., set(MyClass $value) { ... }) + foreach ($node->params as $param) { + $this->addParamDependency($param); + } + } } diff --git a/tests/Unit/Analyzer/FileParser/CanParsePropertyHooksTest.php b/tests/Unit/Analyzer/FileParser/CanParsePropertyHooksTest.php index 9e71b636..01a548ae 100644 --- a/tests/Unit/Analyzer/FileParser/CanParsePropertyHooksTest.php +++ b/tests/Unit/Analyzer/FileParser/CanParsePropertyHooksTest.php @@ -40,4 +40,75 @@ public function __construct(string $firstName, string $lastName) { self::assertInstanceOf(ClassDescription::class, $cd[0]); } + + public function test_it_collects_dependencies_from_property_hooks(): void + { + $code = <<< 'EOF' + format($this->name); + } + set { + $validator = new Validator(); + $validator->validate($value); + $this->name = $value; + Logger::log('Name set'); + } + } + } + EOF; + + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_4); + $fp->parse($code, 'relativePathName'); + + $cd = $fp->getClassDescriptions(); + + self::assertInstanceOf(ClassDescription::class, $cd[0]); + + $dependencies = $cd[0]->getDependencies(); + $dependencyNames = array_map(fn ($dep) => $dep->getFQCN()->toString(), $dependencies); + + self::assertContains('App\Services\Formatter', $dependencyNames); + self::assertContains('App\Services\Validator', $dependencyNames); + self::assertContains('App\Services\Logger', $dependencyNames); + } + + public function test_it_collects_dependencies_from_property_hook_parameters(): void + { + $code = <<< 'EOF' + name = $name->toString(); + } + } + } + EOF; + + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_4); + $fp->parse($code, 'relativePathName'); + + $cd = $fp->getClassDescriptions(); + + self::assertInstanceOf(ClassDescription::class, $cd[0]); + + $dependencies = $cd[0]->getDependencies(); + $dependencyNames = array_map(fn ($dep) => $dep->getFQCN()->toString(), $dependencies); + + self::assertContains('App\ValueObjects\Name', $dependencyNames); + } }