From 080742f3cc983e7f58e81b02e1a42caaea077e0a Mon Sep 17 00:00:00 2001 From: Charles Sprayberry Date: Mon, 17 Jun 2024 17:13:27 -0400 Subject: [PATCH 1/2] Resolve majority of static-analysis issues --- Justfile | 6 +- annotated-container-definition.xsd | 68 ++-- annotated-container.xsd | 12 +- composer.json | 9 +- known-issues.xml | 297 ------------------ psalm.xml | 15 +- src/Autowire/AutowireableFactory.php | 5 +- src/Autowire/AutowireableParameter.php | 2 +- ...nScanningThirdPartyInitializerProvider.php | 22 +- src/Bootstrap/ServiceGatherer.php | 2 +- src/Bootstrap/ServiceWiringListener.php | 21 +- .../XmlBootstrappingConfiguration.php | 4 +- src/Cli/Command/InitCommand.php | 105 +++++-- .../AbstractContainerFactory.php | 6 +- .../StandardAliasDefinitionResolver.php | 4 +- .../AurynContainerFactory.php | 27 +- .../AurynContainerFactoryState.php | 10 +- .../HasServicePrepareState.php | 9 +- .../IlluminateContainerFactory.php | 73 +++-- .../IlluminateContainerFactoryState.php | 34 +- src/ContainerFactory/ListOf.php | 3 +- src/ContainerFactory/ListOfAsArray.php | 8 +- .../PhpDiContainerFactory.php | 50 ++- .../PhpDiContainerFactoryState.php | 60 +++- src/Definition/InjectDefinitionBuilder.php | 26 +- .../ProfilesAwareContainerDefinition.php | 4 +- .../XmlContainerDefinitionSerializer.php | 74 +++-- src/Definition/ServicePrepareDefinition.php | 2 +- src/Exception/InvalidAutowireParameter.php | 4 - .../InvalidThirdPartyInitializer.php | 12 + src/Function/auto-wired-parameters.php | 20 +- src/Function/definitions.php | 2 +- src/Internal/SerializerInjectValueParser.php | 13 +- .../Check/DuplicateServiceDelegate.php | 4 +- .../Check/DuplicateServiceName.php | 2 +- .../Check/DuplicateServicePrepare.php | 2 +- .../Check/DuplicateServiceType.php | 2 +- .../MultiplePrimaryForAbstractService.php | 6 +- .../Check/NonPublicServiceDelegate.php | 4 +- .../Check/NonPublicServicePrepare.php | 4 +- ...tatedTargetContainerDefinitionAnalyzer.php | 18 +- .../AnnotatedTargetDefinitionConverter.php | 34 +- stubs.php | 27 ++ test/Unit/Bootstrap/BootstrapTest.php | 34 +- ...nningThirdPartyInitializerProviderTest.php | 139 ++++++++ test/Unit/Cli/Command/ValidateCommandTest.php | 6 +- .../ContainerDefinitionAssertionsTrait.php | 8 +- .../ContainerFactoryTestCase.php | 124 ++++---- .../ProfilesAwareContainerDefinitionTest.php | 4 +- .../ServiceDefinitionBuilderTest.php | 4 +- .../Check/DuplicateServiceDelegateTest.php | 8 +- .../Check/DuplicateServicePrepareTest.php | 8 +- .../MultiplePrimaryForAbstractServiceTest.php | 6 +- .../DataProviderExpects/ExpectedInject.php | 2 +- .../AssertExpectedInjectDefinition.php | 14 +- .../HasConfigurationDefinitionTestsTrait.php | 6 +- .../HasServiceDefinitionTestsTrait.php | 12 +- .../InjectPrepareServicesTest.php | 2 +- .../InjectServiceConstructorServicesTest.php | 2 +- ...dTargetContainerDefinitionAnalyzerTest.php | 6 +- ...AnnotatedTargetDefinitionConverterTest.php | 2 +- .../AbstractSharedServicesTest.php | 2 +- ...tatedTargetDefinitionConverterTestCase.php | 8 +- .../InjectArrayMethodParamTest.php | 2 +- .../InjectBoolMethodParamTest.php | 2 +- .../InjectEnvMethodParamTest.php | 2 +- .../InjectExplicitMixedMethodParamTest.php | 2 +- .../InjectFloatMethodParamTest.php | 2 +- .../InjectImplicitMixedMethodParamTest.php | 2 +- .../InjectIntMethodParamTest.php | 2 +- ...ctMultipleProfilesFirstMethodParamTest.php | 2 +- ...tMultipleProfilesSecondMethodParamTest.php | 2 +- ...ctMultipleProfilesThirdMethodParamTest.php | 2 +- .../InjectNullableServiceMethodParamTest.php | 2 +- .../InjectNullableStringMethodParamTest.php | 2 +- .../InjectScalarTypeUnionMethodParamTest.php | 2 +- .../InjectServiceMethodParamTest.php | 6 +- ...tServiceScalarTypeUnionMethodParamTest.php | 2 +- ...ectServiceTypeIntersectMethodParamTest.php | 6 +- .../InjectStringMethodParamTest.php | 2 +- .../MultipleServicesWithPrimaryTest.php | 2 +- .../NamedServiceConverterTest.php | 2 +- .../ProfileResolvedServicesConverterTest.php | 2 +- .../ServiceDelegateConverterTest.php | 2 +- .../ServicePrepareConverterTest.php | 2 +- .../SingleAliasedServiceConverterTest.php | 2 +- .../SingleConcreteServiceConverterTest.php | 2 +- test/Unit/ThirdPartyFunctionsTest.php | 6 +- 88 files changed, 899 insertions(+), 672 deletions(-) delete mode 100644 known-issues.xml create mode 100644 stubs.php diff --git a/Justfile b/Justfile index 0424ed2..d5c11db 100644 --- a/Justfile +++ b/Justfile @@ -32,8 +32,8 @@ static-analysis-set-baseline: @./tools/psalm/vendor/bin/psalm --set-baseline=known-issues.xml --no-cache # Update the baseline to _remove_ fixed issues. If new issues are to be added please use static-analysis-set-baseline -static-analysis-update-baseline: - @./tools/psalm/vendor/bin/psalm --update-baseline --no-cache +static-analysis-update-baseline *FLAGS: + @./tools/psalm/vendor/bin/psalm --update-baseline --no-cache {{FLAGS}} static-analysis-clear-cache: @./tools/psalm/vendor/bin/psalm --clear-cache @@ -56,4 +56,4 @@ ci-check: # Generate a new Architectural Decision Record document generate-adr: - @./vendor/bin/architectural-decisions \ No newline at end of file + @./tools/adr/bin/generate-adr \ No newline at end of file diff --git a/annotated-container-definition.xsd b/annotated-container-definition.xsd index c178b9c..77c06fa 100644 --- a/annotated-container-definition.xsd +++ b/annotated-container-definition.xsd @@ -5,8 +5,8 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="https://annotated-container.cspray.io/schema/annotated-container-definition.xsd" elementFormDefault="qualified" - attributeFormDefault="unqualified" - targetNamespace="https://annotated-container.cspray.io/schema/annotated-container-definition.xsd"> + targetNamespace="https://annotated-container.cspray.io/schema/annotated-container-definition.xsd" + > @@ -42,11 +42,11 @@ - + - + @@ -59,8 +59,8 @@ - - + + @@ -72,9 +72,9 @@ - - - + + + @@ -86,10 +86,10 @@ - - - - + + + + @@ -101,23 +101,29 @@ - - - - - + + + + + - + - + + + + + + + @@ -125,17 +131,35 @@ - + - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/annotated-container.xsd b/annotated-container.xsd index bb6feaa..38949d9 100644 --- a/annotated-container.xsd +++ b/annotated-container.xsd @@ -38,17 +38,23 @@ - + - + - + + + + + + + diff --git a/composer.json b/composer.json index e378916..d56cdd5 100644 --- a/composer.json +++ b/composer.json @@ -16,11 +16,12 @@ "ext-dom": "*", "ext-libxml": "*", "composer-runtime-api": "^2.2", - "cspray/annotated-container-adr": "^3.2", - "cspray/annotated-container-attribute": "^2.0.0.alpha.5", - "cspray/annotated-target": "^v1.1", + "cspray/annotated-container-adr": "^4.0.0.alpha", + "cspray/annotated-container-attribute": "^2.0.0-alpha", + "cspray/annotated-target": "^v2.0.0.alpha", + "cspray/architectural-decision": "^3.0.0.alpha", "cspray/precision-stopwatch": "^0.2.0", - "cspray/typiphy": "^0.3", + "cspray/typiphy": "^0.4", "nikic/php-parser": "^4.19", "psr/container": "^2.0" }, diff --git a/known-issues.xml b/known-issues.xml deleted file mode 100644 index 01d7fbb..0000000 --- a/known-issues.xml +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - service; - } - - public function definition() : ServiceDefinition { - return $this->definition; - } - }]]> - - - - - - - - - - - textContent]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - state->injector->make( - $classType, - $this->convertAutowireableParameterSet($parameters) - )]]> - - - - - $value->listOf->toCollection($values)]]> - - - - - - - - - - - - - servicePrepares]]> - servicePrepares]]> - - - - - - - - - - - $container->call([$target, $delegateInfo['delegateMethod']])]]> - - - - - - - - - getName()]]> - getName()]]> - - - - - - - - - - - - - - name()]]]> - name()]]]> - - - - - - - - - - - - - - - - - - - state->container->make($classType, $params)]]> - - - - - abstractServices]]> - aliases]]> - concreteServices]]> - delegates]]> - namedServices]]> - - - - - - - - - - $container->call(]]> - - - - value()->getName()]]> - - - - - name()]]]> - - - - - - - - - - - container->make( - $classType, - $this->convertAutowireableParameterSet($parameters) - )]]> - - - serviceKey($aliasDefinition->abstractService()->getName())]]> - - - - - - - - - - - - - - serviceKeys[$serviceType] ?? null]]> - serviceKeys[$serviceType] ?? null]]> - - - - - methodName]]> - paramName]]> - store]]> - - - - - - - - paramName]]> - - - - - saveXML()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - query('@isPrimary', $serviceDefinition)[0]?->value]]> - query('@isPrimary', $serviceDefinition)[0]?->value]]> - - - diff --git a/psalm.xml b/psalm.xml index 69131dc..7644dec 100644 --- a/psalm.xml +++ b/psalm.xml @@ -7,7 +7,6 @@ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" findUnusedBaselineEntry="true" findUnusedCode="false" - errorBaseline="known-issues.xml" > @@ -19,10 +18,17 @@ + + + + + + + @@ -31,6 +37,13 @@ + + + + + + + diff --git a/src/Autowire/AutowireableFactory.php b/src/Autowire/AutowireableFactory.php index abb99f9..633e5f7 100644 --- a/src/Autowire/AutowireableFactory.php +++ b/src/Autowire/AutowireableFactory.php @@ -12,11 +12,12 @@ interface AutowireableFactory { * Construct an object matching $classType, autowiring any parameters that were not provided as part of the * AutowireableParameterSet. * - * @param string $classType The FQCN for the type that should be created + * @template T of object + * @param class-string $classType The FQCN for the type that should be created * @param AutowireableParameterSet|null $parameters A set of AutowireableParameters that should be used for constructor * arguments in place of or in addition to any autowire-resolved * parameters. - * @return object An object that is an instanceof $classType + * @return T */ public function make(string $classType, AutowireableParameterSet $parameters = null) : object; } diff --git a/src/Autowire/AutowireableParameter.php b/src/Autowire/AutowireableParameter.php index a1bd6d3..d4c0e2e 100644 --- a/src/Autowire/AutowireableParameter.php +++ b/src/Autowire/AutowireableParameter.php @@ -15,7 +15,7 @@ interface AutowireableParameter { /** - * @return string The name of the parameter the value should be injected into + * @return non-empty-string The name of the parameter the value should be injected into */ public function name() : string; diff --git a/src/Bootstrap/ComposerJsonScanningThirdPartyInitializerProvider.php b/src/Bootstrap/ComposerJsonScanningThirdPartyInitializerProvider.php index 8ef9333..4539adf 100644 --- a/src/Bootstrap/ComposerJsonScanningThirdPartyInitializerProvider.php +++ b/src/Bootstrap/ComposerJsonScanningThirdPartyInitializerProvider.php @@ -36,8 +36,28 @@ private function scanVendorDirectoryForInitializers() : array { 512, JSON_THROW_ON_ERROR ); + assert(is_array($composerData)); + + $extra = $composerData['extra'] ?? null; + if (!is_array($extra) || !array_key_exists('$annotatedContainer', $extra)) { + return []; + } + + $annotatedContainerExtra = $extra['$annotatedContainer']; + + if (!is_array($annotatedContainerExtra)) { + throw InvalidThirdPartyInitializer::fromComposerExtraAnnotatedContainerConfigNotArray(); + } + + if (!array_key_exists('initializers', $annotatedContainerExtra)) { + throw InvalidThirdPartyInitializer::fromComposerExtraAnnotatedContainerConfigNoInitializers(); + } + + $packageInitializers = $annotatedContainerExtra['initializers']; + if (!is_array($packageInitializers)) { + throw InvalidThirdPartyInitializer::fromComposerExtraAnnotatedContainerConfigInitializersNotArray(); + } - $packageInitializers = $composerData['extra']['$annotatedContainer']['initializers'] ?? []; foreach ($packageInitializers as $packageInitializer) { if (!is_string($packageInitializer) || !class_exists($packageInitializer)) { throw InvalidThirdPartyInitializer::fromConfiguredProviderNotClass( diff --git a/src/Bootstrap/ServiceGatherer.php b/src/Bootstrap/ServiceGatherer.php index e68a545..03c46a2 100644 --- a/src/Bootstrap/ServiceGatherer.php +++ b/src/Bootstrap/ServiceGatherer.php @@ -14,7 +14,7 @@ public function servicesForType(string $type) : array; /** * @template T * @param class-string $attributeType - * @return list> + * @return list */ public function servicesWithAttribute(string $attributeType) : array; } diff --git a/src/Bootstrap/ServiceWiringListener.php b/src/Bootstrap/ServiceWiringListener.php index 59697ee..8912b4e 100644 --- a/src/Bootstrap/ServiceWiringListener.php +++ b/src/Bootstrap/ServiceWiringListener.php @@ -27,15 +27,20 @@ public function __construct( $this->containerDefinition = new ProfilesAwareContainerDefinition($containerDefinition, $activeProfiles); } + /** + * @template T of object + * @param class-string $type + * @return list> + */ public function servicesForType(string $type) : array { - /** @var list $services */ + /** @var list> $services */ $services = []; foreach ($this->containerDefinition->serviceDefinitions() as $serviceDefinition) { if ($serviceDefinition->isAbstract()) { continue; } - $serviceType = $serviceDefinition->type()->getName(); + $serviceType = $serviceDefinition->type()->name(); if (is_a($serviceType, $type, true)) { $service = $this->container->get($serviceType); assert($service instanceof $type); @@ -58,7 +63,7 @@ public function servicesWithAttribute(string $attributeType) : array { continue; } - $service = $this->container->get($serviceDefinition->type()->getName()); + $service = $this->container->get($serviceDefinition->type()->name()); assert(is_object($service)); $services[] = $this->createServiceFromServiceDefinition($service, $serviceDefinition); } @@ -72,7 +77,12 @@ public function servicesWithAttribute(string $attributeType) : array { * @return ServiceFromServiceDefinition */ private function createServiceFromServiceDefinition(object $service, ServiceDefinition $serviceDefinition) : ServiceFromServiceDefinition { - return new class($service, $serviceDefinition) implements ServiceFromServiceDefinition { + $serviceFromDefinition = + + /** + * @implements ServiceFromServiceDefinition + */ + new class($service, $serviceDefinition) implements ServiceFromServiceDefinition { public function __construct( private readonly object $service, private readonly ServiceDefinition $definition @@ -87,6 +97,9 @@ public function definition() : ServiceDefinition { return $this->definition; } }; + + /** @var ServiceFromServiceDefinition $serviceFromDefinition */ + return $serviceFromDefinition; } }; $this->wireServices($container, $serviceGatherer); diff --git a/src/Bootstrap/XmlBootstrappingConfiguration.php b/src/Bootstrap/XmlBootstrappingConfiguration.php index 92decf4..dff0e2f 100644 --- a/src/Bootstrap/XmlBootstrappingConfiguration.php +++ b/src/Bootstrap/XmlBootstrappingConfiguration.php @@ -54,7 +54,9 @@ public function __construct( $scanDirectoriesNodes = $xpath->query('/ac:annotatedContainer/ac:scanDirectories/ac:source/ac:dir'); $scanDirectories = []; foreach ($scanDirectoriesNodes as $scanDirectory) { - $scanDirectories[] = $scanDirectory->textContent; + $sourceDirectory = $scanDirectory->nodeValue; + assert($sourceDirectory !== null); + $scanDirectories[] = $sourceDirectory; } $vendorPackagesNodes = $xpath->query('/ac:annotatedContainer/ac:scanDirectories/ac:vendor/ac:package'); diff --git a/src/Cli/Command/InitCommand.php b/src/Cli/Command/InitCommand.php index 5b36307..9f13890 100644 --- a/src/Cli/Command/InitCommand.php +++ b/src/Cli/Command/InitCommand.php @@ -164,7 +164,19 @@ public function handle(Input $input, TerminalOutput $output) : int { throw ComposerConfigurationNotFound::fromMissingComposerJson(); } - $composer = json_decode($this->filesystem->read($composerFile), true); + + // Normally we'd want to test that this is what we expect. However, if you have a composer.json file we + // expect it to adhere to the composer.json schema and this is how the relevant pieces of autoloading work. + // Testing that this piece is formatted correctly is a waste. It is covered by Composer's spec and how + // Composer autoloading works. If you've messed up this portion of your composer.json chances are this code + // will never run in the first place. + /** + * @var array{ + * autoload?: array{"psr-0"?: list, "psr-4"?: list}, + * "autoload-dev"?: array{"psr-0"?: list, "psr-4"?: list} + * } $composer + */ + $composer = json_decode($this->filesystem->read($composerFile), associative: true, flags: JSON_THROW_ON_ERROR); $this->generateAndSaveConfiguration($input, $composer, $configFile); @@ -193,36 +205,44 @@ private function validateInput(Input $input) : void { } /** + * @param array{ + * autoload?: array{"psr-4"?: list, "psr-0"?: list}, + * "autoload-dev"?: array{"psr-4"?: list, "psr-0"?: list} + * } $composer * @return list */ private function getComposerDirectories(array $composer) : array { - $autoloadPsr4 = $composer['autoload']['psr-4'] ?? []; - $autoloadPsr0 = $composer['autoload']['psr-0'] ?? []; - $autoloadDevPsr4 = $composer['autoload-dev']['psr-4'] ?? []; - $autoloadDevPsr0 = $composer['autoload-dev']['psr-0'] ?? []; - - $composerDirs = [ - ...$autoloadPsr0, - ...$autoloadPsr4, - ]; - $composerDevDirs = [ - ...$autoloadDevPsr0, - ...$autoloadDevPsr4, - ]; + $normalizedData = $this->normalizedComposerJson($composer); $dirs = []; + $composerDirectories = [ + ...$normalizedData['autoload']['psr-0'], + ...$normalizedData['autoload']['psr-4'], + ...$normalizedData['autoload-dev']['psr-0'], + ...$normalizedData['autoload-dev']['psr-4'], + ]; - foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($composerDirs)) as $composerDir) { - $dirs[] = (string) $composerDir; - } - - foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($composerDevDirs)) as $composerDevDir) { - $dirs[] = (string) $composerDevDir; + /** + * @var non-empty-string $composerDir + */ + foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($composerDirectories)) as $composerDir) { + $dirs[] = $composerDir; } return $dirs; } + /** + * @param Input $input + * @param array{ + * autoload?: array{"psr-4"?: list, "psr-0"?: list}, + * "autoload-dev"?: array{"psr-4"?: list, "psr-0"?: list} + * } $composer + * @param string $configFile + * @return void + * @throws ComposerAutoloadNotFound + * @throws DOMException + */ private function generateAndSaveConfiguration(Input $input, array $composer, string $configFile) : void { $composerDirectories = $this->getComposerDirectories($composer); if ($composerDirectories === []) { @@ -253,11 +273,14 @@ private function generateAndSaveConfiguration(Input $input, array $composer, str ); } - /** @var string|array|null $parameterStores */ - $parameterStores = $input->option('parameter-store'); - if ($parameterStores !== null) { - $parameterStores = is_string($parameterStores) ? [$parameterStores] : $parameterStores; + $parameterStoresInput = $input->option('parameter-store'); + if ($parameterStoresInput !== null) { + $parameterStores = is_string($parameterStoresInput) ? [$parameterStoresInput] : $parameterStoresInput; $parameterStoresNode = $root->appendChild($dom->createElementNS(self::XML_SCHEMA, 'parameterStores')); + + assert(is_array($parameterStores)); + + /** @var non-empty-string $parameterStore */ foreach ($parameterStores as $parameterStore) { $parameterStoresNode->appendChild($dom->createElementNS(self::XML_SCHEMA, 'parameterStore', $parameterStore)); } @@ -298,4 +321,38 @@ private function generateAndSaveConfiguration(Input $input, array $composer, str $dom->schemaValidate($schemaPath); $this->filesystem->write($configFile, $dom->saveXML()); } + + /** + * @param array{ + * autoload?: array{"psr-4"?: list, "psr-0"?: list}, + * "autoload-dev"?: array{"psr-4"?: list, "psr-0"?: list} + * } $composer + * @return array{ + * autoload: array{"psr-4": list, "psr-0": list}, + * "autoload-dev": array{"psr-4": list, "psr-0": list} + * } + */ + private function normalizedComposerJson(array $composer) : array { + /** + * @var array{ + * autoload: array{"psr-4": list, "psr-0": list}, + * "autoload-dev": array{"psr-4": list, "psr-0": list} + * } $normalized + */ + $normalized = array_merge_recursive( + [ + 'autoload' => [ + 'psr-4' => [], + 'psr-0' => [] + ], + 'autoload-dev' => [ + 'psr-4' => [], + 'psr-0' => [] + ] + ], + $composer + ); + + return $normalized; + } } diff --git a/src/ContainerFactory/AbstractContainerFactory.php b/src/ContainerFactory/AbstractContainerFactory.php index c07a0c4..d870a9f 100644 --- a/src/ContainerFactory/AbstractContainerFactory.php +++ b/src/ContainerFactory/AbstractContainerFactory.php @@ -104,6 +104,9 @@ final protected function injectDefinitionValue(InjectDefinition $definition) : m if ($parameterStore === null) { throw ParameterStoreNotFound::fromParameterStoreNotAddedToContainerFactory($store); } + assert(is_string($value) && $value !== ''); + + /** @var mixed $value */ $value = $parameterStore->fetch($definition->type(), $value); } @@ -114,7 +117,8 @@ final protected function injectDefinitionValue(InjectDefinition $definition) : m $value->type(), $type ); - } elseif ($type instanceof ObjectType && !is_a($definition->type()->getName(), UnitEnum::class, true)) { + } elseif ($type instanceof ObjectType && !is_a($definition->type()->name(), UnitEnum::class, true)) { + assert(is_string($value) && $value !== ''); $value = new ContainerReference($value, $type); } diff --git a/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php b/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php index e5ad043..d3b1a62 100644 --- a/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php +++ b/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php @@ -19,7 +19,7 @@ public function resolveAlias( } else { $aliases = []; foreach ($containerDefinition->aliasDefinitions() as $aliasDefinition) { - if ($aliasDefinition->abstractService()->getName() === $abstractService->getName()) { + if ($aliasDefinition->abstractService()->name() === $abstractService->name()) { $aliases[] = $aliasDefinition; } } @@ -71,7 +71,7 @@ public function aliasDefinition() : ?AliasDefinition { private function isServiceDelegate(ContainerDefinition $containerDefinition, ObjectType $service) : bool { foreach ($containerDefinition->serviceDelegateDefinitions() as $serviceDelegateDefinition) { - if ($serviceDelegateDefinition->serviceType()->getName() === $service->getName()) { + if ($serviceDelegateDefinition->serviceType()->name() === $service->name()) { return true; } } diff --git a/src/ContainerFactory/AurynContainerFactory.php b/src/ContainerFactory/AurynContainerFactory.php index d6e532b..a3c9dc0 100644 --- a/src/ContainerFactory/AurynContainerFactory.php +++ b/src/ContainerFactory/AurynContainerFactory.php @@ -40,7 +40,7 @@ protected function containerFactoryState(ContainerDefinition $containerDefinitio protected function handleServiceDefinition(ContainerFactoryState $state, ServiceDefinition $definition) : void { assert($state instanceof AurynContainerFactoryState); - $state->injector->share($definition->type()->getName()); + $state->injector->share($definition->type()->name()); $name = $definition->name(); if ($name !== null) { $state->addNameType($name, $definition->type()); @@ -52,36 +52,37 @@ protected function handleAliasDefinition(ContainerFactoryState $state, AliasDefi $alias = $resolution->aliasDefinition(); if ($alias !== null) { $state->injector->alias( - $alias->abstractService()->getName(), - $alias->concreteService()->getName() + $alias->abstractService()->name(), + $alias->concreteService()->name() ); } } protected function handleServiceDelegateDefinition(ContainerFactoryState $state, ServiceDelegateDefinition $definition) : void { assert($state instanceof AurynContainerFactoryState); - $delegateType = $definition->delegateType()->getName(); + $delegateType = $definition->delegateType()->name(); $delegateMethod = $definition->delegateMethod(); $parameters = $state->parametersForMethod($delegateType, $delegateMethod); $state->injector->delegate( - $definition->serviceType()->getName(), + $definition->serviceType()->name(), static fn() : mixed => $state->injector->execute([$delegateType, $delegateMethod], $parameters) ); } protected function handleServicePrepareDefinition(ContainerFactoryState $state, ServicePrepareDefinition $definition) : void { assert($state instanceof AurynContainerFactoryState); - $serviceType = $definition->service()->getName(); + $serviceType = $definition->service()->name(); $state->addServicePrepare($serviceType, $definition->methodName()); } protected function handleInjectDefinition(ContainerFactoryState $state, InjectDefinition $definition) : void { assert($state instanceof AurynContainerFactoryState); - $injectTargetType = $definition->class()->getName(); + $injectTargetType = $definition->class()->name(); $method = $definition->methodName(); $parameterName = $definition->parameterName(); + /** @var mixed $value */ $value = $this->injectDefinitionValue($definition); $state->addMethodInject($injectTargetType, $method, $parameterName, $value); @@ -96,10 +97,6 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil } } - /** - * @var class-string $serviceType - * @var list $methods - */ foreach ($state->servicePrepares() as $serviceType => $methods) { $state->injector->prepare( $serviceType, @@ -129,9 +126,11 @@ public function get(string $id) { throw ServiceNotFound::fromServiceNotInContainer($id); } + assert($id !== ''); + $namedType = $this->state->typeForName($id); if ($namedType !== null) { - $id = $namedType->getName(); + $id = $namedType->name(); } return $this->state->injector->make($id); } catch (InjectionException $injectionException) { @@ -140,6 +139,8 @@ public function get(string $id) { } public function has(string $id): bool { + assert($id !== ''); + $namedType = $this->state->typeForName($id); if ($namedType !== null) { return true; @@ -176,7 +177,7 @@ private function convertAutowireableParameterSet(AutowireableParameterSet $param /** @var AutowireableParameter $parameter */ foreach ($parameters as $parameter) { $name = $parameter->isServiceIdentifier() ? $parameter->name() : ':' . $parameter->name(); - $params[$name] = $parameter->isServiceIdentifier() ? $parameter->value()->getName() : $parameter->value(); + $params[$name] = $parameter->isServiceIdentifier() ? $parameter->value()->name() : $parameter->value(); } } return $params; diff --git a/src/ContainerFactory/AurynContainerFactoryState.php b/src/ContainerFactory/AurynContainerFactoryState.php index 211f3bc..8d98b3b 100644 --- a/src/ContainerFactory/AurynContainerFactoryState.php +++ b/src/ContainerFactory/AurynContainerFactoryState.php @@ -39,7 +39,7 @@ public function addMethodInject(string $class, string $method, string $param, mi $key = $param; $nameType = $this->typeForName($value->name); if ($nameType !== null) { - $value = $nameType->getName(); + $value = $nameType->name(); } else { $value = $value->name; } @@ -47,16 +47,16 @@ public function addMethodInject(string $class, string $method, string $param, mi $key = '+' . $param; $values = []; foreach ($this->containerDefinition->serviceDefinitions() as $serviceDefinition) { - if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->getName() === $class) { + if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->name() === $class) { continue; } - if (is_a($serviceDefinition->type()->getName(), $value->valueType->getName(), true)) { - $values[] = $this->injector->make($serviceDefinition->type()->getName()); + if (is_a($serviceDefinition->type()->name(), $value->valueType->name(), true)) { + $values[] = $this->injector->make($serviceDefinition->type()->name()); } } - $value = static fn() => $value->listOf->toCollection($values); + $value = static fn() : mixed => $value->listOf->toCollection($values); } else { $key = ':' . $param; } diff --git a/src/ContainerFactory/HasServicePrepareState.php b/src/ContainerFactory/HasServicePrepareState.php index 57f0433..7bbde3c 100644 --- a/src/ContainerFactory/HasServicePrepareState.php +++ b/src/ContainerFactory/HasServicePrepareState.php @@ -5,15 +5,22 @@ trait HasServicePrepareState { /** - * @var array> + * @var array> */ private array $servicePrepares = []; + /** + * @param class-string $class + * @param non-empty-string $method + */ public function addServicePrepare(string $class, string $method) : void { $this->servicePrepares[$class] ??= []; $this->servicePrepares[$class][] = $method; } + /** + * @return array> + */ public function servicePrepares() : array { return $this->servicePrepares; } diff --git a/src/ContainerFactory/IlluminateContainerFactory.php b/src/ContainerFactory/IlluminateContainerFactory.php index 7097505..d52b0be 100644 --- a/src/ContainerFactory/IlluminateContainerFactory.php +++ b/src/ContainerFactory/IlluminateContainerFactory.php @@ -49,13 +49,13 @@ protected function containerFactoryState(ContainerDefinition $containerDefinitio protected function handleServiceDefinition(ContainerFactoryState $state, ServiceDefinition $definition) : void { assert($state instanceof IlluminateContainerFactoryState); if ($definition->isConcrete()) { - $state->addConcreteService($definition->type()->getName()); + $state->addConcreteService($definition->type()->name()); } else { - $state->addAbstractService($definition->type()->getName()); + $state->addAbstractService($definition->type()->name()); } $name = $definition->name(); if ($name !== null) { - $state->addNamedService($definition->type()->getName(), $name); + $state->addNamedService($definition->type()->name(), $name); } } @@ -63,24 +63,24 @@ protected function handleAliasDefinition(ContainerFactoryState $state, AliasDefi assert($state instanceof IlluminateContainerFactoryState); $definition = $resolution->aliasDefinition(); if ($definition !== null) { - $state->addAlias($definition->abstractService()->getName(), $definition->concreteService()->getName()); + $state->addAlias($definition->abstractService()->name(), $definition->concreteService()->name()); } } protected function handleServiceDelegateDefinition(ContainerFactoryState $state, ServiceDelegateDefinition $definition) : void { assert($state instanceof IlluminateContainerFactoryState); - $reflectionMethod = new \ReflectionMethod($definition->delegateType()->getName(), $definition->delegateMethod()); + $reflectionMethod = new \ReflectionMethod($definition->delegateType()->name(), $definition->delegateMethod()); if ($reflectionMethod->isStatic()) { $state->addStaticDelegate( - $definition->serviceType()->getName(), - $definition->delegateType()->getName(), + $definition->serviceType()->name(), + $definition->delegateType()->name(), $definition->delegateMethod() ); } else { $state->addInstanceDelegate( - $definition->serviceType()->getName(), - $definition->delegateType()->getName(), + $definition->serviceType()->name(), + $definition->delegateType()->name(), $definition->delegateMethod() ); } @@ -88,13 +88,13 @@ protected function handleServiceDelegateDefinition(ContainerFactoryState $state, protected function handleServicePrepareDefinition(ContainerFactoryState $state, ServicePrepareDefinition $definition) : void { assert($state instanceof IlluminateContainerFactoryState); - $state->addServicePrepare($definition->service()->getName(), $definition->methodName()); + $state->addServicePrepare($definition->service()->name(), $definition->methodName()); } protected function handleInjectDefinition(ContainerFactoryState $state, InjectDefinition $definition) : void { assert($state instanceof IlluminateContainerFactoryState); $state->addMethodInject( - $definition->class()->getName(), + $definition->class()->name(), $definition->methodName(), $definition->parameterName(), $this->injectDefinitionValue($definition) @@ -118,7 +118,7 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil } $container->singleton( $service, - static fn(Container $container) => $container->call([$target, $delegateInfo['delegateMethod']]) + static fn(Container $container) : object => $container->call([$target, $delegateInfo['delegateMethod']]) ); } @@ -148,16 +148,17 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil foreach ($state->methodInject() as $service => $methods) { foreach ($methods as $method => $params) { if ($method === '__construct') { + /** @var mixed $value */ foreach ($params as $param => $value) { if ($value instanceof ContainerReference) { $container->when($service) - ->needs($value->type->getName()) + ->needs($value->type->name()) ->give($value->name); } elseif ($value instanceof ServiceCollectorReference) { if ($value->collectionType === arrayType()) { $paramIdentifier = sprintf('$%s', $param); } else { - $paramIdentifier = $value->collectionType->getName(); + $paramIdentifier = $value->collectionType->name(); } $container->when($service) @@ -165,12 +166,12 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil ->give(function() use($state, $container, $value, $service): mixed { $values = []; foreach ($state->containerDefinition->serviceDefinitions() as $serviceDefinition) { - if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->getName() === $service) { + if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->name() === $service) { continue; } - if (is_a($serviceDefinition->type()->getName(), $value->valueType->getName(), true)) { - $values[] = $container->get($serviceDefinition->type()->getName()); + if (is_a($serviceDefinition->type()->name(), $value->valueType->name(), true)) { + $values[] = $container->get($serviceDefinition->type()->name()); } } return $value->listOf->toCollection($values); @@ -178,7 +179,7 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil } else { $container->when($service) ->needs(sprintf('$%s', $param)) - ->give($value); + ->give(static fn() : mixed => $value); } } } @@ -205,31 +206,39 @@ public function backingContainer() : Container { } public function make(string $classType, AutowireableParameterSet $parameters = null) : object { - $params = []; - if ($parameters !== null) { - foreach ($parameters as $parameter) { - $value = $parameter->value(); - if ($parameter->isServiceIdentifier()) { - $value = $this->state->container->get($value->getName()); - } - $params[$parameter->name()] = $value; - } - } - return $this->state->container->make($classType, $params); + $object = $this->state->container->make($classType, $this->resolvedParameters($parameters)); + assert($object instanceof $classType); + return $object; } public function invoke(callable $callable, AutowireableParameterSet $parameters = null) : mixed { + return $this->state->container->call($callable, $this->resolvedParameters($parameters)); + } + + /** + * @return array + */ + private function resolvedParameters(?AutowireableParameterSet $parameters) : array { + /** @var array $params */ $params = []; if ($parameters !== null) { foreach ($parameters as $parameter) { - $value = $parameter->value(); if ($parameter->isServiceIdentifier()) { - $value = $this->state->container->get($value->getName()); + $parameterValue = $parameter->value(); + assert($parameterValue instanceof ObjectType); + + /** @psalm-var mixed $value */ + $value = $this->state->container->get($parameterValue->name()); + } else { + /** @psalm-var mixed $value */ + $value = $parameter->value(); } + $params[$parameter->name()] = $value; } } - return $this->state->container->call($callable, $params); + + return $params; } public function get(string $id) { diff --git a/src/ContainerFactory/IlluminateContainerFactoryState.php b/src/ContainerFactory/IlluminateContainerFactoryState.php index 03a6809..b391b05 100644 --- a/src/ContainerFactory/IlluminateContainerFactoryState.php +++ b/src/ContainerFactory/IlluminateContainerFactoryState.php @@ -18,12 +18,12 @@ final class IlluminateContainerFactoryState implements ContainerFactoryState { private array $delegates = []; /** - * @var array + * @var list */ private array $concreteServices = []; /** - * @var array + * @var list */ private array $abstractServices = []; @@ -57,6 +57,12 @@ public function addStaticDelegate(string $service, string $delegate, string $met ]; } + /** + * @param class-string $service + * @param class-string $delegate + * @param non-empty-string $method + * @return void + */ public function addInstanceDelegate(string $service, string $delegate, string $method) : void { $this->delegates[$service] = [ 'delegateType' => $delegate, @@ -65,26 +71,50 @@ public function addInstanceDelegate(string $service, string $delegate, string $m ]; } + /** + * @param class-string $service + * @return void + */ public function addAbstractService(string $service) : void { $this->abstractServices[] = $service; } + /** + * @param class-string $service + * @return void + */ public function addConcreteService(string $service) : void { $this->concreteServices[] = $service; } + /** + * @param class-string $service + * @param non-empty-string $name + * @return void + */ public function addNamedService(string $service, string $name) : void { $this->namedServices[$service] = $name; } + /** + * @param class-string $abstract + * @param class-string $concrete + * @return void + */ public function addAlias(string $abstract, string $concrete) : void { $this->aliases[$abstract] = $concrete; } + /** + * @return list + */ public function abstractServices() : array { return $this->abstractServices; } + /** + * @return list + */ public function concreteServices() : array { return $this->concreteServices; } diff --git a/src/ContainerFactory/ListOf.php b/src/ContainerFactory/ListOf.php index 7e4cf65..ce4f12e 100644 --- a/src/ContainerFactory/ListOf.php +++ b/src/ContainerFactory/ListOf.php @@ -5,6 +5,7 @@ use Cspray\Typiphy\ObjectType; /** + * @template ServiceType of object * @template CollectionType */ interface ListOf { @@ -12,7 +13,7 @@ interface ListOf { public function type() : ObjectType; /**' - * @param list $servicesOfType + * @psalm-param list $servicesOfType * @return CollectionType */ public function toCollection(array $servicesOfType) : mixed; diff --git a/src/ContainerFactory/ListOfAsArray.php b/src/ContainerFactory/ListOfAsArray.php index bec22b0..ee25dac 100644 --- a/src/ContainerFactory/ListOfAsArray.php +++ b/src/ContainerFactory/ListOfAsArray.php @@ -6,8 +6,8 @@ use function Cspray\Typiphy\objectType; /** - * @template ItemType - * @implements ListOf> + * @template ItemType of object + * @implements ListOf> */ final class ListOfAsArray implements ListOf { @@ -23,10 +23,6 @@ public function type() : ObjectType { return objectType($this->type); } - /** - * @param list $servicesOfType - * @return list - */ public function toCollection(array $servicesOfType) : array { return $servicesOfType; } diff --git a/src/ContainerFactory/PhpDiContainerFactory.php b/src/ContainerFactory/PhpDiContainerFactory.php index 36860e9..8148b02 100644 --- a/src/ContainerFactory/PhpDiContainerFactory.php +++ b/src/ContainerFactory/PhpDiContainerFactory.php @@ -18,6 +18,8 @@ use Cspray\AnnotatedContainer\Exception\ServiceNotFound; use Cspray\Typiphy\ObjectType; use DI\ContainerBuilder; +use DI\Definition\Helper\AutowireDefinitionHelper; +use DI\Definition\Reference; use function Cspray\Typiphy\objectType; use function DI\decorate; use function DI\get; @@ -42,14 +44,14 @@ protected function containerFactoryState(ContainerDefinition $containerDefinitio protected function handleServiceDefinition(ContainerFactoryState $state, ServiceDefinition $definition) : void { assert($state instanceof PhpDiContainerFactoryState); - $serviceType = $definition->type()->getName(); + $serviceType = $definition->type()->name(); $state->addService($serviceType); $state->autowireService($serviceType); $key = $serviceType; $name = $definition->name(); if ($name !== null) { $state->addService($name); - $state->referenceService($name, $definition->type()->getName()); + $state->referenceService($name, $definition->type()->name()); $key = $name; } $state->setServiceKey($serviceType, $key); @@ -59,31 +61,36 @@ protected function handleAliasDefinition(ContainerFactoryState $state, AliasDefi assert($state instanceof PhpDiContainerFactoryState); $aliasDefinition = $resolution->aliasDefinition(); if ($aliasDefinition !== null) { + // We know that $abstractService can't be null here because AliasDefinitions are inferred from those types + // that are available for resolution after all definitions have been provided. The AliasDefinition couldn't + // exist if there wasn't a corresponding abstract service. + $abstractService = $state->serviceKey($aliasDefinition->abstractService()->name()); + assert($abstractService !== null); $state->referenceService( - $state->serviceKey($aliasDefinition->abstractService()->getName()), - $aliasDefinition->concreteService()->getName() + $abstractService, + $aliasDefinition->concreteService()->name() ); } } public function handleServiceDelegateDefinition(ContainerFactoryState $state, ServiceDelegateDefinition $definition) : void { assert($state instanceof PhpDiContainerFactoryState); - $serviceName = $definition->serviceType()->getName(); - $state->factoryService($serviceName, static fn(Container $container) => $container->call( - [$definition->delegateType()->getName(), $definition->delegateMethod()] + $serviceName = $definition->serviceType()->name(); + $state->factoryService($serviceName, static fn(Container $container) : mixed => $container->call( + [$definition->delegateType()->name(), $definition->delegateMethod()] )); } public function handleServicePrepareDefinition(ContainerFactoryState $state, ServicePrepareDefinition $definition) : void { assert($state instanceof PhpDiContainerFactoryState); - $state->addServicePrepare($definition->service()->getName(), $definition->methodName()); + $state->addServicePrepare($definition->service()->name(), $definition->methodName()); } public function handleInjectDefinition(ContainerFactoryState $state, InjectDefinition $definition) : void { assert($state instanceof PhpDiContainerFactoryState); $state->addMethodInject( - $definition->class()->getName(), + $definition->class()->name(), $definition->methodName(), $definition->parameterName(), $this->injectDefinitionValue($definition) @@ -97,10 +104,13 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil $definitions = $state->definitions(); foreach ($state->methodInject() as $service => $methods) { + $serviceDefinition = $definitions[$service]; + assert($serviceDefinition instanceof AutowireDefinitionHelper); foreach ($methods as $method => $params) { if ($method === '__construct') { + /** @var mixed $value */ foreach ($params as $param => $value) { - $definitions[$service]->constructorParameter($param, $value); + $serviceDefinition->constructorParameter($param, $value); } } } @@ -133,10 +143,13 @@ public function __construct( } public function make(string $classType, AutowireableParameterSet $parameters = null) : object { - return $this->container->make( + $object = $this->container->make( $classType, $this->convertAutowireableParameterSet($parameters) ); + assert($object instanceof $classType); + + return $object; } public function get(string $id) { @@ -161,12 +174,23 @@ public function invoke(callable $callable, AutowireableParameterSet $parameters ); } + /** + * @param AutowireableParameterSet|null $parameters + * @return array + */ private function convertAutowireableParameterSet(AutowireableParameterSet $parameters = null) : array { + /** @var array $params */ $params = []; if (!is_null($parameters)) { - /** @var AutowireableParameter $parameter */ foreach ($parameters as $parameter) { - $params[$parameter->name()] = $parameter->isServiceIdentifier() ? get($parameter->value()->getName()) : $parameter->value(); + /** @var Reference|mixed $value */ + $value = $parameter->value(); + if ($parameter->isServiceIdentifier()) { + assert($value instanceof ObjectType); + $value = get($value->name()); + } + + $params[$parameter->name()] = $value; } } return $params; diff --git a/src/ContainerFactory/PhpDiContainerFactoryState.php b/src/ContainerFactory/PhpDiContainerFactoryState.php index 6485709..887d9df 100644 --- a/src/ContainerFactory/PhpDiContainerFactoryState.php +++ b/src/ContainerFactory/PhpDiContainerFactoryState.php @@ -2,10 +2,13 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; +use Closure; use Cspray\AnnotatedContainer\Autowire\AutowireableFactory; use Cspray\AnnotatedContainer\Autowire\AutowireableInvoker; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use DI\Container; +use DI\Definition\Helper\AutowireDefinitionHelper; +use DI\Definition\Helper\DefinitionHelper; use DI\Definition\Reference; use Cspray\AnnotatedContainer\Profiles; use function DI\autowire; @@ -18,10 +21,19 @@ final class PhpDiContainerFactoryState implements ContainerFactoryState { HasMethodInjectState::addMethodInject as addResolvedMethodInject; } + /** + * @var list + */ private array $services = []; + /** + * @var array + */ private array $definitions = []; + /** + * @var array + */ private array $serviceKeys = []; public function __construct( @@ -46,20 +58,23 @@ public function addMethodInject(string $class, string $method, string $param, mi if ($value instanceof ServiceCollectorReference) { $values = []; foreach ($this->containerDefinition->serviceDefinitions() as $serviceDefinition) { - if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->getName() === $class) { + if ($serviceDefinition->isAbstract() || $serviceDefinition->type()->name() === $class) { continue; } - if (is_a($serviceDefinition->type()->getName(), $value->valueType->getName(), true)) { - $values[] = get($serviceDefinition->type()->getName()); + if (is_a($serviceDefinition->type()->name(), $value->valueType->name(), true)) { + $values[] = get($serviceDefinition->type()->name()); } } - $value = factory(function(Container $container) use ($values, $value) { + $value = factory(function(Container $container) use ($values, $value) : mixed { + /** @var list $resolvedValues */ $resolvedValues = []; /** @var Reference $val */ foreach ($values as $val) { - $resolvedValues[] = $val->resolve($container); + $resolvedVal = $val->resolve($container); + assert(is_object($resolvedVal)); + $resolvedValues[] = $resolvedVal; } return $value->listOf->toCollection($resolvedValues); }); @@ -68,34 +83,67 @@ public function addMethodInject(string $class, string $method, string $param, mi $this->addResolvedMethodInject($class, $method, $param, $value); } + /** + * @return array + */ public function definitions() : array { return $this->definitions; } + /** + * @return list + */ public function services() : array { return $this->services; } + /** + * @param non-empty-string $service + * @return void + */ public function addService(string $service) : void { $this->services[] = $service; } + /** + * @param class-string $service + * @return void + */ public function autowireService(string $service) : void { $this->definitions[$service] = autowire(); } + /** + * @param non-empty-string $name + * @param non-empty-string $service + * @return void + */ public function referenceService(string $name, string $service) : void { $this->definitions[$name] = get($service); } - public function factoryService(string $name, \Closure $closure) : void { + /** + * @param non-empty-string $name + * @param Closure $closure + * @return void + */ + public function factoryService(string $name, Closure $closure) : void { $this->definitions[$name] = $closure; } + /** + * @param class-string $serviceType + * @param non-empty-string $key + * @return void + */ public function setServiceKey(string $serviceType, string $key) : void { $this->serviceKeys[$serviceType] = $key; } + /** + * @param class-string $serviceType + * @return non-empty-string|null + */ public function serviceKey(string $serviceType) : ?string { return $this->serviceKeys[$serviceType] ?? null; } diff --git a/src/Definition/InjectDefinitionBuilder.php b/src/Definition/InjectDefinitionBuilder.php index 81010fe..9687849 100644 --- a/src/Definition/InjectDefinitionBuilder.php +++ b/src/Definition/InjectDefinitionBuilder.php @@ -12,7 +12,13 @@ final class InjectDefinitionBuilder { private ObjectType $service; + /** + * @var non-empty-string|null + */ private ?string $method = null; + /** + * @var non-empty-string|null + */ private ?string $paramName = null; private Type|TypeUnion|TypeIntersect $type; private mixed $value; @@ -23,6 +29,10 @@ final class InjectDefinitionBuilder { * @var list */ private array $profiles = []; + + /** + * @var non-empty-string|null + */ private ?string $store = null; private function __construct() { @@ -34,6 +44,12 @@ public static function forService(ObjectType $type) : self { return $instance; } + /** + * @param non-empty-string $method + * @param Type|TypeUnion|TypeIntersect $type + * @param non-empty-string $paramName + * @return $this + */ public function withMethod(string $method, Type|TypeUnion|TypeIntersect $type, string $paramName) : self { $instance = clone $this; $instance->method = $method; @@ -62,6 +78,10 @@ public function withProfiles(string $profile, string...$additionalProfiles) : se return $instance; } + /** + * @param non-empty-string $storeName + * @return $this + */ public function withStore(string $storeName) : self { $instance = clone $this; $instance->store = $storeName; @@ -75,7 +95,7 @@ public function withAttribute(InjectAttribute $injectAttribute) : self { } public function build() : InjectDefinition { - if (!isset($this->method)) { + if (!isset($this->method) || !isset($this->paramName)) { throw InvalidInjectDefinition::fromMissingMethod(); } elseif (!$this->isValueCalled) { throw InvalidInjectDefinition::fromMissingValue(); @@ -90,7 +110,9 @@ public function build() : InjectDefinition { /** * @param Type|TypeUnion|TypeIntersect $type - * @param string|null $store + * @param non-empty-string $methodName + * @param non-empty-string $paramName + * @param non-empty-string|null $store * @param list $profiles */ public function __construct( diff --git a/src/Definition/ProfilesAwareContainerDefinition.php b/src/Definition/ProfilesAwareContainerDefinition.php index 666fee0..52c1f36 100644 --- a/src/Definition/ProfilesAwareContainerDefinition.php +++ b/src/Definition/ProfilesAwareContainerDefinition.php @@ -30,12 +30,12 @@ public function aliasDefinitions() : array { foreach ($this->containerDefinition->aliasDefinitions() as $aliasDefinition) { $abstract = $this->getServiceDefinition($aliasDefinition->abstractService()); if ($abstract === null) { - throw InvalidAlias::fromAbstractNotService($aliasDefinition->abstractService()->getName()); + throw InvalidAlias::fromAbstractNotService($aliasDefinition->abstractService()->name()); } $concrete = $this->getServiceDefinition($aliasDefinition->concreteService()); if ($concrete === null) { - throw InvalidAlias::fromConcreteNotService($aliasDefinition->concreteService()->getName()); + throw InvalidAlias::fromConcreteNotService($aliasDefinition->concreteService()->name()); } if ($this->hasActiveProfile($abstract) && $this->hasActiveProfile($concrete)) { diff --git a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php index 743756d..f307b03 100644 --- a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php +++ b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php @@ -3,6 +3,7 @@ namespace Cspray\AnnotatedContainer\Definition\Serializer; use Cspray\AnnotatedContainer\AnnotatedContainerVersion; +use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; @@ -10,6 +11,7 @@ use Cspray\AnnotatedContainer\Definition\InjectDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinitionBuilder; +use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition; use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinitionBuilder; use Cspray\AnnotatedContainer\Exception\InvalidSerializedContainerDefinition; use Cspray\AnnotatedContainer\Exception\InvalidInjectDefinition; @@ -21,6 +23,7 @@ use DOMXPath; use Exception as PhpException; use function Cspray\Typiphy\objectType; +use function PHPUnit\Framework\assertSame; /** * @internal @@ -51,7 +54,11 @@ public function serialize(ContainerDefinition $containerDefinition) : Serialized $this->addServiceDelegateDefinitionsToDom($root, $containerDefinition); $this->addInjectDefinitionsToDom($root, $containerDefinition); - return SerializedContainerDefinition::fromString($dom->saveXML()); + // if we get to this point then we know the XML document will contain _something_ + $xml = $dom->saveXML(); + assert($xml !== false && $xml !== ''); + + return SerializedContainerDefinition::fromString($xml); } private function addServiceDefinitionsToDom(DOMElement $root, ContainerDefinition $containerDefinition) : void { @@ -71,7 +78,7 @@ private function addServiceDefinitionsToDom(DOMElement $root, ContainerDefinitio } $serviceDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'type', $serviceDefinition->type()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'type', $serviceDefinition->type()->name()) ); $serviceDefinitionNode->appendChild( $nameNode = $dom->createElementNS(self::XML_SCHEMA, 'name') @@ -120,10 +127,10 @@ private function addAliasDefinitionsToDom(DOMElement $root, ContainerDefinition ); $aliasDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'abstractService', $aliasDefinition->abstractService()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'abstractService', $aliasDefinition->abstractService()->name()) ); $aliasDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'concreteService', $aliasDefinition->concreteService()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'concreteService', $aliasDefinition->concreteService()->name()) ); } } @@ -141,7 +148,7 @@ private function addServicePrepareDefinitionsToDom(DOMElement $root, ContainerDe ); $servicePrepareDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'type', $servicePrepareDefinition->service()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'type', $servicePrepareDefinition->service()->name()) ); $servicePrepareDefinitionNode->appendChild( @@ -172,10 +179,10 @@ private function addServiceDelegateDefinitionsToDom(DOMElement $root, ContainerD ); $serviceDelegateDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'service', $serviceDelegateDefinition->serviceType()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'service', $serviceDelegateDefinition->serviceType()->name()) ); $serviceDelegateDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'delegateType', $serviceDelegateDefinition->delegateType()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'delegateType', $serviceDelegateDefinition->delegateType()->name()) ); $serviceDelegateDefinitionNode->appendChild( $dom->createElementNS(self::XML_SCHEMA, 'delegateMethod', $serviceDelegateDefinition->delegateMethod()) @@ -214,7 +221,7 @@ private function addInjectDefinitionsToDom(DOMElement $root, ContainerDefinition $this->addMethodParameterInjectDefinitionToDom($injectDefinitionNode, $injectDefinition); $injectDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'valueType', base64_encode($injectDefinition->type()->getName())) + $dom->createElementNS(self::XML_SCHEMA, 'valueType', base64_encode($injectDefinition->type()->name())) ); $injectDefinitionNode->appendChild( @@ -259,11 +266,10 @@ private function addMethodParameterInjectDefinitionToDom(DOMElement $root, Injec $dom = $root->ownerDocument; $root->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'class', $injectDefinition->class()->getName()) + $dom->createElementNS(self::XML_SCHEMA, 'class', $injectDefinition->class()->name()) ); $methodName = $injectDefinition->methodName(); - assert($methodName !== null); $root->appendChild( $dom->createElementNS(self::XML_SCHEMA, 'method', $methodName) ); @@ -276,8 +282,10 @@ private function addMethodParameterInjectDefinitionToDom(DOMElement $root, Injec public function deserialize(SerializedContainerDefinition $serializedContainerDefinition) : ContainerDefinition { $dom = new DOMDocument(encoding: 'UTF-8'); - // Many assert() calls later on on values provided in the serialized container definition are made - // because they are being asserted as part of the XML passing the container definition schema. + // The assert() calls and docblock annotations in other methods, on values provided in the serialized container + // definition are made because they are being asserted as part of the XML passing the container definition + // schema below. If the code executes beyond the call to $dom->schemaValidate() then we can assume the stuff + // covered by the schema definition is covered and we don't need to cover it again. libxml_use_internal_errors(true); try { @@ -315,12 +323,13 @@ private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $buil assert($serviceDefinitions instanceof DOMNodeList); foreach ($serviceDefinitions as $serviceDefinition) { - $type = objectType( - $xpath->query('cd:type/text()', $serviceDefinition)[0]->nodeValue - ); + $serviceType = $xpath->query('cd:type/text()', $serviceDefinition)[0]->nodeValue; + assert(class_exists($serviceType)); + + $type = objectType($serviceType); $concreteOrAbstract = $xpath->query('cd:concreteOrAbstract/text()', $serviceDefinition)[0]->nodeValue; - $isPrimary = $xpath->query('@isPrimary', $serviceDefinition)[0]?->value; + $isPrimary = $xpath->query('@isPrimary', $serviceDefinition)[0]?->nodeValue; if ($concreteOrAbstract === 'Concrete') { $serviceBuilder = ServiceDefinitionBuilder::forConcrete($type, $isPrimary === 'true'); } else { @@ -329,17 +338,22 @@ private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $buil $name = $xpath->query('cd:name/text()', $serviceDefinition)[0]?->nodeValue; if ($name !== null) { + // We make several assertions that a name cannot be an empty string before a container is serialized and + // a blank name should not be possible + assert($name !== ''); $serviceBuilder = $serviceBuilder->withName($name); } $profiles = $xpath->query('cd:profiles/cd:profile', $serviceDefinition); $serviceProfiles = []; foreach ($profiles as $profile) { - assert($profile instanceof DOMElement); $value = $profile->nodeValue; - assert($value !== ''); + // The profileString type ensures that there is a value listed greater than 1 + assert($value !== null && $value !== ''); $serviceProfiles[] = $value; } + // The profilesType ensures there's at least 1 profile, additionally definitions are never assigned empty profiles + assert($serviceProfiles !== []); $serviceBuilder = $serviceBuilder->withProfiles($serviceProfiles); @@ -361,6 +375,10 @@ private function addAliasDefinitionsToBuilder(ContainerDefinitionBuilder $builde foreach ($aliasDefinitions as $aliasDefinition) { $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($concrete)); + $builder = $builder->withAliasDefinition( AliasDefinitionBuilder::forAbstract(objectType($abstract))->withConcrete(objectType($concrete))->build() ); @@ -377,13 +395,16 @@ private function addServicePrepareDefinitionsToBuilder(ContainerDefinitionBuilde $service = $xpath->query('cd:type/text()', $prepareDefinition)[0]->nodeValue; $method = $xpath->query('cd:method/text()', $prepareDefinition)[0]->nodeValue; + assert(class_exists($service)); assert($method !== null && $method !== ''); $servicePrepareBuilder = ServicePrepareDefinitionBuilder::forMethod(objectType($service), $method); $attr = $xpath->query('cd:attribute/text()', $prepareDefinition)[0]?->nodeValue; if ($attr !== null) { - $servicePrepareBuilder = $servicePrepareBuilder->withAttribute(unserialize(base64_decode($attr))); + $attrObject = unserialize(base64_decode($attr)); + assert($attrObject instanceof ServicePrepareAttribute); + $servicePrepareBuilder = $servicePrepareBuilder->withAttribute($attrObject); } $builder = $builder->withServicePrepareDefinition($servicePrepareBuilder->build()); @@ -401,6 +422,8 @@ private function addServiceDelegateDefinitionsToBuilder(ContainerDefinitionBuild $delegateType = $xpath->query('cd:delegateType/text()', $delegateDefinition)[0]->nodeValue; $delegateMethod = $xpath->query('cd:delegateMethod/text()', $delegateDefinition)[0]->nodeValue; + assert(class_exists($service)); + assert(class_exists($delegateType)); assert($delegateMethod !== null && $delegateMethod !== ''); $serviceDelegateBuilder = ServiceDelegateDefinitionBuilder::forService(objectType($service)) @@ -427,13 +450,20 @@ private function addInjectDefinitionsToBuilder(ContainerDefinitionBuilder $build $attr = $xpath->query('cd:attribute/text()', $injectDefinition)[0]?->nodeValue; $profiles = $xpath->query('cd:profiles/cd:profile/text()', $injectDefinition); $encodedSerializedValue = $xpath->query('cd:value/text()', $injectDefinition)[0]->nodeValue; + $serializedValue = base64_decode($encodedSerializedValue); + /** @var mixed $value */ $value = unserialize($serializedValue); $valueType = $this->injectValueParser->convertStringToType(base64_decode($valueType)); $type = $xpath->query('cd:class/text()', $injectDefinition)[0]->nodeValue; $methodName = $xpath->query('cd:method/text()', $injectDefinition)[0]->nodeValue; $parameter = $xpath->query('cd:parameter/text()', $injectDefinition)[0]->nodeValue; + + assert(class_exists($type)); + assert($methodName !== null && $methodName !== ''); + assert($parameter !== null && $parameter !== ''); + $injectBuilder = InjectDefinitionBuilder::forService(objectType($type)) ->withMethod($methodName, $valueType, $parameter); @@ -442,13 +472,17 @@ private function addInjectDefinitionsToBuilder(ContainerDefinitionBuilder $build $injectProfiles = []; foreach ($profiles as $profile) { $value = $profile->nodeValue; - assert($value !== ''); + // The profileString type ensures that there is a value listed greater than 1 + assert($value !== null && $value !== ''); $injectProfiles[] = $value; } + // The profilesType ensures there's at least 1 profile, additionally definitions are never assigned empty profiles + assert($injectProfiles !== []); $injectBuilder = $injectBuilder->withProfiles(...$injectProfiles); if ($store !== null) { + assert($store !== ''); $injectBuilder = $injectBuilder->withStore($store); } diff --git a/src/Definition/ServicePrepareDefinition.php b/src/Definition/ServicePrepareDefinition.php index 3b6805a..27793a0 100644 --- a/src/Definition/ServicePrepareDefinition.php +++ b/src/Definition/ServicePrepareDefinition.php @@ -23,7 +23,7 @@ public function service() : ObjectType; /** * The method that should be invoked on the Service. * - * @return string + * @return non-empty-string */ public function methodName() : string; diff --git a/src/Exception/InvalidAutowireParameter.php b/src/Exception/InvalidAutowireParameter.php index 04fd0d9..98e2d71 100644 --- a/src/Exception/InvalidAutowireParameter.php +++ b/src/Exception/InvalidAutowireParameter.php @@ -8,10 +8,6 @@ public static function fromParameterWithMissingName() : self { return new self('A parameter name must have a non-empty value.'); } - public static function fromParameterWithMissingValue() : self { - return new self('A parameter name must have a non-empty value.'); - } - public static function fromParameterAlreadyAddedToSet(string $parameter) : self { $message = sprintf( 'A parameter named "%s" has already been added to this set.', diff --git a/src/Exception/InvalidThirdPartyInitializer.php b/src/Exception/InvalidThirdPartyInitializer.php index 66a8d2e..8130300 100644 --- a/src/Exception/InvalidThirdPartyInitializer.php +++ b/src/Exception/InvalidThirdPartyInitializer.php @@ -7,6 +7,18 @@ final class InvalidThirdPartyInitializer extends Exception { + public static function fromComposerExtraAnnotatedContainerConfigNotArray() : self { + return new self('The value listed in composer.json extra.$annotatedContainer MUST be an array.'); + } + + public static function fromComposerExtraAnnotatedContainerConfigNoInitializers() : self { + return new self('The value listed in composer.json extra.$annotatedContainer MUST have a key "initializers" that holds a list of ThirdPartyInitializers to use.'); + } + + public static function fromComposerExtraAnnotatedContainerConfigInitializersNotArray() : self { + return new self('The value listed in composer.json extra.$annotatedContainer.initializers MUST be a list of ThirdPartyInitializers to use.'); + } + public static function fromConfiguredProviderNotClass(string $path, mixed $initializerProvider) : self { return new self(sprintf( 'Values listed in %s extra.$annotatedContainer.initializers MUST be a class-string that is an instance of ' . diff --git a/src/Function/auto-wired-parameters.php b/src/Function/auto-wired-parameters.php index c4802be..1891d9b 100644 --- a/src/Function/auto-wired-parameters.php +++ b/src/Function/auto-wired-parameters.php @@ -63,23 +63,30 @@ public function count() : int { * Specify a parameter on a method, by $name, to have a service injected from the Container; if the $objectType is an * abstract service its concrete alias will be resolved and used. * - * @param string $name + * @param non-empty-string $name * @param ObjectType $service * @return AutowireableParameter * @throws InvalidAutowireParameter */ function serviceParam(string $name, ObjectType $service) : AutowireableParameter { if (empty($name)) { - throw InvalidAutowireParameter::fromParameterWithMissingValue(); + throw InvalidAutowireParameter::fromParameterWithMissingName(); } return new class($name, $service) implements AutowireableParameter { + /** + * @param non-empty-string $name + * @param ObjectType $value + */ public function __construct( private readonly string $name, private readonly ObjectType $value ) { } + /** + * @return non-empty-string + */ public function name() : string { return $this->name; } @@ -98,7 +105,7 @@ public function isServiceIdentifier() : bool { * Inject a parameter on a method, by $name, to have a value injected directly; whatever is passed to $value will be * passed to the parameter. * - * @param string $name + * @param non-empty-string $name * @return AutowireableParameter * @throws InvalidAutowireParameter */ @@ -108,12 +115,19 @@ function rawParam(string $name, mixed $value) : AutowireableParameter { } return new class($name, $value) implements AutowireableParameter { + /** + * @param non-empty-string $name + * @param mixed $value + */ public function __construct( private readonly string $name, private readonly mixed $value ) { } + /** + * @return non-empty-string + */ public function name() : string { return $this->name; } diff --git a/src/Function/definitions.php b/src/Function/definitions.php index ee0ced8..20a20c6 100644 --- a/src/Function/definitions.php +++ b/src/Function/definitions.php @@ -29,7 +29,7 @@ * @throws ReflectionException */ function service(ObjectType $type, ?string $name = null, array $profiles = [], bool $isPrimary = false) : ServiceDefinition { - $typeName = $type->getName(); + $typeName = $type->name(); $reflection = new ReflectionClass($typeName); $methodArgs = [$type]; $method = $reflection->isAbstract() || $reflection->isInterface() ? 'forAbstract' : 'forConcrete'; diff --git a/src/Internal/SerializerInjectValueParser.php b/src/Internal/SerializerInjectValueParser.php index ca9032c..164353c 100644 --- a/src/Internal/SerializerInjectValueParser.php +++ b/src/Internal/SerializerInjectValueParser.php @@ -25,10 +25,15 @@ */ final class SerializerInjectValueParser { + /** + * @param non-empty-string|class-string $rawType + * @return Type|TypeUnion|TypeIntersect + */ public function convertStringToType(string $rawType) : Type|TypeUnion|TypeIntersect { if (str_contains($rawType, '|')) { $types = []; foreach (explode('|', $rawType) as $unionType) { + assert($unionType !== ''); $types[] = $this->convertStringToType($unionType); } /** @psalm-var non-empty-list $types */ @@ -36,6 +41,7 @@ public function convertStringToType(string $rawType) : Type|TypeUnion|TypeInters } elseif (str_contains($rawType, '&')) { $types = []; foreach (explode('&', $rawType) as $intersectType) { + assert(class_exists($intersectType)); $parsedType = $this->convertStringToType($intersectType); assert($parsedType instanceof ObjectType); $types[] = $parsedType; @@ -53,8 +59,13 @@ public function convertStringToType(string $rawType) : Type|TypeUnion|TypeInters 'null', 'NULL' => nullType(), 'void' => voidType(), 'callable' => callableType(), - default => objectType($rawType) + default => null }; + + if ($type === null) { + assert(class_exists($rawType)); + $type = objectType($rawType); + } } return $type; diff --git a/src/LogicalConstraint/Check/DuplicateServiceDelegate.php b/src/LogicalConstraint/Check/DuplicateServiceDelegate.php index c336bbc..85dd55a 100644 --- a/src/LogicalConstraint/Check/DuplicateServiceDelegate.php +++ b/src/LogicalConstraint/Check/DuplicateServiceDelegate.php @@ -21,8 +21,8 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P $delegateMap = []; foreach ($containerDefinition->serviceDelegateDefinitions() as $definition) { - $service = $definition->serviceType()->getName(); - $method = sprintf('%s::%s', $definition->delegateType()->getName(), $definition->delegateMethod()); + $service = $definition->serviceType()->name(); + $method = sprintf('%s::%s', $definition->delegateType()->name(), $definition->delegateMethod()); $delegateMap[$service] ??= []; $attribute = $definition->attribute(); if ($attribute !== null) { diff --git a/src/LogicalConstraint/Check/DuplicateServiceName.php b/src/LogicalConstraint/Check/DuplicateServiceName.php index 2a23861..d3b97e8 100644 --- a/src/LogicalConstraint/Check/DuplicateServiceName.php +++ b/src/LogicalConstraint/Check/DuplicateServiceName.php @@ -25,7 +25,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P } $namedServiceMap[$name] ??= []; - $namedServiceMap[$name][] = $definition->type()->getName(); + $namedServiceMap[$name][] = $definition->type()->name(); } foreach ($namedServiceMap as $name => $services) { diff --git a/src/LogicalConstraint/Check/DuplicateServicePrepare.php b/src/LogicalConstraint/Check/DuplicateServicePrepare.php index 669151f..3d3e3e8 100644 --- a/src/LogicalConstraint/Check/DuplicateServicePrepare.php +++ b/src/LogicalConstraint/Check/DuplicateServicePrepare.php @@ -20,7 +20,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P foreach ($containerDefinition->servicePrepareDefinitions() as $prepareDefinition) { $classMethod = sprintf( '%s::%s', - $prepareDefinition->service()->getName(), + $prepareDefinition->service()->name(), $prepareDefinition->methodName() ); diff --git a/src/LogicalConstraint/Check/DuplicateServiceType.php b/src/LogicalConstraint/Check/DuplicateServiceType.php index efb7972..d4bea3c 100644 --- a/src/LogicalConstraint/Check/DuplicateServiceType.php +++ b/src/LogicalConstraint/Check/DuplicateServiceType.php @@ -20,7 +20,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P $serviceTypeMap = []; foreach ($containerDefinition->serviceDefinitions() as $definition) { - $type = $definition->type()->getName(); + $type = $definition->type()->name(); $serviceTypeMap[$type] ??= []; $serviceTypeMap[$type][] = $definition->attribute(); } diff --git a/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php b/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php index 41c20d9..eec5f01 100644 --- a/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php +++ b/src/LogicalConstraint/Check/MultiplePrimaryForAbstractService.php @@ -18,12 +18,12 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P $abstractPrimaryMap = []; foreach ($this->getAbstractServices($containerDefinition) as $abstract) { - $abstractService = $abstract->type()->getName(); + $abstractService = $abstract->type()->name(); $abstractPrimaryMap[$abstractService] ??= []; $concreteServices = $this->getConcreteServicesInstanceOf($containerDefinition, $abstract); foreach ($concreteServices as $concrete) { if ($concrete->isPrimary()) { - $abstractPrimaryMap[$abstractService][] = $concrete->type()->getName() . PHP_EOL; + $abstractPrimaryMap[$abstractService][] = $concrete->type()->name() . PHP_EOL; } } } @@ -67,7 +67,7 @@ private function getAbstractServices(ContainerDefinition $containerDefinition) : private function getConcreteServicesInstanceOf(ContainerDefinition $containerDefinition, ServiceDefinition $serviceDefinition) : Generator { foreach ($containerDefinition->serviceDefinitions() as $service) { if ($service->isConcrete()) { - if (is_subclass_of($service->type()->getName(), $serviceDefinition->type()->getName())) { + if (is_subclass_of($service->type()->name(), $serviceDefinition->type()->name())) { yield $service; } } diff --git a/src/LogicalConstraint/Check/NonPublicServiceDelegate.php b/src/LogicalConstraint/Check/NonPublicServiceDelegate.php index 4d2546f..22751d1 100644 --- a/src/LogicalConstraint/Check/NonPublicServiceDelegate.php +++ b/src/LogicalConstraint/Check/NonPublicServiceDelegate.php @@ -15,7 +15,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P $violations = new LogicalConstraintViolationCollection(); foreach ($containerDefinition->serviceDelegateDefinitions() as $delegateDefinition) { - $reflection = new \ReflectionMethod(sprintf('%s::%s', $delegateDefinition->delegateType()->getName(), $delegateDefinition->delegateMethod())); + $reflection = new \ReflectionMethod(sprintf('%s::%s', $delegateDefinition->delegateType()->name(), $delegateDefinition->delegateMethod())); if ($reflection->isProtected() || $reflection->isPrivate()) { $protectedOrPrivate = $reflection->isProtected() ? 'protected' : 'private'; $violations->add( @@ -23,7 +23,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P sprintf( 'A %s method, %s::%s, is marked as a service delegate. Service delegates MUST be marked public.', $protectedOrPrivate, - $delegateDefinition->delegateType()->getName(), + $delegateDefinition->delegateType()->name(), $delegateDefinition->delegateMethod() ) ) diff --git a/src/LogicalConstraint/Check/NonPublicServicePrepare.php b/src/LogicalConstraint/Check/NonPublicServicePrepare.php index 54afcb6..17eb23e 100644 --- a/src/LogicalConstraint/Check/NonPublicServicePrepare.php +++ b/src/LogicalConstraint/Check/NonPublicServicePrepare.php @@ -15,7 +15,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P $violations = new LogicalConstraintViolationCollection(); foreach ($containerDefinition->servicePrepareDefinitions() as $prepareDefinition) { - $reflection = new \ReflectionMethod(sprintf('%s::%s', $prepareDefinition->service()->getName(), $prepareDefinition->methodName())); + $reflection = new \ReflectionMethod(sprintf('%s::%s', $prepareDefinition->service()->name(), $prepareDefinition->methodName())); if ($reflection->isPrivate() || $reflection->isProtected()) { $protectedOrPrivate = $reflection->isProtected() ? 'protected' : 'private'; $violations->add( @@ -23,7 +23,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P sprintf( 'A %s method, %s::%s, is marked as a service prepare. Service prepare methods MUST be marked public.', $protectedOrPrivate, - $prepareDefinition->service()->getName(), + $prepareDefinition->service()->name(), $prepareDefinition->methodName() ) ) diff --git a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php index de59592..cb2b723 100644 --- a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php +++ b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php @@ -101,7 +101,11 @@ private function parse( $consumer->serviceDelegateDefinitions = []; $consumer->injectDefinitions = []; $attributeTypes = array_map( - static fn(AttributeType $attributeType) => objectType($attributeType->value), + static function(AttributeType $attributeType) : ObjectType { + /** @var class-string $value */ + $value = $attributeType->value; + return objectType($value); + }, AttributeType::cases() ); $dirs = $containerDefinitionAnalysisOptions->scanDirectories(); @@ -153,7 +157,7 @@ private function addAnnotatedDefinitions( foreach ($consumer['serviceDelegateDefinitions'] as $serviceDelegateDefinition) { $serviceDef = $this->serviceDefinition($containerDefinitionBuilder, $serviceDelegateDefinition->serviceType()); if ($serviceDef === null) { - $reflection = new ReflectionClass($serviceDelegateDefinition->serviceType()->getName()); + $reflection = new ReflectionClass($serviceDelegateDefinition->serviceType()->name()); if ($reflection->isInterface() || $reflection->isAbstract()) { $serviceDef = ServiceDefinitionBuilder::forAbstract($serviceDelegateDefinition->serviceType())->build(); } else { @@ -167,7 +171,7 @@ private function addAnnotatedDefinitions( $concretePrepareDefinitions = array_filter($consumer['servicePrepareDefinitions'], function (ServicePrepareDefinition $prepareDef) use ($containerDefinitionBuilder) { $serviceDef = $this->serviceDefinition($containerDefinitionBuilder, $prepareDef->service()); if (is_null($serviceDef)) { - $exception = InvalidServicePrepare::fromClassNotService($prepareDef->service()->getName(), $prepareDef->methodName()); + $exception = InvalidServicePrepare::fromClassNotService($prepareDef->service()->name(), $prepareDef->methodName()); throw $exception; } return $serviceDef->isConcrete(); @@ -184,8 +188,8 @@ private function addAnnotatedDefinitions( foreach ($concretePrepareDefinitions as $concretePrepareDefinition) { $hasAbstractPrepare = false; foreach ($abstractPrepareDefinitions as $abstractPrepareDefinition) { - $concreteServiceName = $concretePrepareDefinition->service()->getName(); - $abstractServiceName = $abstractPrepareDefinition->service()->getName(); + $concreteServiceName = $concretePrepareDefinition->service()->name(); + $abstractServiceName = $abstractPrepareDefinition->service()->name(); if (is_subclass_of($concreteServiceName, $abstractServiceName)) { $hasAbstractPrepare = true; break; @@ -274,8 +278,8 @@ private function addAliasDefinitions(ContainerDefinitionBuilder $containerDefini foreach ($abstractTypes as $abstractType) { foreach ($concreteTypes as $concreteType) { - $abstractTypeString = $abstractType->getName(); - if (is_subclass_of($concreteType->getName(), $abstractTypeString)) { + $abstractTypeString = $abstractType->name(); + if (is_subclass_of($concreteType->name(), $abstractTypeString)) { $aliasDefinition = AliasDefinitionBuilder::forAbstract($abstractType) ->withConcrete($concreteType) ->build(); diff --git a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php b/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php index b868b4e..6de44f8 100644 --- a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php +++ b/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php @@ -57,7 +57,7 @@ final class AnnotatedTargetDefinitionConverter { * @return ServiceDefinition|ServicePrepareDefinition|ServiceDelegateDefinition|InjectDefinition */ public function convert(AnnotatedTarget $target) : ServiceDefinition|ServicePrepareDefinition|ServiceDelegateDefinition|InjectDefinition { - $attrInstance = $target->getAttributeInstance(); + $attrInstance = $target->attributeInstance(); if ($attrInstance instanceof ServiceAttribute) { return $this->buildServiceDefinition($target); } @@ -78,11 +78,11 @@ public function convert(AnnotatedTarget $target) : ServiceDefinition|ServicePrep } private function buildServiceDefinition(AnnotatedTarget $target) : ServiceDefinition { - $serviceType = objectType($target->getTargetReflection()->getName()); - /** @var Service $attribute */ - $attribute = $target->getAttributeInstance(); - $reflection = $target->getTargetReflection(); + $reflection = $target->targetReflection(); assert($reflection instanceof ReflectionClass); + $serviceType = objectType($reflection->getName()); + /** @var Service $attribute */ + $attribute = $target->attributeInstance(); if ($reflection->isInterface() || $reflection->isAbstract()) { $builder = ServiceDefinitionBuilder::forAbstract($serviceType); } else { @@ -105,11 +105,11 @@ private function buildServiceDefinition(AnnotatedTarget $target) : ServiceDefini } private function buildServiceDelegateDefinition(AnnotatedTarget $target) : ServiceDelegateDefinition { - $reflection = $target->getTargetReflection(); + $reflection = $target->targetReflection(); assert($reflection instanceof ReflectionMethod); $delegateType = $reflection->getDeclaringClass()->getName(); $delegateMethod = $reflection->getName(); - $attribute = $target->getAttributeInstance(); + $attribute = $target->attributeInstance(); assert($attribute instanceof ServiceDelegateAttribute); $service = $attribute->service(); @@ -143,11 +143,11 @@ private function buildServiceDelegateDefinition(AnnotatedTarget $target) : Servi } private function buildServicePrepareDefinition(AnnotatedTarget $target) : ServicePrepareDefinition { - $reflection = $target->getTargetReflection(); + $reflection = $target->targetReflection(); assert($reflection instanceof ReflectionMethod); $prepareType = $reflection->getDeclaringClass()->getName(); $method = $reflection->getName(); - $attribute = $target->getAttributeInstance(); + $attribute = $target->attributeInstance(); assert($attribute instanceof ServicePrepareAttribute); return ServicePrepareDefinitionBuilder::forMethod(objectType($prepareType), $method) @@ -160,7 +160,7 @@ private function buildInjectDefinition(AnnotatedTarget $target) : InjectDefiniti } private function buildMethodInjectDefinition(AnnotatedTarget $target) : InjectDefinition { - $targetReflection = $target->getTargetReflection(); + $targetReflection = $target->targetReflection(); assert($targetReflection instanceof \ReflectionParameter); $declaringClass = $targetReflection->getDeclaringClass(); assert(!is_null($declaringClass)); @@ -169,7 +169,7 @@ private function buildMethodInjectDefinition(AnnotatedTarget $target) : InjectDe $method = $targetReflection->getDeclaringFunction()->getName(); $param = $targetReflection->getName(); $paramType = $this->convertReflectionType($targetReflection->getType()); - $attributeInstance = $target->getAttributeInstance(); + $attributeInstance = $target->attributeInstance(); assert($attributeInstance instanceof InjectAttribute); $builder = InjectDefinitionBuilder::forService($serviceType)->withMethod($method, $paramType, $param); @@ -227,14 +227,22 @@ private function convertReflectionType(?ReflectionType $reflectionType) : Type|T } private function convertReflectionNamedType(ReflectionNamedType $reflectionNamedType) : Type { - return match ($type = $reflectionNamedType->getName()) { + $type = $reflectionNamedType->getName(); + $parsedType = match ($type) { 'int' => intType(), 'string' => stringType(), 'bool' => boolType(), 'array' => arrayType(), 'float' => floatType(), 'mixed' => mixedType(), - default => objectType($type) + default => null }; + + if ($parsedType === null) { + assert(class_exists($type)); + $parsedType = objectType($type); + } + + return $parsedType; } } diff --git a/stubs.php b/stubs.php new file mode 100644 index 0000000..90258a8 --- /dev/null +++ b/stubs.php @@ -0,0 +1,27 @@ +, + * delegates: list, + * prepares: list, + * aliases: list, + * shares: list + * } + */ + public function inspect(string $nameFilter = null, string $typeFilter = null) : array {} + + /** + * @psalm-template T of object + * @psalm-param non-empty-string|class-string $name + * @psalm-return ($name is class-string ? T : mixed) + */ + public function make(string $name, array $args = []) : mixed {} + + } + +} \ No newline at end of file diff --git a/test/Unit/Bootstrap/BootstrapTest.php b/test/Unit/Bootstrap/BootstrapTest.php index a642057..b267d3f 100644 --- a/test/Unit/Bootstrap/BootstrapTest.php +++ b/test/Unit/Bootstrap/BootstrapTest.php @@ -77,10 +77,10 @@ public function testBootstrapSingleConcreteServiceNoCache() : void { ); $container = $bootstrap->bootstrapContainer(); - $service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->getName()); + $service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->name()); self::assertInstanceOf( - Fixtures::singleConcreteService()->fooImplementation()->getName(), + Fixtures::singleConcreteService()->fooImplementation()->name(), $service ); } @@ -100,8 +100,8 @@ public function testBootstrapWithValidDefinitionProvider() : void { ); $container = $bootstrap->bootstrapContainer(); - $service = $container->get(Fixtures::thirdPartyServices()->fooInterface()->getName()); - self::assertInstanceOf(Fixtures::thirdPartyServices()->fooImplementation()->getName(), $service); + $service = $container->get(Fixtures::thirdPartyServices()->fooInterface()->name()); + self::assertInstanceOf(Fixtures::thirdPartyServices()->fooImplementation()->name(), $service); } public function testBootstrapWithParameterStores() : void { @@ -119,8 +119,8 @@ public function testBootstrapWithParameterStores() : void { ); $container = $bootstrap->bootstrapContainer(); - $service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->getName()); - self::assertInstanceOf(Fixtures::injectCustomStoreServices()->scalarInjector()->getName(), $service); + $service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->name()); + self::assertInstanceOf(Fixtures::injectCustomStoreServices()->scalarInjector()->name(), $service); self::assertSame('from test-store key', $service->key); } @@ -135,8 +135,8 @@ public function testBootstrapResolvesProfileServices() : void { new Stopwatch() ); $container = $bootstrap->bootstrapContainer(profiles: Profiles::fromList(['default', 'dev'])); - $service = $container->get(Fixtures::profileResolvedServices()->fooInterface()->getName()); - self::assertInstanceOf(Fixtures::profileResolvedServices()->devImplementation()->getName(), $service); + $service = $container->get(Fixtures::profileResolvedServices()->fooInterface()->name()); + self::assertInstanceOf(Fixtures::profileResolvedServices()->devImplementation()->name(), $service); } public function testServiceWiringObserver() : void { @@ -165,7 +165,7 @@ public function getServices() : array { protected function wireServices(AnnotatedContainer $container, ServiceGatherer $gatherer) : void { $this->container = $container; - $this->services = $gatherer->servicesForType(Fixtures::ambiguousAliasedServices()->fooInterface()->getName()); + $this->services = $gatherer->servicesForType(Fixtures::ambiguousAliasedServices()->fooInterface()->name()); } }; @@ -181,9 +181,9 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $ self::assertSame($container, $listener->getAnnotatedContainer()); self::assertSame([ - $container->get(Fixtures::ambiguousAliasedServices()->barImplementation()->getName()), - $container->get(Fixtures::ambiguousAliasedServices()->bazImplementation()->getName()), - $container->get(Fixtures::ambiguousAliasedServices()->quxImplementation()->getName()), + $container->get(Fixtures::ambiguousAliasedServices()->barImplementation()->name()), + $container->get(Fixtures::ambiguousAliasedServices()->bazImplementation()->name()), + $container->get(Fixtures::ambiguousAliasedServices()->quxImplementation()->name()), ], $actualServices); } @@ -226,7 +226,7 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $ self::assertSame($container, $listener->getAnnotatedContainer()); self::assertSame([ - $container->get(Fixtures::customServiceAttribute()->myRepo()->getName()), + $container->get(Fixtures::customServiceAttribute()->myRepo()->name()), ], $actualServices); } @@ -257,7 +257,7 @@ public function getServices() : array { protected function wireServices(AnnotatedContainer $container, ServiceGatherer $gatherer) : void { $this->container = $container; - $this->services = $gatherer->servicesForType(Fixtures::profileResolvedServices()->fooInterface()->getName()); + $this->services = $gatherer->servicesForType(Fixtures::profileResolvedServices()->fooInterface()->name()); } }; @@ -274,7 +274,7 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $ self::assertSame($container, $listener->getAnnotatedContainer()); self::assertSame([ - $container->get(Fixtures::profileResolvedServices()->prodImplementation()->getName()), + $container->get(Fixtures::profileResolvedServices()->prodImplementation()->name()), ], $actualServices); self::assertCount(1, $actualDefinitions); } @@ -478,10 +478,10 @@ public function testBootstrapFromAnnotatedContainerConventionsWithFilePresentRet ); $container = $bootstrap->bootstrapContainer(); - $service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->getName()); + $service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->name()); self::assertInstanceOf( - Fixtures::singleConcreteService()->fooImplementation()->getName(), + Fixtures::singleConcreteService()->fooImplementation()->name(), $service ); } diff --git a/test/Unit/Bootstrap/ComposerJsonScanningThirdPartyInitializerProviderTest.php b/test/Unit/Bootstrap/ComposerJsonScanningThirdPartyInitializerProviderTest.php index 163b64e..a8b1d63 100644 --- a/test/Unit/Bootstrap/ComposerJsonScanningThirdPartyInitializerProviderTest.php +++ b/test/Unit/Bootstrap/ComposerJsonScanningThirdPartyInitializerProviderTest.php @@ -166,4 +166,143 @@ public function testComposerJsonHasNonStringValueThrowsException() : void { $composerJsonProvider ); } + + public function testHandleComposerJsonExtraNotArray() : void { + $composerJsonProvider = $this->createMock(PackagesComposerJsonPathProvider::class); + $composerJsonProvider->expects($this->once()) + ->method('composerJsonPaths') + ->willReturn([ + '/path/to/vendor/package/composer.json' + ]); + + $filesystem = $this->createMock(Filesystem::class); + $filesystem->expects($this->once()) + ->method('read') + ->with('/path/to/vendor/package/composer.json') + ->willReturn(json_encode([ + 'name' => 'cspray/package', + 'extra' => 'not an array', + ])); + + $provider = new ComposerJsonScanningThirdPartyInitializerProvider( + $filesystem, + $composerJsonProvider + ); + + self::assertSame([], $provider->thirdPartyInitializers()); + } + + public function testHandleComposerJsonExtraWithNoAnnotatedContainerKey() : void { + $composerJsonProvider = $this->createMock(PackagesComposerJsonPathProvider::class); + $composerJsonProvider->expects($this->once()) + ->method('composerJsonPaths') + ->willReturn([ + '/path/to/vendor/package/composer.json' + ]); + + $filesystem = $this->createMock(Filesystem::class); + $filesystem->expects($this->once()) + ->method('read') + ->with('/path/to/vendor/package/composer.json') + ->willReturn(json_encode([ + 'name' => 'cspray/package', + 'extra' => [], + ])); + + $provider = new ComposerJsonScanningThirdPartyInitializerProvider( + $filesystem, + $composerJsonProvider + ); + + self::assertSame([], $provider->thirdPartyInitializers()); + } + + public function testComposerJsonExtraWithAnnotatedContainerKeyNotArrayThrowsException() : void { + $composerJsonProvider = $this->createMock(PackagesComposerJsonPathProvider::class); + $composerJsonProvider->expects($this->once()) + ->method('composerJsonPaths') + ->willReturn([ + '/path/to/vendor/package/composer.json' + ]); + + $filesystem = $this->createMock(Filesystem::class); + $filesystem->expects($this->once()) + ->method('read') + ->with('/path/to/vendor/package/composer.json') + ->willReturn(json_encode([ + 'name' => 'cspray/package', + 'extra' => [ + '$annotatedContainer' => 'not an array' + ], + ])); + + + $this->expectException(InvalidThirdPartyInitializer::class); + $this->expectExceptionMessage('The value listed in composer.json extra.$annotatedContainer MUST be an array.'); + + new ComposerJsonScanningThirdPartyInitializerProvider( + $filesystem, + $composerJsonProvider + ); + } + + public function testComposerJsonExtraWithAnnotatedContainerKeyArrayHasNoInitializers() : void { + $composerJsonProvider = $this->createMock(PackagesComposerJsonPathProvider::class); + $composerJsonProvider->expects($this->once()) + ->method('composerJsonPaths') + ->willReturn([ + '/path/to/vendor/package/composer.json' + ]); + + $filesystem = $this->createMock(Filesystem::class); + $filesystem->expects($this->once()) + ->method('read') + ->with('/path/to/vendor/package/composer.json') + ->willReturn(json_encode([ + 'name' => 'cspray/package', + 'extra' => [ + '$annotatedContainer' => [] + ], + ])); + + + $this->expectException(InvalidThirdPartyInitializer::class); + $this->expectExceptionMessage('The value listed in composer.json extra.$annotatedContainer MUST have a key "initializers" that holds a list of ThirdPartyInitializers to use.'); + + new ComposerJsonScanningThirdPartyInitializerProvider( + $filesystem, + $composerJsonProvider + ); + } + + public function testComposerJsonExtraWithAnnotatedContainerKeyArrayHasInitializersNotArray() : void { + $composerJsonProvider = $this->createMock(PackagesComposerJsonPathProvider::class); + $composerJsonProvider->expects($this->once()) + ->method('composerJsonPaths') + ->willReturn([ + '/path/to/vendor/package/composer.json' + ]); + + $filesystem = $this->createMock(Filesystem::class); + $filesystem->expects($this->once()) + ->method('read') + ->with('/path/to/vendor/package/composer.json') + ->willReturn(json_encode([ + 'name' => 'cspray/package', + 'extra' => [ + '$annotatedContainer' => [ + 'initializers' => false + ] + ], + ])); + + + $this->expectException(InvalidThirdPartyInitializer::class); + $this->expectExceptionMessage('The value listed in composer.json extra.$annotatedContainer.initializers MUST be a list of ThirdPartyInitializers to use.'); + + new ComposerJsonScanningThirdPartyInitializerProvider( + $filesystem, + $composerJsonProvider + ); + } } diff --git a/test/Unit/Cli/Command/ValidateCommandTest.php b/test/Unit/Cli/Command/ValidateCommandTest.php index b04ed60..4770084 100644 --- a/test/Unit/Cli/Command/ValidateCommandTest.php +++ b/test/Unit/Cli/Command/ValidateCommandTest.php @@ -131,8 +131,8 @@ public function testHandleWithConfigurationFilePresentShowsNoLogicalConstraints( public function testHandleWithConfigurationFilePresentShowsLogicalConstraints() : void { $banner = str_repeat('*', 80); - $barService = LogicalConstraintFixtures::duplicateServiceName()->getBarService()->getName(); - $fooService = LogicalConstraintFixtures::duplicateServiceName()->getFooService()->getName(); + $barService = LogicalConstraintFixtures::duplicateServiceName()->getBarService()->name(); + $fooService = LogicalConstraintFixtures::duplicateServiceName()->getFooService()->name(); $configClass = $this->bootstrappingConfiguration::class; $expected = <<fooService()->getName(); + $service = LogicalConstraintFixtures::duplicateServiceType()->fooService()->name(); $serviceAttr = Service::class; $dummyAttr = DummyService::class; $configClass = $this->bootstrappingConfiguration::class; diff --git a/test/Unit/ContainerDefinitionAssertionsTrait.php b/test/Unit/ContainerDefinitionAssertionsTrait.php index 327f42e..3c8b2aa 100644 --- a/test/Unit/ContainerDefinitionAssertionsTrait.php +++ b/test/Unit/ContainerDefinitionAssertionsTrait.php @@ -49,8 +49,8 @@ protected function assertAliasDefinitionsMap(array $expectedAliasMap, array $ali foreach ($aliasDefinitions as $aliasDefinition) { $this->assertInstanceOf(AliasDefinition::class, $aliasDefinition); $actualMap[] = [ - $aliasDefinition->abstractService()->getName(), - $aliasDefinition->concreteService()->getName() + $aliasDefinition->abstractService()->name(), + $aliasDefinition->concreteService()->name() ]; } @@ -67,7 +67,7 @@ protected function assertServicePrepareTypes(array $expectedServicePrepare, arra $actualMap = []; foreach ($servicePrepareDefinitions as $servicePrepareDefinition) { $this->assertInstanceOf(ServicePrepareDefinition::class, $servicePrepareDefinition); - $key = $servicePrepareDefinition->service()->getName(); + $key = $servicePrepareDefinition->service()->name(); $actualMap[] = [$key, $servicePrepareDefinition->methodName()]; } @@ -83,7 +83,7 @@ protected function assertServicePrepareTypes(array $expectedServicePrepare, arra */ protected function getServiceDefinition(array $serviceDefinitions, string $serviceDefinitionType) : ?ServiceDefinition { foreach ($serviceDefinitions as $serviceDefinition) { - if ($serviceDefinitionType === $serviceDefinition->type()->getName()) { + if ($serviceDefinitionType === $serviceDefinition->type()->name()) { return $serviceDefinition; } } diff --git a/test/Unit/ContainerFactory/ContainerFactoryTestCase.php b/test/Unit/ContainerFactory/ContainerFactoryTestCase.php index 63fd764..de8d45d 100644 --- a/test/Unit/ContainerFactory/ContainerFactoryTestCase.php +++ b/test/Unit/ContainerFactory/ContainerFactoryTestCase.php @@ -79,12 +79,12 @@ public function testCreateServiceNotHasThrowsException() { $container = $this->getContainer(Fixtures::nonAnnotatedServices()->getPath()); self::expectException(NotFoundExceptionInterface::class); - self::expectExceptionMessage('The service "' . Fixtures::nonAnnotatedServices()->nonAnnotatedService()->getName() . '" could not be found in this container.'); - $container->get(Fixtures::nonAnnotatedServices()->nonAnnotatedService()->getName()); + self::expectExceptionMessage('The service "' . Fixtures::nonAnnotatedServices()->nonAnnotatedService()->name() . '" could not be found in this container.'); + $container->get(Fixtures::nonAnnotatedServices()->nonAnnotatedService()->name()); } public function testGetSingleConcreteService() { - $class = Fixtures::singleConcreteService()->fooImplementation()->getName(); + $class = Fixtures::singleConcreteService()->fooImplementation()->name(); $container = $this->getContainer(Fixtures::singleConcreteService()->getPath()); $subject = $container->get($class); @@ -93,38 +93,38 @@ public function testGetSingleConcreteService() { public function testInterfaceServicePrepare() { $container = $this->getContainer(Fixtures::interfacePrepareServices()->getPath()); - $subject = $container->get(Fixtures::interfacePrepareServices()->fooInterface()->getName()); + $subject = $container->get(Fixtures::interfacePrepareServices()->fooInterface()->name()); - self::assertInstanceOf(Fixtures::interfacePrepareServices()->fooImplementation()->getName(), $subject); + self::assertInstanceOf(Fixtures::interfacePrepareServices()->fooImplementation()->name(), $subject); self::assertEquals(1, $subject->getBarCounter()); } public function testServicePrepareInvokedOnContainer() { $container = $this->getContainer(Fixtures::injectPrepareServices()->getPath()); - $subject = $container->get(Fixtures::injectPrepareServices()->prepareInjector()->getName()); + $subject = $container->get(Fixtures::injectPrepareServices()->prepareInjector()->name()); - self::assertInstanceOf(Fixtures::injectPrepareServices()->prepareInjector()->getName(), $subject); + self::assertInstanceOf(Fixtures::injectPrepareServices()->prepareInjector()->name(), $subject); self::assertSame('foo', $subject->getVal()); - self::assertInstanceOf(Fixtures::injectPrepareServices()->barImplementation()->getName(), $subject->getService()); + self::assertInstanceOf(Fixtures::injectPrepareServices()->barImplementation()->name(), $subject->getService()); } public function testMultipleAliasResolutionNoMakeDefine() { $container = $this->getContainer(Fixtures::ambiguousAliasedServices()->getPath()); self::expectException(ContainerExceptionInterface::class); - $container->get(Fixtures::ambiguousAliasedServices()->fooInterface()->getName()); + $container->get(Fixtures::ambiguousAliasedServices()->fooInterface()->name()); } public function testServiceDelegateOnInstanceMethod() : void { $container = $this->getContainer(Fixtures::delegatedService()->getPath()); - $service = $container->get(Fixtures::delegatedService()->serviceInterface()->getName()); + $service = $container->get(Fixtures::delegatedService()->serviceInterface()->name()); self::assertSame('From ServiceFactory From FooService', $service->getValue()); } public function testServiceDelegateOnStaticMethod() : void { $container = $this->getContainer(Fixtures::delegatedServiceStaticFactory()->getPath()); - $service = $container->get(Fixtures::delegatedServiceStaticFactory()->serviceInterface()->getName()); + $service = $container->get(Fixtures::delegatedServiceStaticFactory()->serviceInterface()->name()); self::assertSame('From static ServiceFactory From FooService', $service->getValue()); } @@ -132,23 +132,23 @@ public function testServiceDelegateOnStaticMethod() : void { public function testHasServiceIfCompiled() { $container = $this->getContainer(Fixtures::singleConcreteService()->getPath()); - self::assertTrue($container->has(Fixtures::singleConcreteService()->fooImplementation()->getName())); - self::assertFalse($container->has(Fixtures::ambiguousAliasedServices()->fooInterface()->getName())); + self::assertTrue($container->has(Fixtures::singleConcreteService()->fooImplementation()->name())); + self::assertFalse($container->has(Fixtures::ambiguousAliasedServices()->fooInterface()->name())); } public function testMultipleServicesWithPrimary() { $container = $this->getContainer(Fixtures::primaryAliasedServices()->getPath()); - self::assertInstanceOf(Fixtures::primaryAliasedServices()->fooImplementation()->getName(), $container->get(Fixtures::primaryAliasedServices()->fooInterface()->getName())); + self::assertInstanceOf(Fixtures::primaryAliasedServices()->fooImplementation()->name(), $container->get(Fixtures::primaryAliasedServices()->fooInterface()->name())); } public function testProfileResolvedServices() { $container = $this->getContainer(Fixtures::profileResolvedServices()->getPath(), Profiles::fromList(['default', 'dev'])); - $instance = $container->get(Fixtures::profileResolvedServices()->fooInterface()->getName()); + $instance = $container->get(Fixtures::profileResolvedServices()->fooInterface()->name()); self::assertNotNull($instance); - self::assertInstanceOf(Fixtures::profileResolvedServices()->devImplementation()->getName(), $instance); + self::assertInstanceOf(Fixtures::profileResolvedServices()->devImplementation()->name(), $instance); } public function testCreateNamedService() { @@ -159,18 +159,18 @@ public function testCreateNamedService() { $instance = $container->get('foo'); self::assertNotNull($instance); - self::assertInstanceOf(Fixtures::namedServices()->fooImplementation()->getName(), $instance); + self::assertInstanceOf(Fixtures::namedServices()->fooImplementation()->name(), $instance); } public function testCreateInjectStringService() { $container = $this->getContainer(Fixtures::injectConstructorServices()->getPath()); - self::assertSame('foobar', $container->get(Fixtures::injectConstructorServices()->injectStringService()->getName())->val); + self::assertSame('foobar', $container->get(Fixtures::injectConstructorServices()->injectStringService()->name())->val); } public function testConcreteAliasDefinitionDoesNotHaveServiceDefinition() { - $abstractService = Fixtures::implicitAliasedServices()->fooInterface()->getName(); - $concreteService = Fixtures::implicitAliasedServices()->fooImplementation()->getName(); + $abstractService = Fixtures::implicitAliasedServices()->fooInterface()->name(); + $concreteService = Fixtures::implicitAliasedServices()->fooImplementation()->name(); $containerDefinition = ContainerDefinitionBuilder::newDefinition() ->withServiceDefinition( ServiceDefinitionBuilder::forAbstract($abstract = objectType($abstractService))->build() @@ -180,14 +180,14 @@ public function testConcreteAliasDefinitionDoesNotHaveServiceDefinition() { )->build(); $this->expectException(InvalidAlias::class); - $this->expectExceptionMessage('An AliasDefinition has a concrete type, ' . $concrete->getName() . ', that is not a registered ServiceDefinition.'); + $this->expectExceptionMessage('An AliasDefinition has a concrete type, ' . $concrete->name() . ', that is not a registered ServiceDefinition.'); $this->getContainerFactory()->createContainer($containerDefinition); } public function testMultipleServicePrepare() { $container = $this->getContainer(Fixtures::multiplePrepareServices()->getPath()); - $subject = $container->get(Fixtures::multiplePrepareServices()->fooImplementation()->getName()); + $subject = $container->get(Fixtures::multiplePrepareServices()->fooImplementation()->name()); self::assertSame('foobar', $subject->getProperty()); } @@ -195,15 +195,15 @@ public function testMultipleServicePrepare() { public function testInjectServiceObjectMethodParam() { $container = $this->getContainer(Fixtures::injectServiceConstructorServices()->getPath()); - $subject = $container->get(Fixtures::injectServiceConstructorServices()->serviceInjector()->getName()); + $subject = $container->get(Fixtures::injectServiceConstructorServices()->serviceInjector()->name()); - self::assertInstanceOf(Fixtures::injectServiceConstructorServices()->fooImplementation()->getName(), $subject->foo); + self::assertInstanceOf(Fixtures::injectServiceConstructorServices()->fooImplementation()->name(), $subject->foo); } public function testInjectEnvMethodParam() { $container = $this->getContainer(Fixtures::injectConstructorServices()->getPath()); - $subject = $container->get(Fixtures::injectConstructorServices()->injectEnvService()->getName()); + $subject = $container->get(Fixtures::injectConstructorServices()->injectEnvService()->name()); self::assertSame(getenv('USER'), $subject->user); } @@ -219,7 +219,7 @@ public function fetch(Type|TypeUnion|TypeIntersect $type, string $key) : mixed { }; $container = $this->getContainer(Fixtures::injectCustomStoreServices()->getPath(), parameterStore: $parameterStore); - $subject = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->getName()); + $subject = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->name()); self::assertSame('key_test_store', $subject->key); } @@ -230,15 +230,15 @@ public function name() : string { } public function fetch(Type|TypeUnion|TypeIntersect $type, string $key) : mixed { - $type = Fixtures::injectUnionCustomStoreServices()->fooImplementation()->getName(); + $type = Fixtures::injectUnionCustomStoreServices()->fooImplementation()->name(); return new $type(); } }; $container = $this->getContainer(Fixtures::injectUnionCustomStoreServices()->getPath(), parameterStore: $parameterStore); - $subject = $container->get(Fixtures::injectUnionCustomStoreServices()->unionInjector()->getName()); + $subject = $container->get(Fixtures::injectUnionCustomStoreServices()->unionInjector()->name()); - self::assertInstanceOf(Fixtures::injectUnionCustomStoreServices()->fooImplementation()->getName(), $subject->fooOrBar); + self::assertInstanceOf(Fixtures::injectUnionCustomStoreServices()->fooImplementation()->name(), $subject->fooOrBar); } public function testCreateArbitraryStoreWithIntersectType() { @@ -248,15 +248,15 @@ public function name() : string { } public function fetch(Type|TypeUnion|TypeIntersect $type, string $key) : mixed { - $type = Fixtures::injectIntersectCustomStoreServices()->fooBarImplementation()->getName(); + $type = Fixtures::injectIntersectCustomStoreServices()->fooBarImplementation()->name(); return new $type(); } }; $container = $this->getContainer(Fixtures::injectIntersectCustomStoreServices()->getPath(), parameterStore: $parameterStore); - $subject = $container->get(Fixtures::injectIntersectCustomStoreServices()->intersectInjector()->getName()); + $subject = $container->get(Fixtures::injectIntersectCustomStoreServices()->intersectInjector()->name()); - self::assertInstanceOf(Fixtures::injectIntersectCustomStoreServices()->fooBarImplementation()->getName(), $subject->fooAndBar); + self::assertInstanceOf(Fixtures::injectIntersectCustomStoreServices()->fooBarImplementation()->name(), $subject->fooAndBar); } public function testCreateArbitraryStoreOnServiceNotPresent() { @@ -276,34 +276,34 @@ public static function profilesProvider() : array { #[DataProvider('profilesProvider')] public function testInjectProfilesMethodParam(string $expected, Profiles $profiles) { $container = $this->getContainer(Fixtures::injectConstructorServices()->getPath(), $profiles); - $subject = $container->get(Fixtures::injectConstructorServices()->injectProfilesStringService()->getName()); + $subject = $container->get(Fixtures::injectConstructorServices()->injectProfilesStringService()->name()); self::assertSame($expected, $subject->val); } public function testMakeAutowiredObject() { $container = $this->getContainer(Fixtures::autowireableFactoryServices()->getPath()); - $subject = $container->make(Fixtures::autowireableFactoryServices()->factoryCreatedService()->getName(), autowiredParams(rawParam('scalar', '802'))); + $subject = $container->make(Fixtures::autowireableFactoryServices()->factoryCreatedService()->name(), autowiredParams(rawParam('scalar', '802'))); - self::assertInstanceOf(Fixtures::autowireableFactoryServices()->fooImplementation()->getName(), $subject->foo); + self::assertInstanceOf(Fixtures::autowireableFactoryServices()->fooImplementation()->name(), $subject->foo); self::assertSame('802', $subject->scalar); } public function testMakeAutowiredObjectReplaceServiceTarget() { $container = $this->getContainer(Fixtures::autowireableFactoryServices()->getPath()); - $subject = $container->make(Fixtures::autowireableFactoryServices()->factoryCreatedService()->getName(), autowiredParams( + $subject = $container->make(Fixtures::autowireableFactoryServices()->factoryCreatedService()->name(), autowiredParams( rawParam('scalar', 'quarters'), serviceParam('foo', Fixtures::autowireableFactoryServices()->barImplementation()) )); - self::assertInstanceOf(Fixtures::autowireableFactoryServices()->barImplementation()->getName(), $subject->foo); + self::assertInstanceOf(Fixtures::autowireableFactoryServices()->barImplementation()->name(), $subject->foo); self::assertSame('quarters', $subject->scalar); } public function testBackingContainerInstanceOf() { $containerDefinition = ContainerDefinitionBuilder::newDefinition()->build(); self::assertInstanceOf( - $this->getBackingContainerInstanceOf()->getName(), + $this->getBackingContainerInstanceOf()->name(), $this->getContainerFactory()->createContainer($containerDefinition)->backingContainer() ); } @@ -326,7 +326,7 @@ public function testNamedServicesShared() : void { $container = $this->getContainer(Fixtures::injectNamedServices()->getPath()); $namedService = $container->get('bar'); - $typedService = $container->get(Fixtures::injectNamedServices()->barImplementation()->getName()); + $typedService = $container->get(Fixtures::injectNamedServices()->barImplementation()->name()); self::assertSame($namedService, $typedService); } @@ -334,17 +334,17 @@ public function testNamedServicesShared() : void { public function testInjectingNamedServices() : void { if (!$this->supportsInjectingMultipleNamedServices()) { $this->markTestSkipped( - $this->getBackingContainerInstanceOf()->getName() . ' does not support injecting multiple named services.' + $this->getBackingContainerInstanceOf()->name() . ' does not support injecting multiple named services.' ); } $container = $this->getContainer(Fixtures::injectNamedServices()->getPath()); /** @var \Cspray\AnnotatedContainer\Fixture\InjectNamedServices\ServiceConsumer $service */ - $service = $container->get(Fixtures::injectNamedServices()->serviceConsumer()->getName()); + $service = $container->get(Fixtures::injectNamedServices()->serviceConsumer()->name()); - self::assertInstanceOf(Fixtures::injectNamedServices()->fooImplementation()->getName(), $service->foo); - self::assertInstanceOf(Fixtures::injectNamedServices()->barImplementation()->getName(), $service->bar); + self::assertInstanceOf(Fixtures::injectNamedServices()->fooImplementation()->name(), $service->foo); + self::assertInstanceOf(Fixtures::injectNamedServices()->barImplementation()->name(), $service->bar); } public function testGettingProfilesImplicitlyShared() : void { @@ -374,7 +374,7 @@ public function testInvokeWithImplicitAlias() : void { $invoker->invoke($callable); - self::assertInstanceOf(Fixtures::implicitAliasedServices()->fooImplementation()->getName(), $state->foo); + self::assertInstanceOf(Fixtures::implicitAliasedServices()->fooImplementation()->name(), $state->foo); } public function testInvokeWithAmbiguousAliasRespectsParameters() : void { @@ -384,7 +384,7 @@ public function testInvokeWithAmbiguousAliasRespectsParameters() : void { $callable = fn(\Cspray\AnnotatedContainer\Fixture\AmbiguousAliasedServices\FooInterface $foo) => $state->foo = $foo; $invoker->invoke($callable, autowiredParams(serviceParam('foo', Fixtures::ambiguousAliasedServices()->quxImplementation()))); - self::assertInstanceOf(Fixtures::ambiguousAliasedServices()->quxImplementation()->getName(), $state->foo); + self::assertInstanceOf(Fixtures::ambiguousAliasedServices()->quxImplementation()->name(), $state->foo); } public function testInvokeWithScalarParameter() : void { @@ -410,16 +410,16 @@ public function testInvokeReturnsCallableReturnValue() : void { public function testServiceProfileNotActiveNotShared() : void { $container = $this->getContainer(Fixtures::profileResolvedServices()->getPath(), Profiles::fromList(['default', 'dev'])); - self::assertTrue($container->has(Fixtures::profileResolvedServices()->fooInterface()->getName())); - self::assertTrue($container->has(Fixtures::profileResolvedServices()->devImplementation()->getName())); - self::assertFalse($container->has(Fixtures::profileResolvedServices()->prodImplementation()->getName())); - self::assertFalse($container->has(Fixtures::profileResolvedServices()->testImplementation()->getName())); + self::assertTrue($container->has(Fixtures::profileResolvedServices()->fooInterface()->name())); + self::assertTrue($container->has(Fixtures::profileResolvedServices()->devImplementation()->name())); + self::assertFalse($container->has(Fixtures::profileResolvedServices()->prodImplementation()->name())); + self::assertFalse($container->has(Fixtures::profileResolvedServices()->testImplementation()->name())); } public function testNamedServiceProfileNotActiveNotShared() : void { $container = $this->getContainer(Fixtures::namedProfileResolvedServices()->getPath(), Profiles::fromList(['default', 'prod'])); - self::assertTrue($container->has(Fixtures::namedProfileResolvedServices()->fooInterface()->getName())); + self::assertTrue($container->has(Fixtures::namedProfileResolvedServices()->fooInterface()->name())); self::assertTrue($container->has('prod-foo')); self::assertFalse($container->has('dev-foo')); self::assertFalse($container->has('test-foo')); @@ -432,14 +432,14 @@ public static function deserializeContainerProvider() : array { $containerFactory->addParameterStore($store); $container = $containerFactory->createContainer($deserialize); - $service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->getName()); + $service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->name()); self::assertSame('from test-store key', $service->key); }], [Fixtures::injectConstructorServices(), function(ContainerFactory $containerFactory, ContainerDefinition $deserialize) { $container = $containerFactory->createContainer($deserialize); - $service = $container->get(Fixtures::injectConstructorServices()->injectTypeUnionService()->getName()); + $service = $container->get(Fixtures::injectConstructorServices()->injectTypeUnionService()->name()); self::assertSame(4.20, $service->value); }] @@ -479,28 +479,28 @@ public function testContainerCreationEventsEmitted() : void { public function testCreatingServiceWithInjectServiceCollectionDecorator() : void { $container = $this->getContainer(Fixtures::injectServiceCollectionDecorator()->getPath()); - $fooService = $container->get(Fixtures::injectServiceCollectionDecorator()->fooService()->getName()); + $fooService = $container->get(Fixtures::injectServiceCollectionDecorator()->fooService()->name()); self::assertInstanceOf( - Fixtures::injectServiceCollectionDecorator()->fooService()->getName(), + Fixtures::injectServiceCollectionDecorator()->fooService()->name(), $fooService ); self::assertInstanceOf( - Fixtures::injectServiceCollectionDecorator()->compositeFoo()->getName(), + Fixtures::injectServiceCollectionDecorator()->compositeFoo()->name(), $fooService->foo ); self::assertCount(3, $fooService->foo->foos); $fooClasses = array_map(static fn(object $foo) => $foo::class, $fooService->foo->foos); self::assertContains( - Fixtures::injectServiceCollectionDecorator()->fooImplementation()->getName(), + Fixtures::injectServiceCollectionDecorator()->fooImplementation()->name(), $fooClasses ); self::assertContains( - Fixtures::injectServiceCollectionDecorator()->barImplementation()->getName(), + Fixtures::injectServiceCollectionDecorator()->barImplementation()->name(), $fooClasses ); self::assertContains( - Fixtures::injectServiceCollectionDecorator()->bazImplementation()->getName(), + Fixtures::injectServiceCollectionDecorator()->bazImplementation()->name(), $fooClasses ); } @@ -508,11 +508,11 @@ public function testCreatingServiceWithInjectServiceCollectionDecorator() : void public function testCreatingServiceWithInjectServiceCollection() : void { $container = $this->getContainer(Fixtures::injectServiceCollection()->getPath()); - $collectionInjector = $container->get(Fixtures::injectServiceCollection()->collectionInjector()->getName()); + $collectionInjector = $container->get(Fixtures::injectServiceCollection()->collectionInjector()->name()); self::assertCount(3, $collectionInjector->services); self::assertContainsOnlyInstancesOf( - Fixtures::injectServiceCollection()->fooInterface()->getName(), + Fixtures::injectServiceCollection()->fooInterface()->name(), $collectionInjector->services ); } @@ -520,11 +520,11 @@ public function testCreatingServiceWithInjectServiceCollection() : void { public function testCreatingServiceWithInjectServiceDomainCollection() : void { $container = $this->getContainer(Fixtures::injectServiceDomainCollection()->getPath()); - $collectionInjector = $container->get(Fixtures::injectServiceDomainCollection()->collectionInjector()->getName()); + $collectionInjector = $container->get(Fixtures::injectServiceDomainCollection()->collectionInjector()->name()); self::assertCount(3, $collectionInjector->collection->services); self::assertContainsOnlyInstancesOf( - Fixtures::injectServiceDomainCollection()->fooInterface()->getName(), + Fixtures::injectServiceDomainCollection()->fooInterface()->name(), $collectionInjector->collection->services ); } diff --git a/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php b/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php index ba8a491..0912b29 100644 --- a/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php +++ b/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php @@ -108,7 +108,7 @@ public function testGetAliasDefinitionAbstractNotServiceDefinitionThrowsExceptio self::expectException(InvalidAlias::class); self::expectExceptionMessage(sprintf( 'An AliasDefinition has an abstract type, %s, that is not a registered ServiceDefinition.', - Fixtures::ambiguousAliasedServices()->fooInterface()->getName() + Fixtures::ambiguousAliasedServices()->fooInterface()->name() )); $subject->aliasDefinitions(); @@ -130,7 +130,7 @@ public function testGetAliasDefinitionConcreteNotServiceDefinitionThrowsExceptio self::expectException(InvalidAlias::class); self::expectExceptionMessage(sprintf( 'An AliasDefinition has a concrete type, %s, that is not a registered ServiceDefinition.', - Fixtures::ambiguousAliasedServices()->barImplementation()->getName() + Fixtures::ambiguousAliasedServices()->barImplementation()->name() )); $subject->aliasDefinitions(); diff --git a/test/Unit/Definition/ServiceDefinitionBuilderTest.php b/test/Unit/Definition/ServiceDefinitionBuilderTest.php index f50807c..f939117 100644 --- a/test/Unit/Definition/ServiceDefinitionBuilderTest.php +++ b/test/Unit/Definition/ServiceDefinitionBuilderTest.php @@ -18,11 +18,11 @@ public function factoryMethodProvider() { } private function getAbstractType() : string { - return Fixtures::implicitAliasedServices()->fooInterface()->getName(); + return Fixtures::implicitAliasedServices()->fooInterface()->name(); } private function getConcreteType() : string { - return Fixtures::implicitAliasedServices()->fooImplementation()->getName(); + return Fixtures::implicitAliasedServices()->fooImplementation()->name(); } public function testBuildingTypeForAbstractHasCorrectServiceDefinitionType() { diff --git a/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php b/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php index 274a179..0914a82 100644 --- a/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php +++ b/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php @@ -49,8 +49,8 @@ public function testDuplicateDelegateAttributeForSameServiceHasCorrectViolation( self::assertCount(1, $violations); $violation = $violations->get(0); - $fooService = LogicalConstraintFixtures::duplicateServiceDelegate()->fooService()->getName(); - $factory = LogicalConstraintFixtures::duplicateServiceDelegate()->factory()->getName(); + $fooService = LogicalConstraintFixtures::duplicateServiceDelegate()->fooService()->name(); + $factory = LogicalConstraintFixtures::duplicateServiceDelegate()->factory()->name(); $serviceDelegate = ServiceDelegate::class; $expected = <<get(0); - $fooService = Fixtures::implicitServiceDelegateType()->fooService()->getName(); - $factory = Fixtures::implicitServiceDelegateType()->fooServiceFactory()->getName(); + $fooService = Fixtures::implicitServiceDelegateType()->fooService()->name(); + $factory = Fixtures::implicitServiceDelegateType()->fooServiceFactory()->name(); $serviceDelegate = ServiceDelegate::class; $expected = <<get(0); - $service = LogicalConstraintFixtures::duplicateServicePrepare()->fooService()->getName(); + $service = LogicalConstraintFixtures::duplicateServicePrepare()->fooService()->name(); $prepareAttr = ServicePrepare::class; $dummyAttr = DummyPrepare::class; @@ -82,12 +82,12 @@ public function testDuplicatePreparesWithDefinitionProviderHasViolation() : void public function consume(DefinitionProviderContext $context) : void { $context->addServicePrepareDefinition( servicePrepare(objectType( - Fixtures::singleConcreteService()->fooImplementation()->getName() + Fixtures::singleConcreteService()->fooImplementation()->name() ), 'postConstruct') ); $context->addServicePrepareDefinition( servicePrepare(objectType( - Fixtures::singleConcreteService()->fooImplementation()->getName() + Fixtures::singleConcreteService()->fooImplementation()->name() ), 'postConstruct') ); } @@ -100,7 +100,7 @@ public function consume(DefinitionProviderContext $context) : void { self::assertCount(1, $results); $violation = $results->get(0); - $service = Fixtures::singleConcreteService()->fooImplementation()->getName(); + $service = Fixtures::singleConcreteService()->fooImplementation()->name(); $expected = <<get(0); - $abstractService = LogicalConstraintFixtures::multiplePrimaryService()->fooInterface()->getName(); - $fooService = LogicalConstraintFixtures::multiplePrimaryService()->fooService()->getName(); - $barService = LogicalConstraintFixtures::multiplePrimaryService()->barService()->getName(); + $abstractService = LogicalConstraintFixtures::multiplePrimaryService()->fooInterface()->name(); + $fooService = LogicalConstraintFixtures::multiplePrimaryService()->fooService()->name(); + $barService = LogicalConstraintFixtures::multiplePrimaryService()->barService()->name(); $expected = << $injectDefinition->parameterName() === $expectedInject->targetName); + $definitionsForParam = array_filter($injectDefinitions, fn($injectDefinition) => $injectDefinition->parameterName() === $expectedInject->tarname); if (empty($definitionsForParam)) { Assert::fail(sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->methodName )); @@ -68,7 +68,7 @@ private function validateMethodType(ExpectedInject $expectedInject, array $injec if (empty($definitionsWithTypes)) { Assert::fail(sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with type \'%s\'.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->methodName, $expectedInject->type @@ -81,7 +81,7 @@ private function validatePropertyType(ExpectedInject $expectedInject, array $inj if (empty($definitionsWithType)) { Assert::fail(sprintf( 'Could not find an InjectDefinition for property \'%s\' on %s with type \'%s\'.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->type )); @@ -93,7 +93,7 @@ private function validateValue(ExpectedInject $expectedInject, array $injectDefi if (empty($definitionsWithValues)) { $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with a value matching:%s %s.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->methodName, str_repeat(PHP_EOL, 2), @@ -111,7 +111,7 @@ private function validateProfiles(ExpectedInject $expectedInject, array $injectD if (empty($definitionsWithProfiles)) { $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with %s.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->methodName, $profileDescriptor() @@ -126,7 +126,7 @@ private function validateStoreName(ExpectedInject $expectedInject, array $inject if (empty($definitionsWithNames)) { $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with %s.', - $expectedInject->targetName, + $expectedInject->tarname, $expectedInject->service, $expectedInject->methodName, $storeDescriptor() diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php index 214e983..a52f29b 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php @@ -32,15 +32,15 @@ final public function testConfigurationNameCount() : void { #[DataProvider('configurationTypeProvider')] final public function testConfigurationType(ExpectedConfigurationType $expectedConfigurationType) : void { - $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationType->configuration->getName()); + $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationType->configuration->name()); $this->assertNotNull($configurationDefinition); } #[DataProvider('configurationNameProvider')] final public function testConfigurationName(ExpectedConfigurationName $expectedConfigurationName) : void { - $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationName->configuration->getName()); + $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationName->configuration->name()); - $this->assertSame($expectedConfigurationName->name, $configurationDefinition->getName()); + $this->assertSame($expectedConfigurationName->name, $configurationDefinition->name()); } } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php index d385dbf..695fe64 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php @@ -102,7 +102,7 @@ final public function testExpectedServiceProfilesCount() : void { #[DataProvider('serviceTypeProvider')] final public function testExpectedServiceTypes(ExpectedServiceType $expectedServiceType) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceType->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceType->type->name()); $this->assertNotNull( $serviceDefinition, @@ -112,35 +112,35 @@ final public function testExpectedServiceTypes(ExpectedServiceType $expectedServ #[DataProvider('serviceNameProvider')] final public function testExpectedServiceNames(ExpectedServiceName $expectedServiceName) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceName->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceName->type->name()); $this->assertSame($expectedServiceName->name, $serviceDefinition?->name()); } #[DataProvider('serviceIsPrimaryProvider')] final public function testExpectedServiceIsPrimary(ExpectedServiceIsPrimary $expectedServiceIsPrimary) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsPrimary->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsPrimary->type->name()); $this->assertSame($expectedServiceIsPrimary->isPrimary, $serviceDefinition?->isPrimary()); } #[DataProvider('serviceIsConcreteProvider')] final public function testExpectedServiceIsConcrete(ExpectedServiceIsConcrete $expectedServiceIsConcrete) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsConcrete->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsConcrete->type->name()); $this->assertSame($expectedServiceIsConcrete->isConcrete, $serviceDefinition?->isConcrete()); } #[DataProvider('serviceIsAbstractProvider')] final public function testExpectedServiceIsAbstract(ExpectedServiceIsAbstract $expectedServiceIsAbstract) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsAbstract->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceIsAbstract->type->name()); $this->assertSame($expectedServiceIsAbstract->isAbstract, $serviceDefinition?->isAbstract()); } #[DataProvider('serviceProfilesProvider')] final public function testExpectedServiceProfiles(ExpectedServiceProfiles $expectedServiceProfiles) : void { - $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceProfiles->type->getName()); + $serviceDefinition = $this->getServiceDefinition($this->getSubject()->serviceDefinitions(), $expectedServiceProfiles->type->name()); $this->assertSame($expectedServiceProfiles->profiles, $serviceDefinition?->profiles()); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php index 2373144..53d7f64 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php @@ -58,7 +58,7 @@ public static function injectProvider() : array { 'setVals', 'service', Fixtures::injectPrepareServices()->fooInterface(), - Fixtures::injectPrepareServices()->barImplementation()->getName() + Fixtures::injectPrepareServices()->barImplementation()->name() )], [ExpectedInject::forMethodParam( Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector(), diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php index b2e07ce..1898888 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php @@ -48,7 +48,7 @@ public static function injectProvider() : array { Fixtures::injectServiceConstructorServices()->serviceInjector(), 'foo', Fixtures::injectServiceConstructorServices()->fooInterface(), - Fixtures::injectServiceConstructorServices()->fooImplementation()->getName() + Fixtures::injectServiceConstructorServices()->fooImplementation()->name() )], [ExpectedInject::forConstructParam( Fixtures::injectServiceConstructorServices()->nullableServiceInjector(), diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php index 5e9f12a..5a53666 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php @@ -113,7 +113,7 @@ public function testServiceDelegateNotServiceAddsImplicitConcreteService() : voi $serviceDef = $this->getServiceDefinition( $containerDef->serviceDefinitions(), - Fixtures::beanLikeConfigConcrete()->fooService()->getName() + Fixtures::beanLikeConfigConcrete()->fooService()->name() ); self::assertNotNull($serviceDef); @@ -130,7 +130,7 @@ public function testServiceDelegateNotServiceAddsImplicitAbstractInterfaceServic $serviceDef = $this->getServiceDefinition( $containerDef->serviceDefinitions(), - Fixtures::beanLikeConfigInterface()->fooInterface()->getName() + Fixtures::beanLikeConfigInterface()->fooInterface()->name() ); self::assertNotNull($serviceDef); @@ -147,7 +147,7 @@ public function testServiceDelegateNotServiceAddsImplicitAbstractClassService() $serviceDef = $this->getServiceDefinition( $containerDef->serviceDefinitions(), - Fixtures::beanLikeConfigAbstract()->abstractFooService()->getName() + Fixtures::beanLikeConfigAbstract()->abstractFooService()->name() ); self::assertNotNull($serviceDef); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php index ccede1f..28084b2 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php @@ -13,7 +13,7 @@ public function testAnnotatedTargetNotKnownAttributeTypeThrowsException() : void $subject = new AnnotatedTargetDefinitionConverter(); $target = $this->createMock(AnnotatedTarget::class); - $target->expects($this->once())->method('getAttributeInstance')->willReturn(new \stdClass()); + $target->expects($this->once())->method('attributeInstance')->willReturn(new \stdClass()); $this->expectException(InvalidAnnotatedTarget::class); $this->expectExceptionMessage( diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php index 81eaa27..2a2dff9 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php @@ -12,7 +12,7 @@ class AbstractSharedServicesTest extends AnnotatedTargetDefinitionConverterTestC protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass( - Fixtures::abstractClassAliasedService()->fooAbstract()->getName() + Fixtures::abstractClassAliasedService()->fooAbstract()->name() )); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php index 88d41dc..1dc91b4 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php @@ -39,16 +39,16 @@ public function __construct( ) { } - public function getTargetReflection(): ReflectionClass|ReflectionMethod|ReflectionParameter|ReflectionProperty { + public function targetReflection(): ReflectionClass|ReflectionMethod|ReflectionParameter|ReflectionProperty { return $this->reflection; } - public function getAttributeReflection() : ReflectionAttribute { + public function attributeReflection() : ReflectionAttribute { return $this->reflection->getAttributes($this->attributeType->value, ReflectionAttribute::IS_INSTANCEOF)[$this->attributeIndex]; } - public function getAttributeInstance(): Service|ServicePrepare|ServiceDelegate|Inject { - return $this->getAttributeReflection()->newInstance(); + public function attributeInstance(): Service|ServicePrepare|ServiceDelegate|Inject { + return $this->attributeReflection()->newInstance(); } }; } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php index 042cb24..f502523 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectArrayService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectArrayService()->name(), '__construct'], 'values' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php index 0aa17dd..c7c2fe1 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectBoolService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectBoolService()->name(), '__construct'], 'flag' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php index ce5c556..1364c19 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php @@ -13,7 +13,7 @@ class InjectEnvMethodParamTest extends AnnotatedTargetDefinitionConverterTestCas protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectEnvService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectEnvService()->name(), '__construct'], 'user' )); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php index 78c5a5d..c0a990e 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectExplicitMixedService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectExplicitMixedService()->name(), '__construct'], 'value' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php index bbeca70..8b9dae6 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectFloatService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectFloatService()->name(), '__construct'], 'dessert' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php index 5bf1a0e..bb5457e 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectImplicitMixedService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectImplicitMixedService()->name(), '__construct'], 'val' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php index ba1b1a2..94e0de1 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php @@ -15,7 +15,7 @@ protected function getSubjectTarget() : AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectIntService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectIntService()->name(), '__construct'], 'meaningOfLife' ) ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php index b6c1358..50351e4 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php @@ -13,7 +13,7 @@ class InjectMultipleProfilesFirstMethodParamTest extends AnnotatedTargetDefiniti protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], 'val' )); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php index d22264f..d5144f5 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php @@ -13,7 +13,7 @@ class InjectMultipleProfilesSecondMethodParamTest extends AnnotatedTargetDefinit protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], 'val' ), 1); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php index ccfe9ec..b6e6bde 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php @@ -13,7 +13,7 @@ class InjectMultipleProfilesThirdMethodParamTest extends AnnotatedTargetDefiniti protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->getName(), '__construct'], + [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], 'val' ), 2); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php index 336103b..ecf8cb9 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php @@ -15,7 +15,7 @@ class InjectNullableServiceMethodParamTest extends AnnotatedTargetDefinitionConv protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->nullableServiceInjector()->getName(), '__construct'], 'maybeFoo') + new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->nullableServiceInjector()->name(), '__construct'], 'maybeFoo') ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php index c07a864..64acfb0 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php @@ -16,7 +16,7 @@ class InjectNullableStringMethodParamTest extends AnnotatedTargetDefinitionConve protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectNullableStringService()->getName(), '__construct'], 'maybe') + new \ReflectionParameter([Fixtures::injectConstructorServices()->injectNullableStringService()->name(), '__construct'], 'maybe') ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php index c61a5ba..86972e1 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php @@ -17,7 +17,7 @@ class InjectScalarTypeUnionMethodParamTest extends AnnotatedTargetDefinitionConv protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectTypeUnionService()->getName(), '__construct'], 'value') + new \ReflectionParameter([Fixtures::injectConstructorServices()->injectTypeUnionService()->name(), '__construct'], 'value') ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php index 89ff63c..73a30fb 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php @@ -13,7 +13,7 @@ class InjectServiceMethodParamTest extends AnnotatedTargetDefinitionConverterTes protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->serviceInjector()->getName(), '__construct'], 'foo') + new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->serviceInjector()->name(), '__construct'], 'foo') ); } @@ -38,7 +38,7 @@ public function testDefinitionGetType() { } public function testGetValue() { - $this->assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->getName(), $this->definition->value()); + $this->assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->name(), $this->definition->value()); } public function testGetStore() { @@ -51,6 +51,6 @@ public function testGetProfiles() { public function testGetAttribute() { self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->getName(), $this->definition->attribute()->value()); + self::assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->name(), $this->definition->attribute()->value()); } } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php index 76b4236..a6e0e18 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php @@ -15,7 +15,7 @@ class InjectServiceScalarTypeUnionMethodParamTest extends AnnotatedTargetDefinit protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector()->getName(), 'setValue'], 'val') + new \ReflectionParameter([Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector()->name(), 'setValue'], 'val') ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php index 99eb03f..c76bddd 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php @@ -14,7 +14,7 @@ class InjectServiceTypeIntersectMethodParamTest extends AnnotatedTargetDefinitio protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceIntersectConstructorServices()->fooBarConsumer()->getName(), '__construct'], 'fooBar') + new \ReflectionParameter([Fixtures::injectServiceIntersectConstructorServices()->fooBarConsumer()->name(), '__construct'], 'fooBar') ); } @@ -42,7 +42,7 @@ public function testDefinitionGetTypeIntersect() { } public function testGetValue() { - $this->assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->getName(), $this->definition->value()); + $this->assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->name(), $this->definition->value()); } public function testGetStore() { @@ -55,6 +55,6 @@ public function testGetProfiles() { public function testGetAttribute() { self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->getName(), $this->definition->attribute()->value()); + self::assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->name(), $this->definition->attribute()->value()); } } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php index f58108f..f473735 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php @@ -14,7 +14,7 @@ class InjectStringMethodParamTest extends AnnotatedTargetDefinitionConverterTest protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectStringService()->getName(), '__construct'], 'val') + new \ReflectionParameter([Fixtures::injectConstructorServices()->injectStringService()->name(), '__construct'], 'val') ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php index 9b0da24..a5a58df 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php @@ -14,7 +14,7 @@ class MultipleServicesWithPrimaryTest extends AnnotatedTargetDefinitionConverter protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget( AttributeType::Service, - new ReflectionClass(Fixtures::primaryAliasedServices()->fooImplementation()->getName()) + new ReflectionClass(Fixtures::primaryAliasedServices()->fooImplementation()->name()) ); } public function testGetServiceDefinitionInstance() { diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php index caa7df0..9f95534 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php @@ -12,7 +12,7 @@ class NamedServiceConverterTest extends AnnotatedTargetDefinitionConverterTestCase { protected function getSubjectTarget(): AnnotatedTarget { - return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::namedServices()->fooInterface()->getName())); + return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::namedServices()->fooInterface()->name())); } public function testGetServiceDefinitionInstance() { $this->assertInstanceOf(ServiceDefinition::class, $this->definition); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php index 4a55474..711f672 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php @@ -12,7 +12,7 @@ class ProfileResolvedServicesConverterTest extends AnnotatedTargetDefinitionConverterTestCase { protected function getSubjectTarget(): AnnotatedTarget { - return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::profileResolvedServices()->devImplementation()->getName())); + return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::profileResolvedServices()->devImplementation()->name())); } public function testGetServiceDefinitionInstance() { diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php index 5cf1f74..16be542 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php @@ -13,7 +13,7 @@ class ServiceDelegateConverterTest extends AnnotatedTargetDefinitionConverterTes protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::ServiceDelegate, new ReflectionMethod( - Fixtures::delegatedService()->serviceFactory()->getName(), + Fixtures::delegatedService()->serviceFactory()->name(), 'createService' )); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php index ae9dcf2..37a9c59 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php @@ -13,7 +13,7 @@ class ServicePrepareConverterTest extends AnnotatedTargetDefinitionConverterTest protected function getSubjectTarget(): AnnotatedTarget { return $this->getAnnotatedTarget(AttributeType::ServicePrepare, new ReflectionMethod( - Fixtures::interfacePrepareServices()->fooInterface()->getName(), + Fixtures::interfacePrepareServices()->fooInterface()->name(), 'setBar' )); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php index 47c1f61..9b27d9d 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php @@ -13,7 +13,7 @@ class SingleAliasedServiceConverterTest extends AnnotatedTargetDefinitionConverterTestCase { private function getClass() : string { - return Fixtures::implicitAliasedServices()->fooInterface()->getName(); + return Fixtures::implicitAliasedServices()->fooInterface()->name(); } protected function getSubjectTarget(): AnnotatedTarget { diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php index c4d2f95..2d3a67c 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php @@ -13,7 +13,7 @@ class SingleConcreteServiceConverterTest extends AnnotatedTargetDefinitionConverterTestCase { private function getClass() : string { - return Fixtures::singleConcreteService()->fooImplementation()->getName(); + return Fixtures::singleConcreteService()->fooImplementation()->name(); } protected function getSubjectTarget(): AnnotatedTarget { diff --git a/test/Unit/ThirdPartyFunctionsTest.php b/test/Unit/ThirdPartyFunctionsTest.php index 0fd208e..c7e262b 100644 --- a/test/Unit/ThirdPartyFunctionsTest.php +++ b/test/Unit/ThirdPartyFunctionsTest.php @@ -66,8 +66,8 @@ public function testServiceDelegateDefinition() { $service = Fixtures::delegatedService()->serviceInterface(); $serviceDelegateDefinition = serviceDelegate($service, Fixtures::delegatedService()->serviceFactory(), 'createService'); - $this->assertSame(Fixtures::delegatedService()->serviceInterface()->getName(), $serviceDelegateDefinition->serviceType()->getName()); - $this->assertSame(Fixtures::delegatedService()->serviceFactory()->getName(), $serviceDelegateDefinition->delegateType()->getName()); + $this->assertSame(Fixtures::delegatedService()->serviceInterface()->name(), $serviceDelegateDefinition->serviceType()->name()); + $this->assertSame(Fixtures::delegatedService()->serviceFactory()->name(), $serviceDelegateDefinition->delegateType()->name()); $this->assertSame('createService', $serviceDelegateDefinition->delegateMethod()); } @@ -75,7 +75,7 @@ public function testServicePrepareDefinition() { $servicePrepareDefinition = servicePrepare(Fixtures::interfacePrepareServices()->fooInterface(), 'setBar'); $this->assertServicePrepareTypes([ - [Fixtures::interfacePrepareServices()->fooInterface()->getName(), 'setBar'] + [Fixtures::interfacePrepareServices()->fooInterface()->name(), 'setBar'] ], [$servicePrepareDefinition]); } From f2a2af39bf6eea004e7fa6ae58512e17c49b1620 Mon Sep 17 00:00:00 2001 From: Charles Sprayberry Date: Mon, 17 Jun 2024 18:08:30 -0400 Subject: [PATCH 2/2] Resolve remainder of fixable psalm issues --- known-issues.xml | 46 +++++++++++++++++++ psalm.xml | 1 + src/Autowire/AutowireableFactory.php | 7 +-- src/Bootstrap/ServiceWiringListener.php | 22 ++++----- .../AurynContainerFactory.php | 37 +++++++++++++-- .../AurynContainerFactoryState.php | 9 ++-- .../IlluminateContainerFactory.php | 43 +++++++++++------ .../IlluminateContainerFactoryState.php | 6 +++ .../PhpDiContainerFactory.php | 10 +++- .../XmlContainerDefinitionSerializer.php | 19 ++++++-- .../AnnotatedTargetDefinitionConverter.php | 1 + stubs.php | 34 +++++++++++++- 12 files changed, 190 insertions(+), 45 deletions(-) create mode 100644 known-issues.xml diff --git a/known-issues.xml b/known-issues.xml new file mode 100644 index 0000000..742aea9 --- /dev/null +++ b/known-issues.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + name()]]]> + + + + + + + + + + + + + + + + + name()]]]> + + + + + + diff --git a/psalm.xml b/psalm.xml index 7644dec..fb78109 100644 --- a/psalm.xml +++ b/psalm.xml @@ -7,6 +7,7 @@ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" findUnusedBaselineEntry="true" findUnusedCode="false" + errorBaseline="known-issues.xml" > diff --git a/src/Autowire/AutowireableFactory.php b/src/Autowire/AutowireableFactory.php index 633e5f7..ff09b62 100644 --- a/src/Autowire/AutowireableFactory.php +++ b/src/Autowire/AutowireableFactory.php @@ -13,11 +13,8 @@ interface AutowireableFactory { * AutowireableParameterSet. * * @template T of object - * @param class-string $classType The FQCN for the type that should be created - * @param AutowireableParameterSet|null $parameters A set of AutowireableParameters that should be used for constructor - * arguments in place of or in addition to any autowire-resolved - * parameters. - * @return T + * @psalm-param class-string $classType + * @psalm-return T */ public function make(string $classType, AutowireableParameterSet $parameters = null) : object; } diff --git a/src/Bootstrap/ServiceWiringListener.php b/src/Bootstrap/ServiceWiringListener.php index 8912b4e..21bc6e5 100644 --- a/src/Bootstrap/ServiceWiringListener.php +++ b/src/Bootstrap/ServiceWiringListener.php @@ -23,7 +23,6 @@ public function __construct( private readonly AnnotatedContainer $container ) { $activeProfiles = $container->get(Profiles::class); - assert($activeProfiles instanceof Profiles); $this->containerDefinition = new ProfilesAwareContainerDefinition($containerDefinition, $activeProfiles); } @@ -64,7 +63,6 @@ public function servicesWithAttribute(string $attributeType) : array { } $service = $this->container->get($serviceDefinition->type()->name()); - assert(is_object($service)); $services[] = $this->createServiceFromServiceDefinition($service, $serviceDefinition); } return $services; @@ -83,20 +81,20 @@ private function createServiceFromServiceDefinition(object $service, ServiceDefi * @implements ServiceFromServiceDefinition */ new class($service, $serviceDefinition) implements ServiceFromServiceDefinition { - public function __construct( + public function __construct( private readonly object $service, private readonly ServiceDefinition $definition - ) { - } + ) { + } - public function service() : object { - return $this->service; - } + public function service() : object { + return $this->service; + } - public function definition() : ServiceDefinition { - return $this->definition; - } - }; + public function definition() : ServiceDefinition { + return $this->definition; + } + }; /** @var ServiceFromServiceDefinition $serviceFromDefinition */ return $serviceFromDefinition; diff --git a/src/ContainerFactory/AurynContainerFactory.php b/src/ContainerFactory/AurynContainerFactory.php index a3c9dc0..0e5f15e 100644 --- a/src/ContainerFactory/AurynContainerFactory.php +++ b/src/ContainerFactory/AurynContainerFactory.php @@ -120,6 +120,11 @@ public function __construct( $state->injector->delegate(Profiles::class, fn() => $activeProfiles); } + /** + * @template T + * @param class-string|non-empty-string $id + * @return ($id is class-string ? T : mixed) + */ public function get(string $id) { try { if (!$this->has($id)) { @@ -132,7 +137,10 @@ public function get(string $id) { if ($namedType !== null) { $id = $namedType->name(); } - return $this->state->injector->make($id); + + /** @var T|mixed $value */ + $value = $this->state->injector->make($id); + return $value; } catch (InjectionException $injectionException) { throw ContainerException::fromCaughtThrowable($injectionException); } @@ -153,11 +161,19 @@ public function has(string $id): bool { return $anyDefined > 0; } + /** + * @template T of object + * @psalm-param class-string $classType + * @psalm-return T + */ public function make(string $classType, AutowireableParameterSet $parameters = null) : object { - return $this->state->injector->make( + /** @var T $object */ + $object = $this->state->injector->make( $classType, $this->convertAutowireableParameterSet($parameters) ); + + return $object; } public function backingContainer() : Injector { @@ -172,12 +188,25 @@ public function invoke(callable $callable, AutowireableParameterSet $parameters } private function convertAutowireableParameterSet(AutowireableParameterSet $parameters = null) : array { + /** @var array $params */ $params = []; if (!is_null($parameters)) { /** @var AutowireableParameter $parameter */ foreach ($parameters as $parameter) { - $name = $parameter->isServiceIdentifier() ? $parameter->name() : ':' . $parameter->name(); - $params[$name] = $parameter->isServiceIdentifier() ? $parameter->value()->name() : $parameter->value(); + if ($parameter->isServiceIdentifier()) { + $parameterValue = $parameter->value(); + assert($parameterValue instanceof ObjectType); + + /** @var non-empty-string $value */ + $value = $parameterValue->name(); + $name = $parameter->name(); + } else { + /** @var mixed $value */ + $value = $parameter->value(); + $name = ':' . $parameter->name(); + } + + $params[$name] = $value; } } return $params; diff --git a/src/ContainerFactory/AurynContainerFactoryState.php b/src/ContainerFactory/AurynContainerFactoryState.php index 8d98b3b..f7b0d40 100644 --- a/src/ContainerFactory/AurynContainerFactoryState.php +++ b/src/ContainerFactory/AurynContainerFactoryState.php @@ -28,11 +28,10 @@ public function __construct( /** - * @param class-string $class + * @template T + * @param class-string $class * @param non-empty-string $method * @param non-empty-string $param - * @return void - * @throws \Auryn\InjectionException */ public function addMethodInject(string $class, string $method, string $param, mixed $value) : void { if ($value instanceof ContainerReference) { @@ -52,7 +51,9 @@ public function addMethodInject(string $class, string $method, string $param, mi } if (is_a($serviceDefinition->type()->name(), $value->valueType->name(), true)) { - $values[] = $this->injector->make($serviceDefinition->type()->name()); + /** @var T $objectValue */ + $objectValue = $this->injector->make($serviceDefinition->type()->name()); + $values[] = $objectValue; } } diff --git a/src/ContainerFactory/IlluminateContainerFactory.php b/src/ContainerFactory/IlluminateContainerFactory.php index d52b0be..8941499 100644 --- a/src/ContainerFactory/IlluminateContainerFactory.php +++ b/src/ContainerFactory/IlluminateContainerFactory.php @@ -118,7 +118,11 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil } $container->singleton( $service, - static fn(Container $container) : object => $container->call([$target, $delegateInfo['delegateMethod']]) + static function(Container $container) use($target, $delegateInfo) : object { + $object = $container->call([$target, $delegateInfo['delegateMethod']]); + assert(is_object($object)); + return $object; + } ); } @@ -130,20 +134,24 @@ protected function createAnnotatedContainer(ContainerFactoryState $state, Profil $container->singleton($service); } - $container->afterResolving(static function ($created, Container $container) use($state) { - foreach ($state->servicePrepares() as $service => $methods) { - if ($created instanceof $service) { - foreach ($methods as $method) { - $params = []; - foreach ($state->parametersForMethod($service, $method) as $param => $value) { - $params[$param] = $value instanceof ContainerReference ? $container->get($value->name) : $value; - } - $container->call([$created, $method], $params); + foreach ($state->servicePrepares() as $service => $methods) { + $container->afterResolving($service, static function (object $created, Container $container) use($state, $service, $methods) { + foreach ($methods as $method) { + /** @var array $params */ + $params = []; + /** + * @var mixed $value + */ + foreach ($state->parametersForMethod($service, $method) as $param => $value) { + /** @var mixed $resolvedValue */ + $resolvedValue = $value instanceof ContainerReference ? $container->get($value->name) : $value; + $params[$param] = $resolvedValue; } - break; + $container->call([$created, $method], $params); } - } - }); + }); + } + foreach ($state->methodInject() as $service => $methods) { foreach ($methods as $method => $params) { @@ -241,12 +249,19 @@ private function resolvedParameters(?AutowireableParameterSet $parameters) : arr return $params; } + /** + * @template T + * @param class-string|non-empty-string $id + * @return ($id is class-string ? T : mixed) + */ public function get(string $id) { if (!$this->has($id)) { throw ServiceNotFound::fromServiceNotInContainer($id); } - return $this->state->container->get($id); + /** @var T|mixed $object */ + $object = $this->state->container->get($id); + return $object; } public function has(string $id) : bool { diff --git a/src/ContainerFactory/IlluminateContainerFactoryState.php b/src/ContainerFactory/IlluminateContainerFactoryState.php index b391b05..c8aaa24 100644 --- a/src/ContainerFactory/IlluminateContainerFactoryState.php +++ b/src/ContainerFactory/IlluminateContainerFactoryState.php @@ -119,6 +119,9 @@ public function concreteServices() : array { return $this->concreteServices; } + /** + * @return array + */ public function aliases() : array { return $this->aliases; } @@ -130,6 +133,9 @@ public function delegates() : array { return $this->delegates; } + /** + * @return array + */ public function namedServices() : array { return $this->namedServices; } diff --git a/src/ContainerFactory/PhpDiContainerFactory.php b/src/ContainerFactory/PhpDiContainerFactory.php index 8148b02..bda0180 100644 --- a/src/ContainerFactory/PhpDiContainerFactory.php +++ b/src/ContainerFactory/PhpDiContainerFactory.php @@ -152,11 +152,19 @@ public function make(string $classType, AutowireableParameterSet $parameters = n return $object; } + /** + * @psalm-template T of object + * @psalm-param class-string|non-empty-string $id + * @psalm-return ($id is class-string ? T : mixed) + */ public function get(string $id) { if (!$this->has($id)) { throw ServiceNotFound::fromServiceNotInContainer($id); } - return $this->container->get($id); + + /** @var T|mixed $object */ + $object = $this->container->get($id); + return $object; } public function has(string $id) : bool { diff --git a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php index f307b03..64ed47f 100644 --- a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php +++ b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php @@ -3,6 +3,9 @@ namespace Cspray\AnnotatedContainer\Definition\Serializer; use Cspray\AnnotatedContainer\AnnotatedContainerVersion; +use Cspray\AnnotatedContainer\Attribute\InjectAttribute; +use Cspray\AnnotatedContainer\Attribute\ServiceAttribute; +use Cspray\AnnotatedContainer\Attribute\ServiceDelegateAttribute; use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; @@ -359,7 +362,9 @@ private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $buil $attr = $xpath->query('cd:attribute/text()', $serviceDefinition)[0]?->nodeValue; if ($attr !== null) { - $serviceBuilder = $serviceBuilder->withAttribute(unserialize(base64_decode($attr))); + $attrInstance = unserialize(base64_decode($attr)); + assert($attrInstance instanceof ServiceAttribute); + $serviceBuilder = $serviceBuilder->withAttribute($attrInstance); } $builder = $builder->withServiceDefinition($serviceBuilder->build()); @@ -431,7 +436,9 @@ private function addServiceDelegateDefinitionsToBuilder(ContainerDefinitionBuild $attr = $xpath->query('cd:attribute/text()', $delegateDefinition)[0]?->nodeValue; if ($attr !== null) { - $serviceDelegateBuilder = $serviceDelegateBuilder->withAttribute(unserialize(base64_decode($attr))); + $attrInstance = unserialize(base64_decode($attr)); + assert($attrInstance instanceof ServiceDelegateAttribute); + $serviceDelegateBuilder = $serviceDelegateBuilder->withAttribute($attrInstance); } $builder = $builder->withServiceDelegateDefinition($serviceDelegateBuilder->build()); @@ -454,7 +461,9 @@ private function addInjectDefinitionsToBuilder(ContainerDefinitionBuilder $build $serializedValue = base64_decode($encodedSerializedValue); /** @var mixed $value */ $value = unserialize($serializedValue); - $valueType = $this->injectValueParser->convertStringToType(base64_decode($valueType)); + /** @var non-empty-string $base64DecodedValueType */ + $base64DecodedValueType = base64_decode($valueType); + $valueType = $this->injectValueParser->convertStringToType($base64DecodedValueType); $type = $xpath->query('cd:class/text()', $injectDefinition)[0]->nodeValue; $methodName = $xpath->query('cd:method/text()', $injectDefinition)[0]->nodeValue; @@ -487,7 +496,9 @@ private function addInjectDefinitionsToBuilder(ContainerDefinitionBuilder $build } if ($attr !== null) { - $injectBuilder = $injectBuilder->withAttribute(unserialize(base64_decode($attr))); + $attrInstance = unserialize(base64_decode($attr)); + assert($attrInstance instanceof InjectAttribute); + $injectBuilder = $injectBuilder->withAttribute($attrInstance); } $builder = $builder->withInjectDefinition($injectBuilder->build()); diff --git a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php b/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php index 6de44f8..c02e22a 100644 --- a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php +++ b/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php @@ -112,6 +112,7 @@ private function buildServiceDelegateDefinition(AnnotatedTarget $target) : Servi $attribute = $target->attributeInstance(); assert($attribute instanceof ServiceDelegateAttribute); + /** @var class-string|null $service */ $service = $attribute->service(); if ($service !== null) { return ServiceDelegateDefinitionBuilder::forService(objectType($service)) diff --git a/stubs.php b/stubs.php index 90258a8..72d9f87 100644 --- a/stubs.php +++ b/stubs.php @@ -1,11 +1,27 @@ |non-empty-string $id + * @psalm-return ($id is class-string ? T : mixed) + */ + public function get(string $id); + + } + + +} + namespace Auryn { class Injector { /** - * @return array{ + * @psalm-return array{ * classDefinitions: list, * delegates: list, * prepares: list, @@ -24,4 +40,20 @@ public function make(string $name, array $args = []) : mixed {} } +} + +namespace Illuminate\Contracts\Container { + + interface Container { + + /** + * @psalm-template T of object + * @psalm-param non-empty-string|class-string $abstract + * @psalm-return ($abstract is class-string ? T : mixed) + */ + public function make(string $abstract, array $parameters = []); + + + } + } \ No newline at end of file