diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 1611b8b..089364a 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -18,6 +18,7 @@ jobs: php-version: 8.2 extensions: xdebug tools: composer:2 + ini-file: development - name: Setup problem matchers for PHP run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" - name: Setup problem matchers for PHPUnit diff --git a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php index 0d261b0..bffee78 100644 --- a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php +++ b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php @@ -305,7 +305,10 @@ private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $buil foreach ($serviceDefinitions as $serviceDefinition) { $serviceType = $xpath->query('cd:type/text()', $serviceDefinition)[0]->nodeValue; - assert(class_exists($serviceType)); + assert( + class_exists($serviceType) || interface_exists($serviceType), + "The type $serviceType does not exist" + ); $isConcrete = $xpath->query('@isConcrete', $serviceDefinition)[0]->nodeValue === 'true'; $attr = unserialize(base64_decode( $xpath->query('cd:attribute/text()', $serviceDefinition)[0]?->nodeValue @@ -331,7 +334,11 @@ private function addAliasDefinitionsToBuilder(ContainerDefinitionBuilder $builde $abstract = $xpath->query('cd:abstractService/text()', $aliasDefinition)[0]->nodeValue; $concrete = $xpath->query('cd:concreteService/text()', $aliasDefinition)[0]->nodeValue; - assert(class_exists($abstract)); + assert( + class_exists($abstract) || interface_exists($abstract), + "The type $abstract does not exist" + ); + // we are not checking for interface_exists() here because an interface cannot be a concrete service assert(class_exists($concrete)); $builder = $builder->withAliasDefinition( @@ -351,7 +358,10 @@ private function addServicePrepareDefinitionsToBuilder(ContainerDefinitionBuilde $method = $xpath->query('cd:method/text()', $prepareDefinition)[0]->nodeValue; $attr = unserialize(base64_decode($xpath->query('cd:attribute/text()', $prepareDefinition)[0]?->nodeValue)); - assert(class_exists($service)); + assert( + class_exists($service) || interface_exists($service), + "The type $service does not exist" + ); assert($method !== null && $method !== ''); $builder = $builder->withServicePrepareDefinition( @@ -372,7 +382,11 @@ private function addServiceDelegateDefinitionsToBuilder(ContainerDefinitionBuild $delegateMethod = $xpath->query('cd:delegateMethod/text()', $delegateDefinition)[0]->nodeValue; $attr = unserialize(base64_decode($xpath->query('cd:attribute/text()', $delegateDefinition)[0]?->nodeValue)); - assert(class_exists($service)); + assert( + class_exists($service) || interface_exists($service), + "The type $service does not exist" + ); + // we are not checking for interface_exists() because a delegate must be a concrete type assert(class_exists($delegateType)); assert($delegateMethod !== null && $delegateMethod !== ''); diff --git a/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php b/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php index 76c1cb9..32cef28 100644 --- a/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php +++ b/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php @@ -68,7 +68,10 @@ private function getConcreteServicesInstanceOf(ContainerDefinition $containerDef foreach ($containerDefinition->serviceDefinitions() as $service) { if ($service->isConcrete()) { $serviceDefinitionType = $serviceDefinition->type()->name(); - assert(class_exists($serviceDefinitionType)); + assert( + class_exists($serviceDefinitionType) || interface_exists($serviceDefinitionType), + "The type $serviceDefinitionType does not exist" + ); if (is_subclass_of($service->type()->name(), $serviceDefinitionType)) { yield $service; } diff --git a/src/Reflection/TypeFactory.php b/src/Reflection/TypeFactory.php index 13510b7..a43a443 100644 --- a/src/Reflection/TypeFactory.php +++ b/src/Reflection/TypeFactory.php @@ -57,7 +57,10 @@ public function fromName(string $name) : Type { default => null, }; if ($type === null) { - assert(class_exists($name)); + assert( + class_exists($name) || interface_exists($name), + "The type $name does not exist" + ); $type = $this->class($name); } diff --git a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php index 5b8ed93..cf5cfb0 100644 --- a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php +++ b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php @@ -189,7 +189,10 @@ private function addAnnotatedDefinitions( foreach ($abstractPrepareDefinitions as $abstractPrepareDefinition) { $concreteServiceName = $concretePrepareDefinition->service()->name(); $abstractServiceName = $abstractPrepareDefinition->service()->name(); - assert(class_exists($abstractServiceName)); + assert( + class_exists($abstractServiceName) || interface_exists($abstractServiceName), + "The type $abstractServiceName does not exist" + ); if (is_subclass_of($concreteServiceName, $abstractServiceName)) { $hasAbstractPrepare = true; break; @@ -277,9 +280,12 @@ private function addAliasDefinitions(ContainerDefinitionBuilder $containerDefini } foreach ($abstractTypes as $abstractType) { + $abstractTypeString = $abstractType->name(); + assert( + class_exists($abstractTypeString) || interface_exists($abstractTypeString), + "The type $abstractTypeString does not exist" + ); foreach ($concreteTypes as $concreteType) { - $abstractTypeString = $abstractType->name(); - assert(class_exists($abstractTypeString), "The type $abstractTypeString does not exist"); if (is_subclass_of($concreteType->name(), $abstractTypeString)) { $aliasDefinition = definitionFactory()->aliasDefinition($abstractType, $concreteType); $containerDefinitionBuilder = $containerDefinitionBuilder->withAliasDefinition($aliasDefinition);