diff --git a/Metadata/ClassMetadata.php b/Metadata/ClassMetadata.php index 7cdbbf5..9f0a7ae 100644 --- a/Metadata/ClassMetadata.php +++ b/Metadata/ClassMetadata.php @@ -34,6 +34,47 @@ class ClassMetadata extends BaseClassMetadata public $properties = array(); public $initMethod; public $environments = array(); + public $services = []; + + /** + * on first call also populate legacy fields + * + * @param string[] $service + */ + public function addService(array $service) + { + if (empty($this->id)) { + $this->id = $service['id']; + $this->parent = $service['parent']; + $this->public = $service['public']; + $this->scope = $service['scope']; + $this->abstract = $service['abstract']; + // TODO update call for other tags (there are several pull requests) + } + + $this->services[$service['id']] = $service; + } + + /** + * get list of defined services, use fallback of original fields + * + * return array[] + */ + public function getServices() + { + // TODO remove fallback for next major version + if (empty($this->services) || !isset($this->services[$this->id])) { + $this->services[] = array( + 'id' => $this->id, + 'parent' => $this->parent, + 'public' => $this->public, + 'scope' => $this->scope, + 'abstract' => $this->abstract, + ); + } + + return $this->services; + } public function isLoadedInEnvironment($env) { @@ -60,6 +101,7 @@ public function serialize() $this->initMethod, parent::serialize(), $this->environments, + $this->services, )); } @@ -79,13 +121,11 @@ public function unserialize($str) $this->lookupMethods, $this->properties, $this->initMethod, - $parentStr + $parentStr, + $this->environments, + $this->services, ) = $data; - if (isset($data[12])) { - $this->environments = $data[12]; - } - parent::unserialize($parentStr); } } diff --git a/Metadata/Driver/AnnotationDriver.php b/Metadata/Driver/AnnotationDriver.php index 4ccf32b..b75a33d 100644 --- a/Metadata/Driver/AnnotationDriver.php +++ b/Metadata/Driver/AnnotationDriver.php @@ -72,16 +72,18 @@ public function loadMetadataForClass(\ReflectionClass $class) foreach ($this->reader->getClassAnnotations($class) as $annot) { if ($annot instanceof Service) { + $service = array(); if (null === $annot->id) { - $metadata->id = $this->namingStrategy->classToServiceName($className); + $service['id'] = $this->namingStrategy->classToServiceName($className); } else { - $metadata->id = $annot->id; + $service['id'] = $annot->id; } - $metadata->parent = $annot->parent; - $metadata->public = $annot->public; - $metadata->scope = $annot->scope; - $metadata->abstract = $annot->abstract; + $service['parent'] = $annot->parent; + $service['public'] = $annot->public; + $service['scope'] = $annot->scope; + $service['abstract'] = $annot->abstract; + $metadata->addService($service); } else if ($annot instanceof Tag) { $metadata->tags[$annot->name][] = $annot->attributes; } else if ($annot instanceof Validator) { diff --git a/Metadata/MetadataConverter.php b/Metadata/MetadataConverter.php index 9c03d70..c1a20db 100644 --- a/Metadata/MetadataConverter.php +++ b/Metadata/MetadataConverter.php @@ -37,42 +37,46 @@ public function convert(ClassHierarchyMetadata $metadata) $definitions = array(); $previous = null; + /** @var ClassMetadata $classMetadata */ foreach ($metadata->classMetadata as $classMetadata) { - if (null === $previous && null === $classMetadata->parent) { - $definition = new Definition(); - } else { - $definition = new DefinitionDecorator( - $classMetadata->parent ?: $previous->id - ); - } + foreach ($classMetadata->getServices() as $service) { + if (null === $previous && null === @$service['parent']) { + $definition = new Definition(); + } else { + $definition = new DefinitionDecorator( + @$service['parent'] ?: $previous->id + ); + } - $definition->setClass($classMetadata->name); - if (null !== $classMetadata->scope) { - $definition->setScope($classMetadata->scope); - } - if (null !== $classMetadata->public) { - $definition->setPublic($classMetadata->public); - } - if (null !== $classMetadata->abstract) { - $definition->setAbstract($classMetadata->abstract); - } - if (null !== $classMetadata->arguments) { - $definition->setArguments($classMetadata->arguments); - } + $definition->setClass($classMetadata->name); + if (null !== @$service['scope']) { + $definition->setScope(@$service['scope']); + } + if (null !== @$service['public']) { + $definition->setPublic(@$service['public']); + } + if (null !== @$service['abstract']) { + $definition->setAbstract(@$service['abstract']); + } + if (null !== $classMetadata->arguments) { + $definition->setArguments($classMetadata->arguments); + } - $definition->setMethodCalls($classMetadata->methodCalls); - $definition->setTags($classMetadata->tags); - $definition->setProperties($classMetadata->properties); + $definition->setMethodCalls($classMetadata->methodCalls); + $definition->setTags($classMetadata->tags); + $definition->setProperties($classMetadata->properties); - if (null === $classMetadata->id) { - $classMetadata->id = '_jms_di_extra.unnamed.service_'.$count++; - } + if (null === @$service['id']) { + $classMetadata->id = '_jms_di_extra.unnamed.service_' . $count++; + } + + if ($classMetadata->initMethod) { + throw new \RuntimeException(sprintf('You can\'t use @AfterSetup on a service.')); + } - if ($classMetadata->initMethod) { - throw new \RuntimeException(sprintf('You can\'t use @AfterSetup on a service.')); + $definitions[$classMetadata->id] = $definition; } - $definitions[$classMetadata->id] = $definition; $previous = $classMetadata; } diff --git a/Tests/Metadata/Driver/AnnotationDriverTest.php b/Tests/Metadata/Driver/AnnotationDriverTest.php index c6814af..545fad4 100644 --- a/Tests/Metadata/Driver/AnnotationDriverTest.php +++ b/Tests/Metadata/Driver/AnnotationDriverTest.php @@ -43,6 +43,19 @@ public function testCustomAnnotationOnMethod() $this->assertEquals('fancy', @$metadata->tags['omg'], 'check key and value of custom annotation'); } + public function testMultiService() + { + $metadata = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\DiExtraBundle\Tests\Metadata\Driver\Fixture\MultiService')); + + $this->assertEquals(array( + 'first.service' => array( + 'id' => 'first.service', + ), + 'second.service' => array( + 'id' => 'first.service', + ) + ), $metadata->getServices()); + } private function getDriver() { diff --git a/Tests/Metadata/Driver/Fixture/MultiService.php b/Tests/Metadata/Driver/Fixture/MultiService.php new file mode 100644 index 0000000..dbdc045 --- /dev/null +++ b/Tests/Metadata/Driver/Fixture/MultiService.php @@ -0,0 +1,13 @@ +