Skip to content

Commit

Permalink
Resolve remainder of fixable psalm issues
Browse files Browse the repository at this point in the history
  • Loading branch information
cspray committed Jun 17, 2024
1 parent 080742f commit f2a2af3
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 45 deletions.
46 changes: 46 additions & 0 deletions known-issues.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.24.0@462c80e31c34e58cc4f750c656be3927e80e550e">
<file src="src/ContainerFactory/AurynContainerFactory.php">
<MethodSignatureMismatch>
<code><![CDATA[$id]]></code>
</MethodSignatureMismatch>
<MixedAssignment>
<code><![CDATA[$params[$name]]]></code>
</MixedAssignment>
<MixedInferredReturnType>
<code><![CDATA[T]]></code>
</MixedInferredReturnType>
<MixedReturnStatement>
<code><![CDATA[$value]]></code>
</MixedReturnStatement>
</file>
<file src="src/ContainerFactory/IlluminateContainerFactory.php">
<MethodSignatureMismatch>
<code><![CDATA[$id]]></code>
</MethodSignatureMismatch>
<MixedAssignment>
<code><![CDATA[$params[$param]]]></code>
<code><![CDATA[$params[$parameter->name()]]]></code>
</MixedAssignment>
<MixedInferredReturnType>
<code><![CDATA[object]]></code>
</MixedInferredReturnType>
<MixedReturnStatement>
<code><![CDATA[$object]]></code>
</MixedReturnStatement>
<NoValue>
<code><![CDATA[$object]]></code>
</NoValue>
</file>
<file src="src/ContainerFactory/PhpDiContainerFactory.php">
<MethodSignatureMismatch>
<code><![CDATA[$id]]></code>
</MethodSignatureMismatch>
<MixedAssignment>
<code><![CDATA[$params[$parameter->name()]]]></code>
</MixedAssignment>
<MixedReturnStatement>
<code><![CDATA[$object]]></code>
</MixedReturnStatement>
</file>
</files>
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
findUnusedCode="false"
errorBaseline="known-issues.xml"
>
<projectFiles>
<directory name="src" />
Expand Down
7 changes: 2 additions & 5 deletions src/Autowire/AutowireableFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ interface AutowireableFactory {
* AutowireableParameterSet.
*
* @template T of object
* @param class-string<T> $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<T> $classType
* @psalm-return T
*/
public function make(string $classType, AutowireableParameterSet $parameters = null) : object;
}
22 changes: 10 additions & 12 deletions src/Bootstrap/ServiceWiringListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -83,20 +81,20 @@ private function createServiceFromServiceDefinition(object $service, ServiceDefi
* @implements ServiceFromServiceDefinition<T>
*/
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<T> $serviceFromDefinition */
return $serviceFromDefinition;
Expand Down
37 changes: 33 additions & 4 deletions src/ContainerFactory/AurynContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ public function __construct(
$state->injector->delegate(Profiles::class, fn() => $activeProfiles);
}

/**
* @template T
* @param class-string<T>|non-empty-string $id
* @return ($id is class-string<T> ? T : mixed)
*/
public function get(string $id) {
try {
if (!$this->has($id)) {
Expand All @@ -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);
}
Expand All @@ -153,11 +161,19 @@ public function has(string $id): bool {
return $anyDefined > 0;
}

/**
* @template T of object
* @psalm-param class-string<T> $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 {
Expand All @@ -172,12 +188,25 @@ public function invoke(callable $callable, AutowireableParameterSet $parameters
}

private function convertAutowireableParameterSet(AutowireableParameterSet $parameters = null) : array {
/** @var array<non-empty-string, mixed> $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;
Expand Down
9 changes: 5 additions & 4 deletions src/ContainerFactory/AurynContainerFactoryState.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ public function __construct(


/**
* @param class-string $class
* @template T
* @param class-string<T> $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) {
Expand All @@ -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;
}
}

Expand Down
43 changes: 29 additions & 14 deletions src/ContainerFactory/IlluminateContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
);
}

Expand All @@ -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<non-empty-string, mixed> $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) {
Expand Down Expand Up @@ -241,12 +249,19 @@ private function resolvedParameters(?AutowireableParameterSet $parameters) : arr
return $params;
}

/**
* @template T
* @param class-string<T>|non-empty-string $id
* @return ($id is class-string<T> ? 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 {
Expand Down
6 changes: 6 additions & 0 deletions src/ContainerFactory/IlluminateContainerFactoryState.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public function concreteServices() : array {
return $this->concreteServices;
}

/**
* @return array<class-string, class-string>
*/
public function aliases() : array {
return $this->aliases;
}
Expand All @@ -130,6 +133,9 @@ public function delegates() : array {
return $this->delegates;
}

/**
* @return array<class-string, non-empty-string>
*/
public function namedServices() : array {
return $this->namedServices;
}
Expand Down
10 changes: 9 additions & 1 deletion src/ContainerFactory/PhpDiContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,19 @@ public function make(string $classType, AutowireableParameterSet $parameters = n
return $object;
}

/**
* @psalm-template T of object
* @psalm-param class-string<T>|non-empty-string $id
* @psalm-return ($id is class-string<T> ? 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 {
Expand Down
19 changes: 15 additions & 4 deletions src/Definition/Serializer/XmlContainerDefinitionSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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());
Expand All @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
1 change: 1 addition & 0 deletions src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Loading

0 comments on commit f2a2af3

Please sign in to comment.