diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
index 41c9cc9fabc1..ad6ef5401c64 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
@@ -15,6 +15,8 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoManager;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
/**
* A console command for autowiring information.
@@ -27,6 +29,15 @@ class DebugAutowiringCommand extends ContainerDebugCommand
{
protected static $defaultName = 'debug:autowiring';
+ private $autowiringInfoManager;
+
+ public function __construct(AutowiringInfoManager $autowiringInfoManager = null)
+ {
+ $this->autowiringInfoManager = $autowiringInfoManager;
+
+ parent::__construct();
+ }
+
/**
* {@inheritdoc}
*/
@@ -78,24 +89,92 @@ protected function execute(InputInterface $input, OutputInterface $output)
asort($serviceIds);
- $io->title('Autowirable Services');
$io->text('The following classes & interfaces can be used as type-hints when autowiring:');
if ($search) {
$io->text(sprintf('(only showing classes/interfaces matching %s)', $search));
}
$io->newLine();
- $tableRows = array();
+
+ $keyServices = array();
+ $otherServices = array();
$hasAlias = array();
foreach ($serviceIds as $serviceId) {
+ if (null !== $this->autowiringInfoManager && $autowiringInfo = $this->autowiringInfoManager->getInfo($serviceId)) {
+ $keyServices[] = array(
+ 'info' => $autowiringInfo,
+ 'alias' => $builder->has($serviceId) ? $builder->getAlias($serviceId) : null,
+ );
+
+ continue;
+ }
+
if ($builder->hasAlias($serviceId)) {
- $tableRows[] = array(sprintf('%s', $serviceId));
- $tableRows[] = array(sprintf(' alias to %s', $builder->getAlias($serviceId)));
- $hasAlias[(string) $builder->getAlias($serviceId)] = true;
- } else {
- $tableRows[$serviceId] = array(sprintf('%s', $serviceId));
+ $hasAlias[(string)$builder->getAlias($serviceId)] = true;
}
+
+ $otherServices[$serviceId] = array(
+ 'type' => $serviceId,
+ 'alias' => $builder->hasAlias($serviceId) ? $builder->getAlias($serviceId) : null,
+ );
}
+ $otherServices = array_diff_key($otherServices, $hasAlias);
+
+ usort($keyServices, function($a, $b) {
+ if ($a['info']->getPriority() === $b['info']->getPriority()) {
+ return 0;
+ }
+
+ return $a['info']->getPriority() > $b['info']->getPriority() ? -1 : 1;
+ });
+
+ $this->printKeyServices($keyServices, $io);
- $io->table(array(), array_diff_key($tableRows, $hasAlias));
+ $this->printOtherServices($otherServices, $io);
+ }
+
+ private function printOtherServices(array $otherServices, SymfonyStyle $io)
+ {
+ if (empty($otherServices)) {
+ return;
+ }
+
+ // not necessary to print if this is the only list
+ if (null !== $this->autowiringInfoManager) {
+ $io->title('Other Services');
+ }
+
+ foreach ($otherServices as $serviceData) {
+ $io->writeln(sprintf('%s', $serviceData['type']));
+ if ($alias = $serviceData['alias']) {
+ $io->writeln(sprintf(' alias to %s', $alias));
+ }
+ }
+ }
+
+ private function printKeyServices(array $keyServices, SymfonyStyle $io)
+ {
+ if (empty($keyServices)) {
+ return;
+ }
+
+ $io->title('Key Services');
+ foreach ($keyServices as $serviceData) {
+ /** @var AutowiringTypeInfo $info */
+ $info = $serviceData['info'];
+
+ $nameLine = sprintf('%s', $info->getName());
+ if ($info->getDescription()) {
+ $nameLine .= sprintf(' (%s)', $info->getDescription());
+ }
+ $io->writeln($nameLine);
+
+ $io->writeln(sprintf(' Type: %s', $info->getType()));
+
+ if ($serviceData['alias']) {
+ $io->writeln(sprintf(' Alias to the %s service', $serviceData['alias']));
+ }
+
+ $io->writeln('');
+ }
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AutowireDebugInfoPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AutowireDebugInfoPass.php
new file mode 100644
index 000000000000..03d96b79aa7c
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AutowireDebugInfoPass.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Looks for & processes debug.autowiring_info_provider tags.
+ *
+ * @author Ryan Weaver
+ */
+class AutowireDebugInfoPass implements CompilerPassInterface
+{
+ const AUTOWIRING_INFO_PROVIDER_TAG = 'debug.autowiring_info_provider';
+
+ public function process(ContainerBuilder $container)
+ {
+ if (false === $container->hasDefinition('debug.autowiring_info_manager')) {
+ return;
+ }
+
+ $definition = $container->getDefinition('debug.autowiring_info_manager');
+
+ $references = array();
+ foreach ($container->findTaggedServiceIds(self::AUTOWIRING_INFO_PROVIDER_TAG, true) as $serviceId => $attributes) {
+ $references[] = new Reference($serviceId);
+ }
+
+ $definition->replaceArgument(0, $references);
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkAutowiringInfoProvider.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkAutowiringInfoProvider.php
new file mode 100644
index 000000000000..8e14bac44d73
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkAutowiringInfoProvider.php
@@ -0,0 +1,105 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
+
+use Doctrine\Common\Annotations\Reader;
+use Psr\Cache\CacheItemPoolInterface;
+use Psr\SimpleCache\CacheInterface;
+use Symfony\Component\Asset\Packages;
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoProviderInterface;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\Form\FormFactoryInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+use Symfony\Component\HttpKernel\KernelInterface;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
+use Symfony\Component\Serializer\SerializerInterface;
+use Symfony\Component\Stopwatch\Stopwatch;
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+use Symfony\Component\Workflow\Registry;
+
+/**
+ * @author Ryan Weaver
+ */
+final class FrameworkAutowiringInfoProvider implements AutowiringInfoProviderInterface
+{
+ public function getTypeInfos(): array
+ {
+ return array(
+ AutowiringTypeInfo::create(CacheItemPoolInterface::class, 'Cache', 10)
+ ->setDescription('general-purpose service for caching things'),
+
+ AutowiringTypeInfo::create(CacheInterface::class, 'Simple Cache', 10)
+ ->setDescription('simpler cache, but less features'),
+
+ AutowiringTypeInfo::create(RouterInterface::class, 'Router', 10)
+ ->setDescription('used to generate URLs'),
+
+ AutowiringTypeInfo::create(EventDispatcherInterface::class, 'Event Dispatcher')
+ ->setDescription('used to dispatch custom events'),
+
+ AutowiringTypeInfo::create(Reader::class, 'Annotation Reader', -10),
+
+ AutowiringTypeInfo::create(ParameterBagInterface::class, 'Parameter Bag')
+ ->setDescription('access service parameters'),
+
+ AutowiringTypeInfo::create(Filesystem::class, 'Filesystem')
+ ->setDescription('helper for filesystem actions'),
+
+ AutowiringTypeInfo::create(RequestStack::class, 'Request Stack')
+ ->setDescription('access the Request object'),
+
+ AutowiringTypeInfo::create(SessionInterface::class, 'Session'),
+
+ AutowiringTypeInfo::create(FlashBagInterface::class, 'Flash Bag')
+ ->setDescription('use to set temporary success/failure messages'),
+
+ AutowiringTypeInfo::create(KernelInterface::class, 'Kernel'),
+
+ AutowiringTypeInfo::create(Stopwatch::class, 'Stopwatch')
+ ->setDescription('use to add custom timings to profiler'),
+
+ AutowiringTypeInfo::create(Packages::class, 'Asset Packages')
+ ->setDescription('use to generate URLs to assets'),
+
+ AutowiringTypeInfo::create(FormFactoryInterface::class, 'Form Factory')
+ ->setDescription('use to create form objects'),
+
+ AutowiringTypeInfo::create(ValidatorInterface::class, 'Validator')
+ ->setDescription('use to validate data against some constraints'),
+
+ AutowiringTypeInfo::create(TranslatorInterface::class, 'Translator'),
+
+ AutowiringTypeInfo::create(PropertyAccessorInterface::class, 'Property Accessor')
+ ->setDescription('use to read dynamic keys from some data'),
+
+ AutowiringTypeInfo::create(CsrfTokenManagerInterface::class, 'CSRF Token Manager')
+ ->setDescription('generate and check CSRF tokens'),
+
+ AutowiringTypeInfo::create(SerializerInterface::class, 'Serializer')
+ ->setDescription('use to serialize data to JSON, XML, etc'),
+
+ AutowiringTypeInfo::create(Registry::class, 'Workflow')
+ ->setDescription('use to fetch workflows'),
+
+ AutowiringTypeInfo::create(Registry::class, 'Workflow')
+ ->setDescription('use to fetch workflows'),
+ );
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 413d61719384..25f2f0d335dd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -16,6 +16,7 @@
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AutowireDebugInfoPass;
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
use Symfony\Bundle\FullStack;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
@@ -33,6 +34,7 @@
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoProviderInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@@ -330,6 +332,8 @@ public function load(array $configs, ContainerBuilder $container)
->addTag('validator.constraint_validator');
$container->registerForAutoconfiguration(ObjectInitializerInterface::class)
->addTag('validator.initializer');
+ $container->registerForAutoconfiguration(AutowiringInfoProviderInterface::class)
+ ->addTag(AutowireDebugInfoPass::AUTOWIRING_INFO_PROVIDER_TAG);
if (!$container->getParameter('kernel.debug')) {
// remove tagged iterator argument for resource checkers
diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
index f25bb71240b9..ab9ed1cb2e45 100644
--- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
+++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
@@ -13,6 +13,7 @@
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass;
+use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AutowireDebugInfoPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CacheCollectorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolClearerPass;
@@ -120,6 +121,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING, -255);
$container->addCompilerPass(new CacheCollectorPass(), PassConfig::TYPE_BEFORE_REMOVING);
+ $container->addCompilerPass(new AutowireDebugInfoPass());
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml
index 34f47a0599b3..2231adbc76bc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml
@@ -56,6 +56,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
index 5d64074422a0..fd1a1e907c24 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml
@@ -23,5 +23,13 @@
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/DebugAutowiringCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/DebugAutowiringCommandTest.php
index 0b7f9290a50b..7413a8d4f7ff 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/DebugAutowiringCommandTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/DebugAutowiringCommandTest.php
@@ -31,6 +31,7 @@ public function testBasicFunctionality()
$this->assertContains('Symfony\Component\HttpKernel\HttpKernelInterface', $tester->getDisplay());
$this->assertContains('alias to http_kernel', $tester->getDisplay());
+ $this->assertContains('Simple Cache', $tester->getDisplay(), 'Key services are displayed');
}
public function testSearchArgument()
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityAutowiringInfoProvider.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityAutowiringInfoProvider.php
new file mode 100644
index 000000000000..8f5c07704d33
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityAutowiringInfoProvider.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoProviderInterface;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
+use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
+use Symfony\Component\Security\Core\Security;
+use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
+
+/**
+ * @author Ryan Weaver
+ */
+final class SecurityAutowiringInfoProvider implements AutowiringInfoProviderInterface
+{
+ public function getTypeInfos(): array
+ {
+ return [
+ AutowiringTypeInfo::create(GuardAuthenticatorHandler::class, 'Guard Auth Handler')
+ ->setDescription('use to manually authenticate with Guard'),
+
+ AutowiringTypeInfo::create(Security::class, 'Security')
+ ->setDescription('use to check access & get the current User'),
+
+ AutowiringTypeInfo::create(UserPasswordEncoderInterface::class, 'Password Encoder')
+ ->setDescription('use to encode passwords & check them'),
+ ];
+ }
+}
\ No newline at end of file
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_debug.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_debug.xml
index d3b7b936ea69..d983dced9542 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_debug.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_debug.xml
@@ -19,5 +19,9 @@
+
+
+
+
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigAutowiringInfoProvider.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigAutowiringInfoProvider.php
new file mode 100644
index 000000000000..70932b631cad
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigAutowiringInfoProvider.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\TwigBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoProviderInterface;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
+use Twig\Environment;
+
+/**
+ * @author Ryan Weaver
+ */
+final class TwigAutowiringInfoProvider implements AutowiringInfoProviderInterface
+{
+ public function getTypeInfos(): array
+ {
+ return [
+ AutowiringTypeInfo::create(Environment::class, 'Twig Templating')
+ ->setDescription('use to render templates'),
+ ];
+ }
+}
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index fca4367ba743..1463641d99bf 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -153,5 +153,9 @@
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoManager.php b/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoManager.php
new file mode 100644
index 000000000000..68a84be14e76
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoManager.php
@@ -0,0 +1,55 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Debug;
+
+/**
+ * @author Ryan Weaver
+ */
+final class AutowiringInfoManager
+{
+ /**
+ * @var AutowiringInfoProviderInterface[]
+ */
+ private $autowiringInfoProviders;
+
+ private $typeInfos = null;
+
+ public function __construct(array $autowiringInfoProviders)
+ {
+ $this->autowiringInfoProviders = $autowiringInfoProviders;
+ }
+
+ /**
+ * @param string $type
+ * @return AutowiringTypeInfo|null
+ */
+ public function getInfo(string $type)
+ {
+ if (null === $this->typeInfos) {
+ $this->populateTypesInfo();
+ }
+
+ return isset($this->typeInfos[$type]) ? $this->typeInfos[$type] : null;
+ }
+
+ private function populateTypesInfo()
+ {
+ $typeInfos = array();
+ foreach ($this->autowiringInfoProviders as $provider) {
+ foreach ($provider->getTypeInfos() as $typeInfo) {
+ $typeInfos[$typeInfo->getType()] = $typeInfo;
+ }
+ }
+
+ $this->typeInfos = $typeInfos;
+ }
+}
\ No newline at end of file
diff --git a/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoProviderInterface.php b/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoProviderInterface.php
new file mode 100644
index 000000000000..a6d8e806a3cf
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Debug/AutowiringInfoProviderInterface.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Debug;
+
+/**
+ * Interface for classes that can provide info about the purpose of service classes/interfaces.
+ *
+ * @author Ryan Weaver
+ */
+interface AutowiringInfoProviderInterface
+{
+ /**
+ * Returns information about autowiring types.
+ *
+ * @return array|AutowiringTypeInfo[]
+ */
+ public function getTypeInfos(): array;
+}
diff --git a/src/Symfony/Component/DependencyInjection/Debug/AutowiringTypeInfo.php b/src/Symfony/Component/DependencyInjection/Debug/AutowiringTypeInfo.php
new file mode 100644
index 000000000000..5bb533152269
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Debug/AutowiringTypeInfo.php
@@ -0,0 +1,71 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Debug;
+
+/**
+ * @author Ryan Weaver
+ */
+final class AutowiringTypeInfo
+{
+ private $type;
+
+ private $name;
+
+ private $priority;
+
+ private $description = '';
+
+ public function __construct(string $type, string $name, int $priority = 0)
+ {
+ $this->type = $type;
+ $this->name = $name;
+ $this->priority = $priority;
+ }
+
+ /**
+ * @param string $type The class/interface for the type
+ * @param string $name A very short name to describe this (e.g. Logger or Annotation Reader)
+ * @param int $priority A priority for how important this service is
+ * @return static
+ */
+ public static function create(string $type, string $name, int $priority = 0)
+ {
+ return new static($type, $name, $priority);
+ }
+
+ public function getType(): string
+ {
+ return $this->type;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getPriority(): int
+ {
+ return $this->priority;
+ }
+
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+
+ public function setDescription(string $description): self
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringInfoManagerTest.php b/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringInfoManagerTest.php
new file mode 100644
index 000000000000..10b1c0350f78
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringInfoManagerTest.php
@@ -0,0 +1,44 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Tests\Debug;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoManager;
+use Symfony\Component\DependencyInjection\Debug\AutowiringInfoProviderInterface;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
+
+class AutowiringInfoManagerTest extends TestCase
+{
+ public function testGetInfo()
+ {
+ $infoFoo = AutowiringTypeInfo::create('FooInterface', 'Foo');
+ $infoBar = AutowiringTypeInfo::create('BarInterface', 'Bar');
+ $infoBaz = AutowiringTypeInfo::create('BazInterface', 'Baz');
+
+ $provider1 = $this->createMock(AutowiringInfoProviderInterface::class);
+ $provider1->expects($this->once())
+ ->method('getTypeInfos')
+ ->willReturn([$infoFoo, $infoBar]);
+
+ $provider2 = $this->createMock(AutowiringInfoProviderInterface::class);
+ $provider2->expects($this->once())
+ ->method('getTypeInfos')
+ ->willReturn([$infoBaz]);
+
+ $manager = new AutowiringInfoManager([$provider1, $provider2]);
+ $this->assertSame($infoFoo, $manager->getInfo('FooInterface'));
+ $this->assertSame($infoBar, $manager->getInfo('BarInterface'));
+ $this->assertSame($infoBaz, $manager->getInfo('BazInterface'));
+ $this->assertNull($manager->getInfo('InventedClass'));
+
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringTypeInfoTest.php b/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringTypeInfoTest.php
new file mode 100644
index 000000000000..df8881de0bfc
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Debug/AutowiringTypeInfoTest.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Tests\Debug;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\DependencyInjection\Debug\AutowiringTypeInfo;
+
+class AutowiringTypeInfoTest extends TestCase
+{
+ public function testBasicFunctionality()
+ {
+ $info = AutowiringTypeInfo::create('Foo\\CoolStuffType', 'Cool Stuff');
+ $this->assertSame($info->getType(), 'Foo\\CoolStuffType');
+ $this->assertSame($info->getName(), 'Cool Stuff');
+ $this->assertSame(0, $info->getPriority());
+ $this->assertSame('', $info->getDescription());
+
+ $info = AutowiringTypeInfo::create('Foo\\CoolStuffType', 'Cool Stuff', 10)
+ ->setDescription('Some really cool stuff');
+
+ $this->assertSame(10, $info->getPriority());
+ $this->assertSame('Some really cool stuff', $info->getDescription());
+ }
+}