Skip to content

Commit

Permalink
Merge pull request #137 from gsteel/qa/plugin-manager-types
Browse files Browse the repository at this point in the history
Improve type inference for plugin manager implementations
  • Loading branch information
Ocramius authored Jun 13, 2022
2 parents e903983 + f1499ed commit db011e3
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 9 deletions.
7 changes: 2 additions & 5 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.22.0@fc2c6ab4d5fa5d644d8617089f012f3bb84b8703">
<files psalm-version="4.23.0@f1fe6ff483bf325c803df9f510d09a03fd796f88">
<file src="src/AbstractFactory/ConfigAbstractFactory.php">
<InvalidStringClass occurrences="1">
<code>new $requestedName(...$arguments)</code>
Expand Down Expand Up @@ -405,7 +405,7 @@
<code>$names[$name]</code>
<code>$object[$shared ? $method : 'build']</code>
</MixedArrayOffset>
<MixedAssignment occurrences="26">
<MixedAssignment occurrences="24">
<code>$callSequence</code>
<code>$first</code>
<code>$idx1</code>
Expand Down Expand Up @@ -502,9 +502,6 @@
<MissingClosureParamType occurrences="1">
<code>$autoload</code>
</MissingClosureParamType>
<MixedAssignment occurrences="1">
<code>$instance</code>
</MixedAssignment>
<RedundantConditionGivenDocblockType occurrences="2">
<code>assertIsArray</code>
<code>assertIsArray</code>
Expand Down
14 changes: 11 additions & 3 deletions src/AbstractPluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
* The implementation extends `ServiceManager`, thus providing the same set
* of capabilities as found in that implementation.
*
* @template InstanceType of object
* @implements PluginManagerInterface<InstanceType>
* @psalm-import-type ServiceManagerConfiguration from ServiceManager
* @psalm-suppress PropertyNotSetInConstructor
*/
Expand All @@ -48,7 +50,7 @@ abstract class AbstractPluginManager extends ServiceManager implements PluginMan
* An object type that the created instance must be instanced of
*
* @var null|string
* @psalm-var null|class-string
* @psalm-var null|class-string<InstanceType>
*/
protected $instanceOf;

Expand Down Expand Up @@ -131,6 +133,10 @@ public function configure(array $config)
* Override setService for additional plugin validation.
*
* {@inheritDoc}
*
* @param string|class-string<InstanceType> $name
* @param InstanceType $service
* @psalm-suppress MoreSpecificImplementedParamType
*/
public function setService($name, $service)
{
Expand All @@ -139,9 +145,10 @@ public function setService($name, $service)
}

/**
* @param string $name Service name of plugin to retrieve.
* @param class-string<InstanceType>|string $name Service name of plugin to retrieve.
* @param null|array<mixed> $options Options to use when creating the instance.
* @return mixed
* @psalm-return ($name is class-string ? InstanceType : mixed)
* @throws Exception\ServiceNotFoundException If the manager does not have
* a service definition for the instance, and the service is not
* auto-invokable.
Expand All @@ -162,14 +169,15 @@ public function get($name, ?array $options = null)
$this->setFactory($name, Factory\InvokableFactory::class);
}

/** @psalm-suppress MixedAssignment */
$instance = ! $options ? parent::get($name) : $this->build($name, $options);
$this->validate($instance);
return $instance;
}

/**
* {@inheritDoc}
*
* @psalm-assert InstanceType $instance
*/
public function validate($instance)
{
Expand Down
3 changes: 3 additions & 0 deletions src/PluginManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* Interface for a plugin manager
*
* A plugin manager is a specialized service locator used to create homogeneous objects
*
* @template InstanceType of object
*/
interface PluginManagerInterface extends ServiceLocatorInterface
{
Expand All @@ -22,6 +24,7 @@ interface PluginManagerInterface extends ServiceLocatorInterface
* @throws InvalidServiceException If created instance does not respect the
* constraint on type imposed by the plugin manager.
* @throws ContainerExceptionInterface If any other error occurs.
* @psalm-assert InstanceType $instance
*/
public function validate($instance);
}
4 changes: 3 additions & 1 deletion src/ServiceLocatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ interface ServiceLocatorInterface extends ContainerInterface
/**
* Build a service by its name, using optional options (such services are NEVER cached).
*
* @param string $name
* @template T of object
* @param string|class-string<T> $name
* @param null|array<mixed> $options
* @return mixed
* @psalm-return ($name is class-string ? T : mixed)
* @throws Exception\ServiceNotFoundException If no factory/abstract
* factory could be found to create the instance.
* @throws Exception\ServiceNotCreatedException If factory/delegator fails
Expand Down
3 changes: 3 additions & 0 deletions src/ServiceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ public function build($name, ?array $options = null)

/**
* {@inheritDoc}
*
* @param string|class-string $name
* @return bool
*/
public function has($name)
{
Expand Down

0 comments on commit db011e3

Please sign in to comment.