[
  {
    "path": ".gitattributes",
    "content": "/Tests export-ignore\n/phpunit.xml.dist export-ignore\n/.git* export-ignore\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Please do not submit any Pull Requests here. They will be closed.\n---\n\nPlease submit your PR here instead:\nhttps://github.com/symfony/symfony\n\nThis repository is what we call a \"subtree split\": a read-only subset of that main repository.\nWe're looking forward to your PR there!\n"
  },
  {
    "path": ".github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: |\n          Thanks for your Pull Request! We love contributions.\n\n          However, you should instead open your PR on the main repository:\n          https://github.com/symfony/symfony\n\n          This repository is what we call a \"subtree split\": a read-only subset of that main repository.\n          We're looking forward to your PR there!\n"
  },
  {
    "path": ".gitignore",
    "content": "vendor/\ncomposer.lock\nphpunit.xml\n"
  },
  {
    "path": "Attribute/AsEventListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Attribute;\n\n/**\n * Service tag to autoconfigure event listeners.\n *\n * @author Alexander M. Turek <me@derrabus.de>\n */\n#[\\Attribute(\\Attribute::TARGET_CLASS | \\Attribute::TARGET_METHOD | \\Attribute::IS_REPEATABLE)]\nclass AsEventListener\n{\n    /**\n     * @param string|null $event      The event name to listen to\n     * @param string|null $method     The method to run when the listened event is triggered\n     * @param int         $priority   The priority of this listener if several are declared for the same event\n     * @param string|null $dispatcher The service id of the event dispatcher to listen to\n     */\n    public function __construct(\n        public ?string $event = null,\n        public ?string $method = null,\n        public int $priority = 0,\n        public ?string $dispatcher = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n6.0\n---\n\n * Remove `LegacyEventDispatcherProxy`\n\n5.4\n---\n\n * Allow `#[AsEventListener]` attribute on methods\n\n5.3\n---\n\n * Add `#[AsEventListener]` attribute for declaring listeners on PHP 8\n\n5.1.0\n-----\n\n * The `LegacyEventDispatcherProxy` class has been deprecated.\n * Added an optional `dispatcher` attribute to the listener and subscriber tags in `RegisterListenerPass`.\n\n5.0.0\n-----\n\n * The signature of the `EventDispatcherInterface::dispatch()` method has been changed to `dispatch($event, string $eventName = null): object`.\n * The `Event` class has been removed in favor of `Symfony\\Contracts\\EventDispatcher\\Event`.\n * The `TraceableEventDispatcherInterface` has been removed.\n * The `WrappedListener` class is now final.\n\n4.4.0\n-----\n\n * `AddEventAliasesPass` has been added, allowing applications and bundles to extend the event alias mapping used by `RegisterListenersPass`.\n * Made the `event` attribute of the `kernel.event_listener` tag optional for FQCN events.\n\n4.3.0\n-----\n\n * The signature of the `EventDispatcherInterface::dispatch()` method should be updated to `dispatch($event, string $eventName = null)`, not doing so is deprecated\n * deprecated the `Event` class, use `Symfony\\Contracts\\EventDispatcher\\Event` instead\n\n4.1.0\n-----\n\n * added support for invokable event listeners tagged with `kernel.event_listener` by default\n * The `TraceableEventDispatcher::getOrphanedEvents()` method has been added.\n * The `TraceableEventDispatcherInterface` has been deprecated.\n\n4.0.0\n-----\n\n * removed the `ContainerAwareEventDispatcher` class\n * added the `reset()` method to the `TraceableEventDispatcherInterface`\n\n3.4.0\n-----\n\n * Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated.\n\n3.3.0\n-----\n\n * The ContainerAwareEventDispatcher class has been deprecated. Use EventDispatcher with closure factories instead.\n\n3.0.0\n-----\n\n * The method `getListenerPriority($eventName, $listener)` has been added to the\n   `EventDispatcherInterface`.\n * The methods `Event::setDispatcher()`, `Event::getDispatcher()`, `Event::setName()`\n   and `Event::getName()` have been removed.\n   The event dispatcher and the event name are passed to the listener call.\n\n2.5.0\n-----\n\n * added Debug\\TraceableEventDispatcher (originally in HttpKernel)\n * changed Debug\\TraceableEventDispatcherInterface to extend EventDispatcherInterface\n * added RegisterListenersPass (originally in HttpKernel)\n\n2.1.0\n-----\n\n * added TraceableEventDispatcherInterface\n * added ContainerAwareEventDispatcher\n * added a reference to the EventDispatcher on the Event\n * added a reference to the Event name on the event\n * added fluid interface to the dispatch() method which now returns the Event\n   object\n * added GenericEvent event class\n * added the possibility for subscribers to subscribe several times for the\n   same event\n * added ImmutableEventDispatcher\n"
  },
  {
    "path": "Debug/TraceableEventDispatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Debug;\n\nuse Psr\\EventDispatcher\\StoppableEventInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\RequestStack;\nuse Symfony\\Component\\Stopwatch\\Stopwatch;\nuse Symfony\\Contracts\\Service\\ResetInterface;\n\n/**\n * Collects some data about event listeners.\n *\n * This event dispatcher delegates the dispatching to another one.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TraceableEventDispatcher implements EventDispatcherInterface, ResetInterface\n{\n    /**\n     * @var \\SplObjectStorage<WrappedListener, array{string, string}>|null\n     */\n    private ?\\SplObjectStorage $callStack = null;\n    private array $wrappedListeners = [];\n    private array $orphanedEvents = [];\n    private string $currentRequestHash = '';\n\n    public function __construct(\n        private EventDispatcherInterface $dispatcher,\n        protected Stopwatch $stopwatch,\n        protected ?LoggerInterface $logger = null,\n        private ?RequestStack $requestStack = null,\n        protected readonly ?\\Closure $disabled = null,\n    ) {\n    }\n\n    public function addListener(string $eventName, callable|array $listener, int $priority = 0): void\n    {\n        $this->dispatcher->addListener($eventName, $listener, $priority);\n    }\n\n    public function addSubscriber(EventSubscriberInterface $subscriber): void\n    {\n        $this->dispatcher->addSubscriber($subscriber);\n    }\n\n    public function removeListener(string $eventName, callable|array $listener): void\n    {\n        if (isset($this->wrappedListeners[$eventName])) {\n            foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {\n                if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \\Closure && $wrappedListener->getWrappedListener() == $listener)) {\n                    $listener = $wrappedListener;\n                    unset($this->wrappedListeners[$eventName][$index]);\n                    break;\n                }\n            }\n        }\n\n        $this->dispatcher->removeListener($eventName, $listener);\n    }\n\n    public function removeSubscriber(EventSubscriberInterface $subscriber): void\n    {\n        $this->dispatcher->removeSubscriber($subscriber);\n    }\n\n    public function getListeners(?string $eventName = null): array\n    {\n        return $this->dispatcher->getListeners($eventName);\n    }\n\n    public function getListenerPriority(string $eventName, callable|array $listener): ?int\n    {\n        // we might have wrapped listeners for the event (if called while dispatching)\n        // in that case get the priority by wrapper\n        if (isset($this->wrappedListeners[$eventName])) {\n            foreach ($this->wrappedListeners[$eventName] as $wrappedListener) {\n                if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \\Closure && $wrappedListener->getWrappedListener() == $listener)) {\n                    return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);\n                }\n            }\n        }\n\n        return $this->dispatcher->getListenerPriority($eventName, $listener);\n    }\n\n    public function hasListeners(?string $eventName = null): bool\n    {\n        return $this->dispatcher->hasListeners($eventName);\n    }\n\n    public function dispatch(object $event, ?string $eventName = null): object\n    {\n        if ($this->disabled?->__invoke()) {\n            return $this->dispatcher->dispatch($event, $eventName);\n        }\n        $eventName ??= $event::class;\n\n        $this->callStack ??= new \\SplObjectStorage();\n\n        $currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : '';\n\n        if (null !== $this->logger && $event instanceof StoppableEventInterface && $event->isPropagationStopped()) {\n            $this->logger->debug(\\sprintf('The \"%s\" event is already stopped. No listeners have been called.', $eventName));\n        }\n\n        $this->preProcess($eventName);\n        try {\n            $this->beforeDispatch($eventName, $event);\n            try {\n                $e = $this->stopwatch->start($eventName, 'section');\n                try {\n                    $this->dispatcher->dispatch($event, $eventName);\n                } finally {\n                    if ($e->isStarted()) {\n                        $e->stop();\n                    }\n                }\n            } finally {\n                $this->afterDispatch($eventName, $event);\n            }\n        } finally {\n            $this->currentRequestHash = $currentRequestHash;\n            $this->postProcess($eventName);\n        }\n\n        return $event;\n    }\n\n    public function getCalledListeners(?Request $request = null): array\n    {\n        if (null === $this->callStack) {\n            return [];\n        }\n\n        $hash = $request ? spl_object_hash($request) : null;\n        $called = [];\n        foreach ($this->callStack as $listener) {\n            [$eventName, $requestHash] = $this->callStack->getInfo();\n            if (null === $hash || $hash === $requestHash) {\n                $called[] = $listener->getInfo($eventName);\n            }\n        }\n\n        return $called;\n    }\n\n    public function getNotCalledListeners(?Request $request = null): array\n    {\n        try {\n            $allListeners = $this->dispatcher instanceof EventDispatcher ? $this->getListenersWithPriority() : $this->getListenersWithoutPriority();\n        } catch (\\Exception $e) {\n            $this->logger?->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]);\n\n            // unable to retrieve the uncalled listeners\n            return [];\n        }\n\n        $hash = $request ? spl_object_hash($request) : null;\n        $calledListeners = [];\n\n        if (null !== $this->callStack) {\n            foreach ($this->callStack as $calledListener) {\n                [, $requestHash] = $this->callStack->getInfo();\n\n                if (null === $hash || $hash === $requestHash) {\n                    $calledListeners[] = $calledListener->getWrappedListener();\n                }\n            }\n        }\n\n        $notCalled = [];\n\n        foreach ($allListeners as $eventName => $listeners) {\n            foreach ($listeners as [$listener, $priority]) {\n                if (!\\in_array($listener, $calledListeners, true)) {\n                    if (!$listener instanceof WrappedListener) {\n                        $listener = new WrappedListener($listener, null, $this->stopwatch, $this, $priority);\n                    }\n                    $notCalled[] = $listener->getInfo($eventName);\n                }\n            }\n        }\n\n        uasort($notCalled, $this->sortNotCalledListeners(...));\n\n        return $notCalled;\n    }\n\n    public function getOrphanedEvents(?Request $request = null): array\n    {\n        if ($request) {\n            return $this->orphanedEvents[spl_object_hash($request)] ?? [];\n        }\n\n        if (!$this->orphanedEvents) {\n            return [];\n        }\n\n        return array_merge(...array_values($this->orphanedEvents));\n    }\n\n    public function reset(): void\n    {\n        $this->callStack = null;\n        $this->orphanedEvents = [];\n        $this->currentRequestHash = '';\n    }\n\n    /**\n     * Proxies all method calls to the original event dispatcher.\n     *\n     * @param string $method    The method name\n     * @param array  $arguments The method arguments\n     */\n    public function __call(string $method, array $arguments): mixed\n    {\n        return $this->dispatcher->{$method}(...$arguments);\n    }\n\n    /**\n     * Called before dispatching the event.\n     */\n    protected function beforeDispatch(string $eventName, object $event): void\n    {\n    }\n\n    /**\n     * Called after dispatching the event.\n     */\n    protected function afterDispatch(string $eventName, object $event): void\n    {\n    }\n\n    private function preProcess(string $eventName): void\n    {\n        if (!$this->dispatcher->hasListeners($eventName)) {\n            $this->orphanedEvents[$this->currentRequestHash][] = $eventName;\n\n            return;\n        }\n\n        foreach ($this->dispatcher->getListeners($eventName) as $listener) {\n            $priority = $this->getListenerPriority($eventName, $listener);\n            $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this);\n            $this->wrappedListeners[$eventName][] = $wrappedListener;\n            $this->dispatcher->removeListener($eventName, $listener);\n            $this->dispatcher->addListener($eventName, $wrappedListener, $priority);\n            $this->callStack[$wrappedListener] = [$eventName, $this->currentRequestHash];\n        }\n    }\n\n    private function postProcess(string $eventName): void\n    {\n        unset($this->wrappedListeners[$eventName]);\n        $skipped = false;\n        foreach ($this->dispatcher->getListeners($eventName) as $listener) {\n            if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.\n                continue;\n            }\n            // Unwrap listener\n            $priority = $this->getListenerPriority($eventName, $listener);\n            $this->dispatcher->removeListener($eventName, $listener);\n            $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority);\n\n            if (null !== $this->logger) {\n                $context = ['event' => $eventName, 'listener' => $listener->getPretty()];\n            }\n\n            if ($listener->wasCalled()) {\n                $this->logger?->debug('Notified event \"{event}\" to listener \"{listener}\".', $context);\n            } else {\n                unset($this->callStack[$listener]);\n            }\n\n            if (null !== $this->logger && $skipped) {\n                $this->logger->debug('Listener \"{listener}\" was not called for event \"{event}\".', $context);\n            }\n\n            if ($listener->stoppedPropagation()) {\n                $this->logger?->debug('Listener \"{listener}\" stopped propagation of the event \"{event}\".', $context);\n\n                $skipped = true;\n            }\n        }\n    }\n\n    private function sortNotCalledListeners(array $a, array $b): int\n    {\n        if (0 !== $cmp = strcmp($a['event'], $b['event'])) {\n            return $cmp;\n        }\n\n        if (\\is_int($a['priority']) && !\\is_int($b['priority'])) {\n            return 1;\n        }\n\n        if (!\\is_int($a['priority']) && \\is_int($b['priority'])) {\n            return -1;\n        }\n\n        if ($a['priority'] === $b['priority']) {\n            return 0;\n        }\n\n        if ($a['priority'] > $b['priority']) {\n            return -1;\n        }\n\n        return 1;\n    }\n\n    private function getListenersWithPriority(): array\n    {\n        $result = [];\n\n        $allListeners = new \\ReflectionProperty(EventDispatcher::class, 'listeners');\n\n        foreach ($allListeners->getValue($this->dispatcher) as $eventName => $listenersByPriority) {\n            foreach ($listenersByPriority as $priority => $listeners) {\n                foreach ($listeners as $listener) {\n                    $result[$eventName][] = [$listener, $priority];\n                }\n            }\n        }\n\n        return $result;\n    }\n\n    private function getListenersWithoutPriority(): array\n    {\n        $result = [];\n\n        foreach ($this->getListeners() as $eventName => $listeners) {\n            foreach ($listeners as $listener) {\n                $result[$eventName][] = [$listener, null];\n            }\n        }\n\n        return $result;\n    }\n}\n"
  },
  {
    "path": "Debug/WrappedListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Debug;\n\nuse Psr\\EventDispatcher\\StoppableEventInterface;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\Stopwatch\\Stopwatch;\nuse Symfony\\Component\\VarDumper\\Caster\\ClassStub;\n\n/**\n * @author Fabien Potencier <fabien@symfony.com>\n */\nfinal class WrappedListener\n{\n    private string|array|object $listener;\n    private ?\\Closure $optimizedListener;\n    private string $name;\n    private bool $called = false;\n    private bool $stoppedPropagation = false;\n    private string $pretty;\n    private string $callableRef;\n    private ClassStub|string $stub;\n    private static bool $hasClassStub;\n\n    public function __construct(\n        callable|array $listener,\n        ?string $name,\n        private Stopwatch $stopwatch,\n        private ?EventDispatcherInterface $dispatcher = null,\n        private ?int $priority = null,\n    ) {\n        $this->listener = $listener;\n        $this->optimizedListener = $listener instanceof \\Closure ? $listener : (\\is_callable($listener) ? $listener(...) : null);\n\n        if (\\is_array($listener)) {\n            [$this->name, $this->callableRef] = $this->parseListener($listener);\n            $this->pretty = $this->name.'::'.$listener[1];\n            $this->callableRef .= '::'.$listener[1];\n        } elseif ($listener instanceof \\Closure) {\n            $r = new \\ReflectionFunction($listener);\n            if ($r->isAnonymous()) {\n                $this->pretty = $this->name = 'closure';\n            } elseif ($class = $r->getClosureCalledClass()) {\n                $this->name = $class->name;\n                $this->pretty = $this->name.'::'.$r->name;\n            } else {\n                $this->pretty = $this->name = $r->name;\n            }\n        } elseif (\\is_string($listener)) {\n            $this->pretty = $this->name = $listener;\n        } else {\n            $this->name = get_debug_type($listener);\n            $this->pretty = $this->name.'::__invoke';\n            $this->callableRef = $listener::class.'::__invoke';\n        }\n\n        if (null !== $name) {\n            $this->name = $name;\n        }\n\n        self::$hasClassStub ??= class_exists(ClassStub::class);\n    }\n\n    public function getWrappedListener(): callable|array\n    {\n        return $this->listener;\n    }\n\n    public function wasCalled(): bool\n    {\n        return $this->called;\n    }\n\n    public function stoppedPropagation(): bool\n    {\n        return $this->stoppedPropagation;\n    }\n\n    public function getPretty(): string\n    {\n        return $this->pretty;\n    }\n\n    public function getInfo(string $eventName): array\n    {\n        $this->stub ??= self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->callableRef ?? $this->listener) : $this->pretty.'()';\n\n        return [\n            'event' => $eventName,\n            'priority' => $this->priority ??= $this->dispatcher?->getListenerPriority($eventName, $this->listener),\n            'pretty' => $this->pretty,\n            'stub' => $this->stub,\n        ];\n    }\n\n    public function __invoke(object $event, string $eventName, EventDispatcherInterface $dispatcher): void\n    {\n        $dispatcher = $this->dispatcher ?: $dispatcher;\n\n        $this->called = true;\n        $this->priority ??= $dispatcher->getListenerPriority($eventName, $this->listener);\n\n        $e = $this->stopwatch->start($this->name, 'event_listener');\n\n        try {\n            ($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);\n        } finally {\n            if ($e->isStarted()) {\n                $e->stop();\n            }\n        }\n\n        if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {\n            $this->stoppedPropagation = true;\n        }\n    }\n\n    private function parseListener(array $listener): array\n    {\n        if ($listener[0] instanceof \\Closure) {\n            foreach ((new \\ReflectionFunction($listener[0]))->getAttributes(\\Closure::class) as $attribute) {\n                if ($name = $attribute->getArguments()['name'] ?? false) {\n                    return [$name, $attribute->getArguments()['class'] ?? $name];\n                }\n            }\n        }\n\n        if (\\is_object($listener[0])) {\n            return [get_debug_type($listener[0]), $listener[0]::class];\n        }\n\n        return [$listener[0], $listener[0]];\n    }\n}\n"
  },
  {
    "path": "DependencyInjection/AddEventAliasesPass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\DependencyInjection;\n\nuse Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\n\n/**\n * This pass allows bundles to extend the list of event aliases.\n *\n * @author Alexander M. Turek <me@derrabus.de>\n */\nclass AddEventAliasesPass implements CompilerPassInterface\n{\n    public function __construct(\n        private array $eventAliases,\n    ) {\n    }\n\n    public function process(ContainerBuilder $container): void\n    {\n        $eventAliases = $container->hasParameter('event_dispatcher.event_aliases') ? $container->getParameter('event_dispatcher.event_aliases') : [];\n\n        $container->setParameter(\n            'event_dispatcher.event_aliases',\n            array_merge($eventAliases, $this->eventAliases)\n        );\n    }\n}\n"
  },
  {
    "path": "DependencyInjection/RegisterListenersPass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\DependencyInjection;\n\nuse Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument;\nuse Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\DependencyInjection\\Reference;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Contracts\\EventDispatcher\\Event;\n\n/**\n * Compiler pass to register tagged services for an event dispatcher.\n */\nclass RegisterListenersPass implements CompilerPassInterface\n{\n    private array $hotPathEvents = [];\n    private array $noPreloadEvents = [];\n\n    /**\n     * @return $this\n     */\n    public function setHotPathEvents(array $hotPathEvents): static\n    {\n        $this->hotPathEvents = array_flip($hotPathEvents);\n\n        return $this;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setNoPreloadEvents(array $noPreloadEvents): static\n    {\n        $this->noPreloadEvents = array_flip($noPreloadEvents);\n\n        return $this;\n    }\n\n    public function process(ContainerBuilder $container): void\n    {\n        if (!$container->hasDefinition('event_dispatcher') && !$container->hasAlias('event_dispatcher')) {\n            return;\n        }\n\n        $aliases = [];\n\n        if ($container->hasParameter('event_dispatcher.event_aliases')) {\n            $aliases = $container->getParameter('event_dispatcher.event_aliases');\n        }\n\n        $globalDispatcherDefinition = $container->findDefinition('event_dispatcher');\n\n        foreach ($container->findTaggedServiceIds('kernel.event_listener', true) as $id => $events) {\n            $noPreload = 0;\n\n            $resolvedEvents = [];\n            foreach ($events as $event) {\n                if (!isset($event['event'])) {\n                    if ($container->getDefinition($id)->hasTag('kernel.event_subscriber')) {\n                        continue;\n                    }\n\n                    $event['method'] ??= '__invoke';\n                    $eventNames = $this->getEventFromTypeDeclaration($container, $id, $event['method']);\n                } else {\n                    $eventNames = [$event['event']];\n                }\n\n                foreach ($eventNames as $eventName) {\n                    $event['event'] = $aliases[$eventName] ?? $eventName;\n                    $resolvedEvents[] = $event;\n                }\n            }\n\n            foreach ($resolvedEvents as $event) {\n                $priority = $event['priority'] ?? 0;\n\n                if (!isset($event['method'])) {\n                    $event['method'] = 'on'.preg_replace_callback([\n                        '/(?<=\\b|_)[a-z]/i',\n                        '/[^a-z0-9]/i',\n                    ], static fn ($matches) => strtoupper($matches[0]), $event['event']);\n                    $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);\n\n                    if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) {\n                        if (!$r->hasMethod('__invoke')) {\n                            throw new InvalidArgumentException(\\sprintf('None of the \"%s\" or \"__invoke\" methods exist for the service \"%s\". Please define the \"method\" attribute on \"kernel.event_listener\" tags.', $event['method'], $id));\n                        }\n\n                        $event['method'] = '__invoke';\n                    }\n                }\n\n                $dispatcherDefinition = $globalDispatcherDefinition;\n                if (isset($event['dispatcher'])) {\n                    $dispatcherDefinition = $container->findDefinition($event['dispatcher']);\n                }\n\n                $dispatcherDefinition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]);\n\n                if (isset($this->hotPathEvents[$event['event']])) {\n                    $container->getDefinition($id)->addTag('container.hot_path');\n                } elseif (isset($this->noPreloadEvents[$event['event']])) {\n                    ++$noPreload;\n                }\n            }\n\n            if ($noPreload && \\count($events) === $noPreload) {\n                $container->getDefinition($id)->addTag('container.no_preload');\n            }\n        }\n\n        $extractingDispatcher = new ExtractingEventDispatcher();\n\n        foreach ($container->findTaggedServiceIds('kernel.event_subscriber', true) as $id => $tags) {\n            $def = $container->getDefinition($id);\n\n            // We must assume that the class value has been correctly filled, even if the service is created by a factory\n            $class = $def->getClass();\n\n            if (!$r = $container->getReflectionClass($class)) {\n                throw new InvalidArgumentException(\\sprintf('Class \"%s\" used for service \"%s\" cannot be found.', $class, $id));\n            }\n            if (!$r->isSubclassOf(EventSubscriberInterface::class)) {\n                throw new InvalidArgumentException(\\sprintf('Service \"%s\" must implement interface \"%s\".', $id, EventSubscriberInterface::class));\n            }\n            $class = $r->name;\n\n            $dispatcherDefinitions = [];\n            foreach ($tags as $attributes) {\n                if (!isset($attributes['dispatcher']) || isset($dispatcherDefinitions[$attributes['dispatcher']])) {\n                    continue;\n                }\n\n                $dispatcherDefinitions[$attributes['dispatcher']] = $container->findDefinition($attributes['dispatcher']);\n            }\n\n            if (!$dispatcherDefinitions) {\n                $dispatcherDefinitions = [$globalDispatcherDefinition];\n            }\n\n            $noPreload = 0;\n            ExtractingEventDispatcher::$aliases = $aliases;\n            ExtractingEventDispatcher::$subscriber = $class;\n            $extractingDispatcher->addSubscriber($extractingDispatcher);\n            foreach ($extractingDispatcher->listeners as $args) {\n                $args[1] = [new ServiceClosureArgument(new Reference($id)), $args[1]];\n                foreach ($dispatcherDefinitions as $dispatcherDefinition) {\n                    $dispatcherDefinition->addMethodCall('addListener', $args);\n                }\n\n                if (isset($this->hotPathEvents[$args[0]])) {\n                    $container->getDefinition($id)->addTag('container.hot_path');\n                } elseif (isset($this->noPreloadEvents[$args[0]])) {\n                    ++$noPreload;\n                }\n            }\n            if ($noPreload && \\count($extractingDispatcher->listeners) === $noPreload) {\n                $container->getDefinition($id)->addTag('container.no_preload');\n            }\n            $extractingDispatcher->listeners = [];\n            ExtractingEventDispatcher::$aliases = [];\n        }\n    }\n\n    /**\n     * @return string[]\n     */\n    private function getEventFromTypeDeclaration(ContainerBuilder $container, string $id, string $method): array\n    {\n        if (\n            null === ($class = $container->getDefinition($id)->getClass())\n            || !($r = $container->getReflectionClass($class, false))\n            || !$r->hasMethod($method)\n            || 1 > ($m = $r->getMethod($method))->getNumberOfParameters()\n            || !(($type = $m->getParameters()[0]->getType()) instanceof \\ReflectionNamedType || $type instanceof \\ReflectionUnionType)\n        ) {\n            throw new InvalidArgumentException(\\sprintf('Service \"%s\" must define the \"event\" attribute on \"kernel.event_listener\" tags.', $id));\n        }\n\n        $types = $type instanceof \\ReflectionUnionType ? $type->getTypes() : [$type];\n\n        $names = [];\n        foreach ($types as $type) {\n            if (!$type instanceof \\ReflectionNamedType\n                || $type->isBuiltin()\n                || Event::class === ($name = $type->getName())\n            ) {\n                continue;\n            }\n\n            $names[] = $name;\n        }\n\n        if (!$names) {\n            throw new InvalidArgumentException(\\sprintf('Service \"%s\" must define the \"event\" attribute on \"kernel.event_listener\" tags.', $id));\n        }\n\n        return $names;\n    }\n}\n\n/**\n * @internal\n */\nclass ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface\n{\n    public array $listeners = [];\n\n    public static array $aliases = [];\n    public static string $subscriber;\n\n    public function addListener(string $eventName, callable|array $listener, int $priority = 0): void\n    {\n        $this->listeners[] = [$eventName, $listener[1], $priority];\n    }\n\n    public static function getSubscribedEvents(): array\n    {\n        $events = [];\n\n        foreach ([self::$subscriber, 'getSubscribedEvents']() as $eventName => $params) {\n            $events[self::$aliases[$eventName] ?? $eventName] = $params;\n        }\n\n        return $events;\n    }\n}\n"
  },
  {
    "path": "EventDispatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher;\n\nuse Psr\\EventDispatcher\\StoppableEventInterface;\nuse Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener;\n\n/**\n * The EventDispatcherInterface is the central point of Symfony's event listener system.\n *\n * Listeners are registered on the manager and events are dispatched through the\n * manager.\n *\n * @author Guilherme Blanco <guilhermeblanco@hotmail.com>\n * @author Jonathan Wage <jonwage@gmail.com>\n * @author Roman Borschel <roman@code-factory.org>\n * @author Bernhard Schussek <bschussek@gmail.com>\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Jordi Boggiano <j.boggiano@seld.be>\n * @author Jordan Alliot <jordan.alliot@gmail.com>\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass EventDispatcher implements EventDispatcherInterface\n{\n    private array $listeners = [];\n    private array $sorted = [];\n    private array $optimized;\n\n    public function __construct()\n    {\n        if (__CLASS__ === static::class) {\n            $this->optimized = [];\n        }\n    }\n\n    public function dispatch(object $event, ?string $eventName = null): object\n    {\n        $eventName ??= $event::class;\n\n        if (isset($this->optimized)) {\n            $listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName));\n        } else {\n            $listeners = $this->getListeners($eventName);\n        }\n\n        if ($listeners) {\n            $this->callListeners($listeners, $eventName, $event);\n        }\n\n        return $event;\n    }\n\n    public function getListeners(?string $eventName = null): array\n    {\n        if (null !== $eventName) {\n            if (empty($this->listeners[$eventName])) {\n                return [];\n            }\n\n            if (!isset($this->sorted[$eventName])) {\n                $this->sortListeners($eventName);\n            }\n\n            return $this->sorted[$eventName];\n        }\n\n        foreach ($this->listeners as $eventName => $eventListeners) {\n            if (!isset($this->sorted[$eventName])) {\n                $this->sortListeners($eventName);\n            }\n        }\n\n        return array_filter($this->sorted);\n    }\n\n    public function getListenerPriority(string $eventName, callable|array $listener): ?int\n    {\n        if (empty($this->listeners[$eventName])) {\n            return null;\n        }\n\n        if (\\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \\Closure && 2 >= \\count($listener)) {\n            $listener[0] = $listener[0]();\n            $listener[1] ??= '__invoke';\n        }\n\n        foreach ($this->listeners[$eventName] as $priority => &$listeners) {\n            foreach ($listeners as &$v) {\n                if ($v !== $listener && \\is_array($v) && isset($v[0]) && $v[0] instanceof \\Closure && 2 >= \\count($v)) {\n                    $v[0] = $v[0]();\n                    $v[1] ??= '__invoke';\n                }\n                if ($v === $listener || ($listener instanceof \\Closure && $v == $listener)) {\n                    return $priority;\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public function hasListeners(?string $eventName = null): bool\n    {\n        if (null !== $eventName) {\n            return !empty($this->listeners[$eventName]);\n        }\n\n        foreach ($this->listeners as $eventListeners) {\n            if ($eventListeners) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    public function addListener(string $eventName, callable|array $listener, int $priority = 0): void\n    {\n        $this->listeners[$eventName][$priority][] = $listener;\n        unset($this->sorted[$eventName], $this->optimized[$eventName]);\n    }\n\n    public function removeListener(string $eventName, callable|array $listener): void\n    {\n        if (empty($this->listeners[$eventName])) {\n            return;\n        }\n\n        if (\\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \\Closure && 2 >= \\count($listener)) {\n            $listener[0] = $listener[0]();\n            $listener[1] ??= '__invoke';\n        }\n\n        foreach ($this->listeners[$eventName] as $priority => &$listeners) {\n            foreach ($listeners as $k => &$v) {\n                if ($v !== $listener && \\is_array($v) && isset($v[0]) && $v[0] instanceof \\Closure && 2 >= \\count($v)) {\n                    $v[0] = $v[0]();\n                    $v[1] ??= '__invoke';\n                }\n                if ($v === $listener || ($listener instanceof \\Closure && $v == $listener)) {\n                    unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);\n                }\n            }\n\n            if (!$listeners) {\n                unset($this->listeners[$eventName][$priority]);\n            }\n        }\n    }\n\n    public function addSubscriber(EventSubscriberInterface $subscriber): void\n    {\n        foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {\n            if (\\is_string($params)) {\n                $this->addListener($eventName, [$subscriber, $params]);\n            } elseif (\\is_string($params[0])) {\n                $this->addListener($eventName, [$subscriber, $params[0]], $params[1] ?? 0);\n            } else {\n                foreach ($params as $listener) {\n                    $this->addListener($eventName, [$subscriber, $listener[0]], $listener[1] ?? 0);\n                }\n            }\n        }\n    }\n\n    public function removeSubscriber(EventSubscriberInterface $subscriber): void\n    {\n        foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {\n            if (\\is_array($params) && \\is_array($params[0])) {\n                foreach ($params as $listener) {\n                    $this->removeListener($eventName, [$subscriber, $listener[0]]);\n                }\n            } else {\n                $this->removeListener($eventName, [$subscriber, \\is_string($params) ? $params : $params[0]]);\n            }\n        }\n    }\n\n    /**\n     * Triggers the listeners of an event.\n     *\n     * This method can be overridden to add functionality that is executed\n     * for each listener.\n     *\n     * @param callable[] $listeners The event listeners\n     * @param string     $eventName The name of the event to dispatch\n     * @param object     $event     The event object to pass to the event handlers/listeners\n     */\n    protected function callListeners(iterable $listeners, string $eventName, object $event): void\n    {\n        $stoppable = $event instanceof StoppableEventInterface;\n\n        foreach ($listeners as $listener) {\n            if ($stoppable && $event->isPropagationStopped()) {\n                break;\n            }\n            $listener($event, $eventName, $this);\n        }\n    }\n\n    /**\n     * Sorts the internal list of listeners for the given event by priority.\n     */\n    private function sortListeners(string $eventName): void\n    {\n        krsort($this->listeners[$eventName]);\n        $this->sorted[$eventName] = [];\n\n        foreach ($this->listeners[$eventName] as &$listeners) {\n            foreach ($listeners as &$listener) {\n                if (\\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \\Closure && 2 >= \\count($listener)) {\n                    $listener[0] = $listener[0]();\n                    $listener[1] ??= '__invoke';\n                }\n                $this->sorted[$eventName][] = $listener;\n            }\n        }\n    }\n\n    /**\n     * Optimizes the internal list of listeners for the given event by priority.\n     */\n    private function optimizeListeners(string $eventName): array\n    {\n        krsort($this->listeners[$eventName]);\n        $this->optimized[$eventName] = [];\n\n        foreach ($this->listeners[$eventName] as &$listeners) {\n            foreach ($listeners as &$listener) {\n                $closure = &$this->optimized[$eventName][];\n                if (\\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \\Closure && 2 >= \\count($listener)) {\n                    $closure = static function (...$args) use (&$listener, &$closure) {\n                        if ($listener[0] instanceof \\Closure) {\n                            $listener[0] = $listener[0]();\n                            $listener[1] ??= '__invoke';\n                        }\n                        ($closure = $listener(...))(...$args);\n                    };\n                } else {\n                    $closure = $listener instanceof WrappedListener ? $listener : $listener(...);\n                }\n            }\n        }\n\n        return $this->optimized[$eventName];\n    }\n}\n"
  },
  {
    "path": "EventDispatcherInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher;\n\nuse Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface as ContractsEventDispatcherInterface;\n\n/**\n * The EventDispatcherInterface is the central point of Symfony's event listener system.\n * Listeners are registered on the manager and events are dispatched through the\n * manager.\n *\n * @author Bernhard Schussek <bschussek@gmail.com>\n */\ninterface EventDispatcherInterface extends ContractsEventDispatcherInterface\n{\n    /**\n     * Adds an event listener that listens on the specified events.\n     *\n     * @param int $priority The higher this value, the earlier an event\n     *                      listener will be triggered in the chain (defaults to 0)\n     */\n    public function addListener(string $eventName, callable $listener, int $priority = 0): void;\n\n    /**\n     * Adds an event subscriber.\n     *\n     * The subscriber is asked for all the events it is\n     * interested in and added as a listener for these events.\n     */\n    public function addSubscriber(EventSubscriberInterface $subscriber): void;\n\n    /**\n     * Removes an event listener from the specified events.\n     */\n    public function removeListener(string $eventName, callable $listener): void;\n\n    public function removeSubscriber(EventSubscriberInterface $subscriber): void;\n\n    /**\n     * Gets the listeners of a specific event or all listeners sorted by descending priority.\n     *\n     * @return ($eventName is null ? array<callable[]> : array<callable>)\n     */\n    public function getListeners(?string $eventName = null): array;\n\n    /**\n     * Gets the listener priority for a specific event.\n     *\n     * Returns null if the event or the listener does not exist.\n     */\n    public function getListenerPriority(string $eventName, callable $listener): ?int;\n\n    /**\n     * Checks whether an event has any registered listeners.\n     */\n    public function hasListeners(?string $eventName = null): bool;\n}\n"
  },
  {
    "path": "EventSubscriberInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher;\n\n/**\n * An EventSubscriber knows itself what events it is interested in.\n * If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes\n * {@link getSubscribedEvents} and registers the subscriber as a listener for all\n * returned events.\n *\n * @author Guilherme Blanco <guilhermeblanco@hotmail.com>\n * @author Jonathan Wage <jonwage@gmail.com>\n * @author Roman Borschel <roman@code-factory.org>\n * @author Bernhard Schussek <bschussek@gmail.com>\n */\ninterface EventSubscriberInterface\n{\n    /**\n     * Returns an array of event names this subscriber wants to listen to.\n     *\n     * The array keys are event names and the value can be:\n     *\n     *  * The method name to call (priority defaults to 0)\n     *  * An array composed of the method name to call and the priority\n     *  * An array of arrays composed of the method names to call and respective\n     *    priorities, or 0 if unset\n     *\n     * For instance:\n     *\n     *  * ['eventName' => 'methodName']\n     *  * ['eventName' => ['methodName', $priority]]\n     *  * ['eventName' => [['methodName1', $priority], ['methodName2']]]\n     *\n     * The code must not depend on runtime state as it will only be called at compile time.\n     * All logic depending on runtime state must be put into the individual methods handling the events.\n     *\n     * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>\n     */\n    public static function getSubscribedEvents(): array;\n}\n"
  },
  {
    "path": "GenericEvent.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher;\n\nuse Symfony\\Contracts\\EventDispatcher\\Event;\n\n/**\n * Event encapsulation class.\n *\n * Encapsulates events thus decoupling the observer from the subject they encapsulate.\n *\n * @author Drak <drak@zikula.org>\n *\n * @implements \\ArrayAccess<string, mixed>\n * @implements \\IteratorAggregate<string, mixed>\n */\nclass GenericEvent extends Event implements \\ArrayAccess, \\IteratorAggregate\n{\n    /**\n     * Encapsulate an event with $subject and $arguments.\n     *\n     * @param mixed $subject   The subject of the event, usually an object or a callable\n     * @param array $arguments Arguments to store in the event\n     */\n    public function __construct(\n        protected mixed $subject = null,\n        protected array $arguments = [],\n    ) {\n    }\n\n    /**\n     * Getter for subject property.\n     */\n    public function getSubject(): mixed\n    {\n        return $this->subject;\n    }\n\n    /**\n     * Get argument by key.\n     *\n     * @throws \\InvalidArgumentException if key is not found\n     */\n    public function getArgument(string $key): mixed\n    {\n        if ($this->hasArgument($key)) {\n            return $this->arguments[$key];\n        }\n\n        throw new \\InvalidArgumentException(\\sprintf('Argument \"%s\" not found.', $key));\n    }\n\n    /**\n     * Add argument to event.\n     *\n     * @return $this\n     */\n    public function setArgument(string $key, mixed $value): static\n    {\n        $this->arguments[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Getter for all arguments.\n     */\n    public function getArguments(): array\n    {\n        return $this->arguments;\n    }\n\n    /**\n     * Set args property.\n     *\n     * @return $this\n     */\n    public function setArguments(array $args = []): static\n    {\n        $this->arguments = $args;\n\n        return $this;\n    }\n\n    /**\n     * Has argument.\n     */\n    public function hasArgument(string $key): bool\n    {\n        return \\array_key_exists($key, $this->arguments);\n    }\n\n    /**\n     * ArrayAccess for argument getter.\n     *\n     * @param string $key Array key\n     *\n     * @throws \\InvalidArgumentException if key does not exist in $this->args\n     */\n    public function offsetGet(mixed $key): mixed\n    {\n        return $this->getArgument($key);\n    }\n\n    /**\n     * ArrayAccess for argument setter.\n     *\n     * @param string $key Array key to set\n     */\n    public function offsetSet(mixed $key, mixed $value): void\n    {\n        $this->setArgument($key, $value);\n    }\n\n    /**\n     * ArrayAccess for unset argument.\n     *\n     * @param string $key Array key\n     */\n    public function offsetUnset(mixed $key): void\n    {\n        if ($this->hasArgument($key)) {\n            unset($this->arguments[$key]);\n        }\n    }\n\n    /**\n     * ArrayAccess has argument.\n     *\n     * @param string $key Array key\n     */\n    public function offsetExists(mixed $key): bool\n    {\n        return $this->hasArgument($key);\n    }\n\n    /**\n     * IteratorAggregate for iterating over the object like an array.\n     *\n     * @return \\ArrayIterator<string, mixed>\n     */\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->arguments);\n    }\n}\n"
  },
  {
    "path": "ImmutableEventDispatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher;\n\n/**\n * A read-only proxy for an event dispatcher.\n *\n * @author Bernhard Schussek <bschussek@gmail.com>\n */\nclass ImmutableEventDispatcher implements EventDispatcherInterface\n{\n    public function __construct(\n        private EventDispatcherInterface $dispatcher,\n    ) {\n    }\n\n    public function dispatch(object $event, ?string $eventName = null): object\n    {\n        return $this->dispatcher->dispatch($event, $eventName);\n    }\n\n    public function addListener(string $eventName, callable|array $listener, int $priority = 0): never\n    {\n        throw new \\BadMethodCallException('Unmodifiable event dispatchers must not be modified.');\n    }\n\n    public function addSubscriber(EventSubscriberInterface $subscriber): never\n    {\n        throw new \\BadMethodCallException('Unmodifiable event dispatchers must not be modified.');\n    }\n\n    public function removeListener(string $eventName, callable|array $listener): never\n    {\n        throw new \\BadMethodCallException('Unmodifiable event dispatchers must not be modified.');\n    }\n\n    public function removeSubscriber(EventSubscriberInterface $subscriber): never\n    {\n        throw new \\BadMethodCallException('Unmodifiable event dispatchers must not be modified.');\n    }\n\n    public function getListeners(?string $eventName = null): array\n    {\n        return $this->dispatcher->getListeners($eventName);\n    }\n\n    public function getListenerPriority(string $eventName, callable|array $listener): ?int\n    {\n        return $this->dispatcher->getListenerPriority($eventName, $listener);\n    }\n\n    public function hasListeners(?string $eventName = null): bool\n    {\n        return $this->dispatcher->hasListeners($eventName);\n    }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2004-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "EventDispatcher Component\n=========================\n\nThe EventDispatcher component provides tools that allow your application\ncomponents to communicate with each other by dispatching events and listening to\nthem.\n\nResources\n---------\n\n * [Documentation](https://symfony.com/doc/current/components/event_dispatcher.html)\n * [Contributing](https://symfony.com/doc/current/contributing/index.html)\n * [Report issues](https://github.com/symfony/symfony/issues) and\n   [send Pull Requests](https://github.com/symfony/symfony/pulls)\n   in the [main Symfony repository](https://github.com/symfony/symfony)\n"
  },
  {
    "path": "Tests/ChildEventDispatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests;\n\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\n\nclass ChildEventDispatcherTest extends EventDispatcherTest\n{\n    protected function createEventDispatcher()\n    {\n        return new ChildEventDispatcher();\n    }\n}\n\nclass ChildEventDispatcher extends EventDispatcher\n{\n}\n"
  },
  {
    "path": "Tests/Debug/TraceableEventDispatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Debug;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\ErrorHandler\\BufferingLogger;\nuse Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\Stopwatch\\Stopwatch;\nuse Symfony\\Contracts\\EventDispatcher\\Event;\n\nclass TraceableEventDispatcherTest extends TestCase\n{\n    public function testAddRemoveListener()\n    {\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n\n        $tdispatcher->addListener('foo', $listener = static function () {});\n        $listeners = $dispatcher->getListeners('foo');\n        $this->assertCount(1, $listeners);\n        $this->assertSame($listener, $listeners[0]);\n\n        $tdispatcher->removeListener('foo', $listener);\n        $this->assertCount(0, $dispatcher->getListeners('foo'));\n    }\n\n    public function testGetListeners()\n    {\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n\n        $tdispatcher->addListener('foo', $listener = static function () {});\n        $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo'));\n    }\n\n    public function testHasListeners()\n    {\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n\n        $this->assertFalse($dispatcher->hasListeners('foo'));\n        $this->assertFalse($tdispatcher->hasListeners('foo'));\n\n        $tdispatcher->addListener('foo', $listener = static function () {});\n        $this->assertTrue($dispatcher->hasListeners('foo'));\n        $this->assertTrue($tdispatcher->hasListeners('foo'));\n    }\n\n    public function testGetListenerPriority()\n    {\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n\n        $tdispatcher->addListener('foo', static function () {}, 123);\n\n        $listeners = $dispatcher->getListeners('foo');\n        $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));\n\n        // Verify that priority is preserved when listener is removed and re-added\n        // in preProcess() and postProcess().\n        $tdispatcher->dispatch(new Event(), 'foo');\n        $listeners = $dispatcher->getListeners('foo');\n        $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));\n    }\n\n    public function testGetListenerPriorityWhileDispatching()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $priorityWhileDispatching = null;\n\n        $listener = static function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) {\n            $priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener);\n        };\n\n        $tdispatcher->addListener('bar', $listener, 5);\n        $tdispatcher->dispatch(new Event(), 'bar');\n        $this->assertSame(5, $priorityWhileDispatching);\n    }\n\n    public function testAddRemoveSubscriber()\n    {\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n\n        $subscriber = new EventSubscriber();\n\n        $tdispatcher->addSubscriber($subscriber);\n        $listeners = $dispatcher->getListeners('foo');\n        $this->assertCount(1, $listeners);\n        $this->assertSame([$subscriber, 'call'], $listeners[0]);\n\n        $tdispatcher->removeSubscriber($subscriber);\n        $this->assertCount(0, $dispatcher->getListeners('foo'));\n    }\n\n    public function testGetCalledListeners()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->addListener('foo', static function () {}, 5);\n\n        $listeners = $tdispatcher->getNotCalledListeners();\n        $this->assertArrayHasKey('stub', $listeners[0]);\n        unset($listeners[0]['stub']);\n        $this->assertEquals([], $tdispatcher->getCalledListeners());\n        $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners);\n\n        $tdispatcher->dispatch(new Event(), 'foo');\n\n        $listeners = $tdispatcher->getCalledListeners();\n        $this->assertArrayHasKey('stub', $listeners[0]);\n        unset($listeners[0]['stub']);\n        $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners);\n        $this->assertEquals([], $tdispatcher->getNotCalledListeners());\n    }\n\n    public function testGetNotCalledClosureListeners()\n    {\n        $instantiationCount = 0;\n\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->addListener('foo', [static function () use (&$instantiationCount) { ++$instantiationCount; }, 'onFoo']);\n\n        $tdispatcher->getNotCalledListeners();\n\n        $this->assertSame(0, $instantiationCount);\n    }\n\n    public function testClearCalledListeners()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->addListener('foo', static function () {}, 5);\n\n        $tdispatcher->dispatch(new Event(), 'foo');\n        $tdispatcher->reset();\n\n        $listeners = $tdispatcher->getNotCalledListeners();\n        $this->assertArrayHasKey('stub', $listeners[0]);\n        unset($listeners[0]['stub']);\n        $this->assertEquals([], $tdispatcher->getCalledListeners());\n        $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners);\n    }\n\n    public function testDispatchAfterReset()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->addListener('foo', static function () {}, 5);\n\n        $tdispatcher->reset();\n        $tdispatcher->dispatch(new Event(), 'foo');\n\n        $listeners = $tdispatcher->getCalledListeners();\n        $this->assertArrayHasKey('stub', $listeners[0]);\n    }\n\n    public function testGetCalledListenersNested()\n    {\n        $tdispatcher = null;\n        $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $dispatcher->addListener('foo', static function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) {\n            $tdispatcher = $dispatcher;\n            $dispatcher->dispatch(new Event(), 'bar');\n        });\n        $dispatcher->addListener('bar', static function (Event $event) {});\n        $dispatcher->dispatch(new Event(), 'foo');\n        $this->assertSame($dispatcher, $tdispatcher);\n        $this->assertCount(2, $dispatcher->getCalledListeners());\n    }\n\n    public function testItReturnsNoOrphanedEventsWhenCreated()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $events = $tdispatcher->getOrphanedEvents();\n        $this->assertSame([], $events);\n    }\n\n    public function testItReturnsOrphanedEventsAfterDispatch()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->dispatch(new Event(), 'foo');\n        $events = $tdispatcher->getOrphanedEvents();\n        $this->assertCount(1, $events);\n        $this->assertEquals(['foo'], $events);\n    }\n\n    public function testItDoesNotReturnHandledEvents()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->addListener('foo', static function () {});\n        $tdispatcher->dispatch(new Event(), 'foo');\n        $events = $tdispatcher->getOrphanedEvents();\n        $this->assertSame([], $events);\n    }\n\n    public function testLogger()\n    {\n        $logger = new BufferingLogger();\n\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);\n        $tdispatcher->addListener('foo', $listener1 = static function () {});\n        $tdispatcher->addListener('foo', $listener2 = static function () {});\n\n        $tdispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertSame([\n            [\n                'debug',\n                'Notified event \"{event}\" to listener \"{listener}\".',\n                ['event' => 'foo', 'listener' => 'closure'],\n            ],\n            [\n                'debug',\n                'Notified event \"{event}\" to listener \"{listener}\".',\n                ['event' => 'foo', 'listener' => 'closure'],\n            ],\n        ], $logger->cleanLogs());\n    }\n\n    public function testLoggerWithStoppedEvent()\n    {\n        $logger = new BufferingLogger();\n\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);\n        $tdispatcher->addListener('foo', $listener1 = static function (Event $event) { $event->stopPropagation(); });\n        $tdispatcher->addListener('foo', $listener2 = static function () {});\n\n        $tdispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertSame([\n            [\n                'debug',\n                'Notified event \"{event}\" to listener \"{listener}\".',\n                ['event' => 'foo', 'listener' => 'closure'],\n            ],\n            [\n                'debug',\n                'Listener \"{listener}\" stopped propagation of the event \"{event}\".',\n                ['event' => 'foo', 'listener' => 'closure'],\n            ],\n            [\n                'debug',\n                'Listener \"{listener}\" was not called for event \"{event}\".',\n                ['event' => 'foo', 'listener' => 'closure'],\n            ],\n        ], $logger->cleanLogs());\n    }\n\n    public function testDispatchCallListeners()\n    {\n        $called = [];\n\n        $dispatcher = new EventDispatcher();\n        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());\n        $tdispatcher->addListener('foo', static function () use (&$called) { $called[] = 'foo1'; }, 10);\n        $tdispatcher->addListener('foo', static function () use (&$called) { $called[] = 'foo2'; }, 20);\n\n        $tdispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertSame(['foo2', 'foo1'], $called);\n    }\n\n    public function testDispatchNested()\n    {\n        $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $loop = 1;\n        $dispatchedEvents = 0;\n        $dispatcher->addListener('foo', $listener1 = static function () use ($dispatcher, &$loop) {\n            ++$loop;\n            if (2 == $loop) {\n                $dispatcher->dispatch(new Event(), 'foo');\n            }\n        });\n        $dispatcher->addListener('foo', static function () use (&$dispatchedEvents) {\n            ++$dispatchedEvents;\n        });\n\n        $dispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertSame(2, $dispatchedEvents);\n    }\n\n    public function testDispatchReusedEventNested()\n    {\n        $nestedCall = false;\n        $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $dispatcher->addListener('foo', static function (Event $e) use ($dispatcher) {\n            $dispatcher->dispatch(new Event(), 'bar', $e);\n        });\n        $dispatcher->addListener('bar', static function (Event $e) use (&$nestedCall) {\n            $nestedCall = true;\n        });\n\n        $this->assertFalse($nestedCall);\n        $dispatcher->dispatch(new Event(), 'foo');\n        $this->assertTrue($nestedCall);\n    }\n\n    public function testListenerCanRemoveItselfWhenExecuted()\n    {\n        $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $listener1 = static function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {\n            $dispatcher->removeListener('foo', $listener1);\n        };\n        $eventDispatcher->addListener('foo', $listener1);\n        $eventDispatcher->addListener('foo', static function () {});\n        $eventDispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');\n    }\n\n    public function testClearOrphanedEvents()\n    {\n        $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());\n        $tdispatcher->dispatch(new Event(), 'foo');\n        $events = $tdispatcher->getOrphanedEvents();\n        $this->assertCount(1, $events);\n        $tdispatcher->reset();\n        $events = $tdispatcher->getOrphanedEvents();\n        $this->assertCount(0, $events);\n    }\n}\n\nclass EventSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return ['foo' => 'call'];\n    }\n}\n"
  },
  {
    "path": "Tests/Debug/WrappedListenerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Debug;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\Stopwatch\\Stopwatch;\nuse Symfony\\Component\\Stopwatch\\StopwatchEvent;\n\nclass WrappedListenerTest extends TestCase\n{\n    #[DataProvider('provideListenersToDescribe')]\n    public function testListenerDescription($listener, $expected)\n    {\n        $wrappedListener = new WrappedListener($listener, null, new Stopwatch(), new EventDispatcher());\n\n        $this->assertStringMatchesFormat($expected, $wrappedListener->getPretty());\n    }\n\n    public static function provideListenersToDescribe()\n    {\n        return [\n            [new FooListener(), 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::__invoke'],\n            [[new FooListener(), 'listen'], 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::listen'],\n            [['Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener', 'listenStatic'], 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::listenStatic'],\n            [['Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener', 'invalidMethod'], 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::invalidMethod'],\n            ['var_dump', 'var_dump'],\n            [static function () {}, 'closure'],\n            [\\Closure::fromCallable([new FooListener(), 'listen']), 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::listen'],\n            [\\Closure::fromCallable(['Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener', 'listenStatic']), 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::listenStatic'],\n            [\\Closure::fromCallable(static function () {}), 'closure'],\n            [[#[\\Closure(name: FooListener::class)] static fn () => new FooListener(), 'listen'], 'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\FooListener::listen'],\n        ];\n    }\n\n    public function testStopwatchEventIsStoppedWhenListenerThrows()\n    {\n        $stopwatchEvent = $this->createMock(StopwatchEvent::class);\n        $stopwatchEvent->expects(self::once())->method('isStarted')->willReturn(true);\n        $stopwatchEvent->expects(self::once())->method('stop');\n\n        $stopwatch = $this->createStub(Stopwatch::class);\n        $stopwatch->method('start')->willReturn($stopwatchEvent);\n\n        $dispatcher = $this->createStub(EventDispatcherInterface::class);\n\n        $wrappedListener = new WrappedListener(static fn () => throw new \\Exception(), null, $stopwatch, $dispatcher);\n\n        try {\n            $wrappedListener(new \\stdClass(), 'foo', $dispatcher);\n        } catch (\\Exception $ex) {\n        }\n    }\n}\n\nclass FooListener\n{\n    public function listen()\n    {\n    }\n\n    public function __invoke()\n    {\n    }\n\n    public static function listenStatic()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/DependencyInjection/RegisterListenersPassTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\DependencyInjection;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Bundle\\FrameworkBundle\\DependencyInjection\\FrameworkExtension;\nuse Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument;\nuse Symfony\\Component\\DependencyInjection\\Compiler\\AttributeAutoconfigurationPass;\nuse Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInstanceofConditionalsPass;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\DependencyInjection\\Reference;\nuse Symfony\\Component\\EventDispatcher\\DependencyInjection\\AddEventAliasesPass;\nuse Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\EventDispatcher\\Tests\\Fixtures\\CustomEvent;\nuse Symfony\\Component\\EventDispatcher\\Tests\\Fixtures\\DummyEvent;\nuse Symfony\\Component\\EventDispatcher\\Tests\\Fixtures\\TaggedInvokableListener;\nuse Symfony\\Component\\EventDispatcher\\Tests\\Fixtures\\TaggedMultiListener;\nuse Symfony\\Component\\EventDispatcher\\Tests\\Fixtures\\TaggedUnionTypeListener;\n\nclass RegisterListenersPassTest extends TestCase\n{\n    /**\n     * Tests that event subscribers not implementing EventSubscriberInterface\n     * trigger an exception.\n     */\n    public function testEventSubscriberWithoutInterface()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $builder = new ContainerBuilder();\n        $builder->register('event_dispatcher');\n        $builder->register('my_event_subscriber', 'stdClass')\n            ->addTag('kernel.event_subscriber');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($builder);\n    }\n\n    public function testValidEventSubscriber()\n    {\n        $builder = new ContainerBuilder();\n        $eventDispatcherDefinition = $builder->register('event_dispatcher');\n        $builder->register('my_event_subscriber', 'Symfony\\Component\\EventDispatcher\\Tests\\DependencyInjection\\SubscriberService')\n            ->addTag('kernel.event_subscriber');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($builder);\n\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'event',\n                    [new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onEvent'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $eventDispatcherDefinition->getMethodCalls());\n    }\n\n    public function testAliasedEventSubscriber()\n    {\n        $builder = new ContainerBuilder();\n        $builder->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);\n        $builder->register('event_dispatcher');\n        $builder->register('my_event_subscriber', AliasedSubscriber::class)\n            ->addTag('kernel.event_subscriber');\n\n        $eventAliasPass = new AddEventAliasesPass([CustomEvent::class => 'custom_event']);\n        $eventAliasPass->process($builder);\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($builder);\n\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'aliased_event',\n                    [new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onAliasedEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'custom_event',\n                    [new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onCustomEvent'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $builder->getDefinition('event_dispatcher')->getMethodCalls());\n    }\n\n    public function testAbstractEventListener()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The service \"foo\" tagged \"kernel.event_listener\" must not be abstract.');\n        $container = new ContainerBuilder();\n        $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_listener', []);\n        $container->register('event_dispatcher', 'stdClass');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testAbstractEventSubscriber()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The service \"foo\" tagged \"kernel.event_subscriber\" must not be abstract.');\n        $container = new ContainerBuilder();\n        $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_subscriber', []);\n        $container->register('event_dispatcher', 'stdClass');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testEventSubscriberResolvableClassName()\n    {\n        $container = new ContainerBuilder();\n\n        $container->setParameter('subscriber.class', 'Symfony\\Component\\EventDispatcher\\Tests\\DependencyInjection\\SubscriberService');\n        $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', []);\n        $container->register('event_dispatcher', 'stdClass');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'event',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onEvent'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $definition->getMethodCalls());\n    }\n\n    public function testHotPathEvents()\n    {\n        $container = new ContainerBuilder();\n\n        $container->register('foo', SubscriberService::class)->addTag('kernel.event_subscriber', []);\n        $container->register('event_dispatcher', 'stdClass');\n\n        (new RegisterListenersPass())->setHotPathEvents(['event'])->process($container);\n\n        $this->assertTrue($container->getDefinition('foo')->hasTag('container.hot_path'));\n    }\n\n    public function testNoPreloadEvents()\n    {\n        $container = new ContainerBuilder();\n\n        $container->register('foo', SubscriberService::class)->addTag('kernel.event_subscriber', []);\n        $container->register('bar')->addTag('kernel.event_listener', ['event' => 'cold_event']);\n        $container->register('baz')\n            ->addTag('kernel.event_listener', ['event' => 'event'])\n            ->addTag('kernel.event_listener', ['event' => 'cold_event']);\n        $container->register('event_dispatcher', 'stdClass');\n\n        (new RegisterListenersPass())\n            ->setHotPathEvents(['event'])\n            ->setNoPreloadEvents(['cold_event'])\n            ->process($container);\n\n        $this->assertFalse($container->getDefinition('foo')->hasTag('container.no_preload'));\n        $this->assertTrue($container->getDefinition('bar')->hasTag('container.no_preload'));\n        $this->assertFalse($container->getDefinition('baz')->hasTag('container.no_preload'));\n    }\n\n    public function testEventSubscriberUnresolvableClassName()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('You have requested a non-existent parameter \"subscriber.class\"');\n        $container = new ContainerBuilder();\n        $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', []);\n        $container->register('event_dispatcher', 'stdClass');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testInvokableEventListener()\n    {\n        $container = new ContainerBuilder();\n        $container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);\n\n        $container->register('foo', \\get_class(new class {\n            public function onFooBar()\n            {\n            }\n        }))->addTag('kernel.event_listener', ['event' => 'foo.bar']);\n        $container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']);\n        $container->register('baz', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'event']);\n        $container->register('zar', \\get_class(new class {\n            public function onFooBarZar()\n            {\n            }\n        }))->addTag('kernel.event_listener', ['event' => 'foo.bar_zar']);\n        $container->register('event_dispatcher', \\stdClass::class);\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'foo.bar',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onFooBar'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'foo.bar',\n                    [new ServiceClosureArgument(new Reference('bar')), '__invoke'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'event',\n                    [new ServiceClosureArgument(new Reference('baz')), 'onEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'foo.bar_zar',\n                    [new ServiceClosureArgument(new Reference('zar')), 'onFooBarZar'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $definition->getMethodCalls());\n    }\n\n    public function testItThrowsAnExceptionIfTagIsMissingMethodAndClassHasNoValidMethod()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('None of the \"onFooBar\" or \"__invoke\" methods exist for the service \"foo\". Please define the \"method\" attribute on \"kernel.event_listener\" tags.');\n\n        $container = new ContainerBuilder();\n\n        $container->register('foo', \\stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']);\n        $container->register('event_dispatcher', \\stdClass::class);\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testTaggedInvokableEventListener()\n    {\n        $container = $this->createContainerBuilder();\n        $container->register('foo', TaggedInvokableListener::class)->setAutoconfigured(true);\n        $container->register('event_dispatcher', \\stdClass::class);\n\n        (new AttributeAutoconfigurationPass())->process($container);\n        (new ResolveInstanceofConditionalsPass())->process($container);\n        (new RegisterListenersPass())->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    CustomEvent::class,\n                    [new ServiceClosureArgument(new Reference('foo')), '__invoke'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, \\array_slice($definition->getMethodCalls(), 0, \\count($expectedCalls)));\n    }\n\n    public function testTaggedMultiEventListener()\n    {\n        $container = $this->createContainerBuilder();\n\n        $container->register('foo', TaggedMultiListener::class)->setAutoconfigured(true);\n        $container->register('event_dispatcher', \\stdClass::class);\n\n        (new AttributeAutoconfigurationPass())->process($container);\n        (new ResolveInstanceofConditionalsPass())->process($container);\n        (new RegisterListenersPass())->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    CustomEvent::class,\n                    [new ServiceClosureArgument(new Reference('foo')), 'onCustomEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'foo',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onFoo'],\n                    42,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'bar',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onBarEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'baz',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onBazEvent'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, \\array_slice($definition->getMethodCalls(), 0, \\count($expectedCalls)));\n    }\n\n    public function testTaggedMethodUnionTypeEventListener()\n    {\n        $container = $this->createContainerBuilder();\n\n        $container->register('foo', TaggedUnionTypeListener::class)->setAutoconfigured(true);\n        $container->register('event_dispatcher', \\stdClass::class);\n\n        (new AttributeAutoconfigurationPass())->process($container);\n        (new ResolveInstanceofConditionalsPass())->process($container);\n        (new RegisterListenersPass())->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    CustomEvent::class,\n                    [new ServiceClosureArgument(new Reference('foo')), 'onUnionEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    DummyEvent::class,\n                    [new ServiceClosureArgument(new Reference('foo')), 'onUnionEvent'],\n                    0,\n                ],\n            ],\n        ];\n\n        $this->assertEquals($expectedCalls, \\array_slice($definition->getMethodCalls(), 0, \\count($expectedCalls)));\n    }\n\n    public function testAliasedEventListener()\n    {\n        $container = new ContainerBuilder();\n        $eventAliases = [AliasedEvent::class => 'aliased_event'];\n        $container->setParameter('event_dispatcher.event_aliases', $eventAliases);\n        $container->register('foo', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => AliasedEvent::class, 'method' => 'onEvent']);\n        $container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => CustomEvent::class, 'method' => 'onEvent']);\n        $container->register('event_dispatcher');\n\n        $customEventAlias = [CustomEvent::class => 'custom_event'];\n        $eventAliasPass = new AddEventAliasesPass($customEventAlias);\n        $eventAliasPass->process($container);\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n\n        $this->assertTrue($container->hasParameter('event_dispatcher.event_aliases'));\n        $this->assertSame(array_merge($eventAliases, $customEventAlias), $container->getParameter('event_dispatcher.event_aliases'));\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'aliased_event',\n                    [new ServiceClosureArgument(new Reference('foo')), 'onEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'custom_event',\n                    [new ServiceClosureArgument(new Reference('bar')), 'onEvent'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $definition->getMethodCalls());\n    }\n\n    public function testOmitEventNameOnTypedListener()\n    {\n        $container = new ContainerBuilder();\n        $container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);\n        $container->register('foo', TypedListener::class)->addTag('kernel.event_listener', ['method' => 'onEvent']);\n        $container->register('bar', TypedListener::class)->addTag('kernel.event_listener');\n        $container->register('event_dispatcher');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    CustomEvent::class,\n                    [new ServiceClosureArgument(new Reference('foo')), 'onEvent'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'aliased_event',\n                    [new ServiceClosureArgument(new Reference('bar')), '__invoke'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $definition->getMethodCalls());\n    }\n\n    public function testOmitEventNameOnUntypedListener()\n    {\n        $container = new ContainerBuilder();\n        $container->register('foo', InvokableListenerService::class)->addTag('kernel.event_listener', ['method' => 'onEvent']);\n        $container->register('event_dispatcher');\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Service \"foo\" must define the \"event\" attribute on \"kernel.event_listener\" tags.');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testOmitEventNameAndMethodOnUntypedListener()\n    {\n        $container = new ContainerBuilder();\n        $container->register('foo', InvokableListenerService::class)->addTag('kernel.event_listener');\n        $container->register('event_dispatcher');\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Service \"foo\" must define the \"event\" attribute on \"kernel.event_listener\" tags.');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testOmitEventNameAndMethodOnGenericListener()\n    {\n        $container = new ContainerBuilder();\n        $container->register('foo', GenericListener::class)->addTag('kernel.event_listener');\n        $container->register('event_dispatcher');\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Service \"foo\" must define the \"event\" attribute on \"kernel.event_listener\" tags.');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n    }\n\n    public function testOmitEventNameOnSubscriber()\n    {\n        $container = new ContainerBuilder();\n        $container->register('subscriber', IncompleteSubscriber::class)\n            ->addTag('kernel.event_subscriber')\n            ->addTag('kernel.event_listener')\n            ->addTag('kernel.event_listener', ['event' => 'bar', 'method' => 'onBar'])\n        ;\n        $container->register('event_dispatcher');\n\n        $registerListenersPass = new RegisterListenersPass();\n        $registerListenersPass->process($container);\n\n        $definition = $container->getDefinition('event_dispatcher');\n        $expectedCalls = [\n            [\n                'addListener',\n                [\n                    'bar',\n                    [new ServiceClosureArgument(new Reference('subscriber')), 'onBar'],\n                    0,\n                ],\n            ],\n            [\n                'addListener',\n                [\n                    'foo',\n                    [new ServiceClosureArgument(new Reference('subscriber')), 'onFoo'],\n                    0,\n                ],\n            ],\n        ];\n        $this->assertEquals($expectedCalls, $definition->getMethodCalls());\n    }\n\n    private function createContainerBuilder(): ContainerBuilder\n    {\n        $container = new ContainerBuilder();\n        $container->setParameter('kernel.debug', true);\n        $container->setParameter('kernel.project_dir', __DIR__);\n        $container->setParameter('kernel.container_class', 'testContainer');\n        (new FrameworkExtension())->load([], $container);\n\n        return $container;\n    }\n}\n\nclass SubscriberService implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return [\n            'event' => 'onEvent',\n        ];\n    }\n}\n\nclass InvokableListenerService\n{\n    public function __invoke()\n    {\n    }\n\n    public function onEvent()\n    {\n    }\n}\n\nfinal class AliasedSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return [\n            AliasedEvent::class => 'onAliasedEvent',\n            CustomEvent::class => 'onCustomEvent',\n        ];\n    }\n}\n\nfinal class AliasedEvent\n{\n}\n\nfinal class TypedListener\n{\n    public function __invoke(AliasedEvent $event): void\n    {\n    }\n\n    public function onEvent(CustomEvent $event): void\n    {\n    }\n}\n\nfinal class GenericListener\n{\n    public function __invoke(object $event): void\n    {\n    }\n}\n\nfinal class IncompleteSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return [\n            'foo' => 'onFoo',\n        ];\n    }\n\n    public function onFoo(): void\n    {\n    }\n\n    public function onBar(): void\n    {\n    }\n\n    public function __invoke(CustomEvent $event): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/EventDispatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Contracts\\EventDispatcher\\Event;\n\nclass EventDispatcherTest extends TestCase\n{\n    /* Some pseudo events */\n    private const preFoo = 'pre.foo';\n    private const postFoo = 'post.foo';\n    private const preBar = 'pre.bar';\n\n    private EventDispatcher $dispatcher;\n    private TestEventListener $listener;\n\n    protected function setUp(): void\n    {\n        $this->dispatcher = $this->createEventDispatcher();\n        $this->listener = new TestEventListener();\n    }\n\n    protected function createEventDispatcher()\n    {\n        return new EventDispatcher();\n    }\n\n    public function testInitialState()\n    {\n        $this->assertEquals([], $this->dispatcher->getListeners());\n        $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertFalse($this->dispatcher->hasListeners(self::postFoo));\n    }\n\n    public function testAddListener()\n    {\n        $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']);\n        $this->dispatcher->addListener('post.foo', $this->listener->postFoo(...));\n        $this->assertTrue($this->dispatcher->hasListeners());\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertTrue($this->dispatcher->hasListeners(self::postFoo));\n        $this->assertCount(1, $this->dispatcher->getListeners(self::preFoo));\n        $this->assertCount(1, $this->dispatcher->getListeners(self::postFoo));\n        $this->assertCount(2, $this->dispatcher->getListeners());\n    }\n\n    public function testGetListenersSortsByPriority()\n    {\n        $listener1 = new TestEventListener();\n        $listener2 = new TestEventListener();\n        $listener3 = new TestEventListener();\n        $listener4 = new TestEventListener();\n        $listener1->name = '1';\n        $listener2->name = '2';\n        $listener3->name = '3';\n        $listener4->name = '4';\n\n        $this->dispatcher->addListener('pre.foo', [$listener1, 'preFoo'], -10);\n        $this->dispatcher->addListener('pre.foo', [$listener2, 'preFoo'], 10);\n        $this->dispatcher->addListener('pre.foo', [$listener3, 'preFoo']);\n        $this->dispatcher->addListener('pre.foo', $listener4->preFoo(...), 20);\n\n        $expected = [\n            $listener4->preFoo(...),\n            [$listener2, 'preFoo'],\n            [$listener3, 'preFoo'],\n            [$listener1, 'preFoo'],\n        ];\n\n        $this->assertEquals($expected, $this->dispatcher->getListeners('pre.foo'));\n    }\n\n    public function testGetAllListenersSortsByPriority()\n    {\n        $listener1 = new TestEventListener();\n        $listener2 = new TestEventListener();\n        $listener3 = new TestEventListener();\n        $listener4 = new TestEventListener();\n        $listener5 = new TestEventListener();\n        $listener6 = new TestEventListener();\n\n        $this->dispatcher->addListener('pre.foo', $listener1, -10);\n        $this->dispatcher->addListener('pre.foo', $listener2);\n        $this->dispatcher->addListener('pre.foo', $listener3, 10);\n        $this->dispatcher->addListener('post.foo', $listener4, -10);\n        $this->dispatcher->addListener('post.foo', $listener5);\n        $this->dispatcher->addListener('post.foo', $listener6, 10);\n\n        $expected = [\n            'pre.foo' => [$listener3, $listener2, $listener1],\n            'post.foo' => [$listener6, $listener5, $listener4],\n        ];\n\n        $this->assertSame($expected, $this->dispatcher->getListeners());\n    }\n\n    public function testGetListenerPriority()\n    {\n        $listener1 = new TestEventListener();\n        $listener2 = new TestEventListener();\n\n        $this->dispatcher->addListener('pre.foo', $listener1, -10);\n        $this->dispatcher->addListener('pre.foo', $listener2);\n\n        $this->assertSame(-10, $this->dispatcher->getListenerPriority('pre.foo', $listener1));\n        $this->assertSame(0, $this->dispatcher->getListenerPriority('pre.foo', $listener2));\n        $this->assertNull($this->dispatcher->getListenerPriority('pre.bar', $listener2));\n        $this->assertNull($this->dispatcher->getListenerPriority('pre.foo', static function () {}));\n    }\n\n    public function testDispatch()\n    {\n        $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']);\n        $this->dispatcher->addListener('post.foo', $this->listener->postFoo(...));\n        $this->dispatcher->dispatch(new Event(), self::preFoo);\n        $this->assertTrue($this->listener->preFooInvoked);\n        $this->assertFalse($this->listener->postFooInvoked);\n        $this->assertInstanceOf(Event::class, $this->dispatcher->dispatch(new Event(), 'noevent'));\n        $this->assertInstanceOf(Event::class, $this->dispatcher->dispatch(new Event(), self::preFoo));\n        $event = new Event();\n        $return = $this->dispatcher->dispatch($event, self::preFoo);\n        $this->assertSame($event, $return);\n    }\n\n    public function testDispatchForClosure()\n    {\n        $invoked = 0;\n        $listener = static function () use (&$invoked) {\n            ++$invoked;\n        };\n        $this->dispatcher->addListener('pre.foo', $listener);\n        $this->dispatcher->addListener('post.foo', $listener);\n        $this->dispatcher->dispatch(new Event(), self::preFoo);\n        $this->assertEquals(1, $invoked);\n    }\n\n    public function testStopEventPropagation()\n    {\n        $otherListener = new TestEventListener();\n\n        // postFoo() stops the propagation, so only one listener should\n        // be executed\n        // Manually set priority to enforce $this->listener to be called first\n        $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo'], 10);\n        $this->dispatcher->addListener('post.foo', $otherListener->postFoo(...));\n        $this->dispatcher->dispatch(new Event(), self::postFoo);\n        $this->assertTrue($this->listener->postFooInvoked);\n        $this->assertFalse($otherListener->postFooInvoked);\n    }\n\n    public function testDispatchByPriority()\n    {\n        $invoked = [];\n        $listener1 = static function () use (&$invoked) {\n            $invoked[] = '1';\n        };\n        $listener2 = static function () use (&$invoked) {\n            $invoked[] = '2';\n        };\n        $listener3 = static function () use (&$invoked) {\n            $invoked[] = '3';\n        };\n        $this->dispatcher->addListener('pre.foo', $listener1, -10);\n        $this->dispatcher->addListener('pre.foo', $listener2);\n        $this->dispatcher->addListener('pre.foo', $listener3, 10);\n        $this->dispatcher->dispatch(new Event(), self::preFoo);\n        $this->assertEquals(['3', '2', '1'], $invoked);\n    }\n\n    public function testRemoveListener()\n    {\n        $this->dispatcher->addListener('pre.bar', $this->listener);\n        $this->assertTrue($this->dispatcher->hasListeners(self::preBar));\n        $this->dispatcher->removeListener('pre.bar', $this->listener);\n        $this->assertFalse($this->dispatcher->hasListeners(self::preBar));\n        $this->dispatcher->removeListener('notExists', $this->listener);\n    }\n\n    public function testAddSubscriber()\n    {\n        $eventSubscriber = new TestEventSubscriber();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertTrue($this->dispatcher->hasListeners(self::postFoo));\n    }\n\n    public function testAddSubscriberWithPriorities()\n    {\n        $eventSubscriber = new TestEventSubscriber();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n\n        $eventSubscriber = new TestEventSubscriberWithPriorities();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n\n        $listeners = $this->dispatcher->getListeners('pre.foo');\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertCount(2, $listeners);\n        $this->assertInstanceOf(TestEventSubscriberWithPriorities::class, $listeners[0][0]);\n    }\n\n    public function testAddSubscriberWithMultipleListeners()\n    {\n        $eventSubscriber = new TestEventSubscriberWithMultipleListeners();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n\n        $listeners = $this->dispatcher->getListeners('pre.foo');\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertCount(2, $listeners);\n        $this->assertEquals('preFoo2', $listeners[0][1]);\n    }\n\n    public function testRemoveSubscriber()\n    {\n        $eventSubscriber = new TestEventSubscriber();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertTrue($this->dispatcher->hasListeners(self::postFoo));\n        $this->dispatcher->removeSubscriber($eventSubscriber);\n        $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertFalse($this->dispatcher->hasListeners(self::postFoo));\n    }\n\n    public function testRemoveSubscriberWithPriorities()\n    {\n        $eventSubscriber = new TestEventSubscriberWithPriorities();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->dispatcher->removeSubscriber($eventSubscriber);\n        $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));\n    }\n\n    public function testRemoveSubscriberWithMultipleListeners()\n    {\n        $eventSubscriber = new TestEventSubscriberWithMultipleListeners();\n        $this->dispatcher->addSubscriber($eventSubscriber);\n        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));\n        $this->assertCount(2, $this->dispatcher->getListeners(self::preFoo));\n        $this->dispatcher->removeSubscriber($eventSubscriber);\n        $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));\n    }\n\n    public function testEventReceivesTheDispatcherInstanceAsArgument()\n    {\n        $listener = new TestWithDispatcher();\n        $this->dispatcher->addListener('test', [$listener, 'foo']);\n        $this->assertNull($listener->name);\n        $this->assertNull($listener->dispatcher);\n        $this->dispatcher->dispatch(new Event(), 'test');\n        $this->assertEquals('test', $listener->name);\n        $this->assertSame($this->dispatcher, $listener->dispatcher);\n    }\n\n    /**\n     * @see https://bugs.php.net/62976\n     *\n     * This bug affects:\n     *  - The PHP 5.3 branch for versions < 5.3.18\n     *  - The PHP 5.4 branch for versions < 5.4.8\n     *  - The PHP 5.5 branch is not affected\n     */\n    public function testWorkaroundForPhpBug62976()\n    {\n        $dispatcher = $this->createEventDispatcher();\n        $dispatcher->addListener('bug.62976', new CallableClass());\n        $dispatcher->removeListener('bug.62976', static function () {});\n        $this->assertTrue($dispatcher->hasListeners('bug.62976'));\n    }\n\n    public function testHasListenersWhenAddedCallbackListenerIsRemoved()\n    {\n        $listener = static function () {};\n        $this->dispatcher->addListener('foo', $listener);\n        $this->dispatcher->removeListener('foo', $listener);\n        $this->assertFalse($this->dispatcher->hasListeners());\n    }\n\n    public function testGetListenersWhenAddedCallbackListenerIsRemoved()\n    {\n        $listener = static function () {};\n        $this->dispatcher->addListener('foo', $listener);\n        $this->dispatcher->removeListener('foo', $listener);\n        $this->assertSame([], $this->dispatcher->getListeners());\n    }\n\n    public function testHasListenersWithoutEventsReturnsFalseAfterHasListenersWithEventHasBeenCalled()\n    {\n        $this->assertFalse($this->dispatcher->hasListeners('foo'));\n        $this->assertFalse($this->dispatcher->hasListeners());\n    }\n\n    public function testHasListenersIsLazy()\n    {\n        $called = 0;\n        $listener = [static function () use (&$called) { ++$called; }, 'onFoo'];\n        $this->dispatcher->addListener('foo', $listener);\n        $this->assertTrue($this->dispatcher->hasListeners());\n        $this->assertTrue($this->dispatcher->hasListeners('foo'));\n        $this->assertSame(0, $called);\n    }\n\n    public function testDispatchLazyListener()\n    {\n        $dispatcher = new TestWithDispatcher();\n        $called = 0;\n        $factory = static function () use (&$called, $dispatcher) {\n            ++$called;\n\n            return $dispatcher;\n        };\n        $this->dispatcher->addListener('foo', [$factory, 'foo']);\n        $this->assertSame(0, $called);\n        $this->dispatcher->dispatch(new Event(), 'foo');\n        $this->assertFalse($dispatcher->invoked);\n        $this->dispatcher->dispatch(new Event(), 'foo');\n        $this->assertSame(1, $called);\n\n        $this->dispatcher->addListener('bar', [$factory]);\n        $this->assertSame(1, $called);\n        $this->dispatcher->dispatch(new Event(), 'bar');\n        $this->assertTrue($dispatcher->invoked);\n        $this->dispatcher->dispatch(new Event(), 'bar');\n        $this->assertSame(2, $called);\n    }\n\n    public function testRemoveFindsLazyListeners()\n    {\n        $test = new TestWithDispatcher();\n        $factory = static fn () => $test;\n\n        $this->dispatcher->addListener('foo', [$factory, 'foo']);\n        $this->assertTrue($this->dispatcher->hasListeners('foo'));\n        $this->dispatcher->removeListener('foo', [$test, 'foo']);\n        $this->assertFalse($this->dispatcher->hasListeners('foo'));\n\n        $this->dispatcher->addListener('foo', [$test, 'foo']);\n        $this->assertTrue($this->dispatcher->hasListeners('foo'));\n        $this->dispatcher->removeListener('foo', [$factory, 'foo']);\n        $this->assertFalse($this->dispatcher->hasListeners('foo'));\n    }\n\n    public function testPriorityFindsLazyListeners()\n    {\n        $test = new TestWithDispatcher();\n        $factory = static fn () => $test;\n\n        $this->dispatcher->addListener('foo', [$factory, 'foo'], 3);\n        $this->assertSame(3, $this->dispatcher->getListenerPriority('foo', [$test, 'foo']));\n        $this->dispatcher->removeListener('foo', [$factory, 'foo']);\n\n        $this->dispatcher->addListener('foo', [$test, 'foo'], 5);\n        $this->assertSame(5, $this->dispatcher->getListenerPriority('foo', [$factory, 'foo']));\n    }\n\n    public function testGetLazyListeners()\n    {\n        $test = new TestWithDispatcher();\n        $factory = static fn () => $test;\n\n        $this->dispatcher->addListener('foo', [$factory, 'foo'], 3);\n        $this->assertSame([[$test, 'foo']], $this->dispatcher->getListeners('foo'));\n\n        $this->dispatcher->removeListener('foo', [$test, 'foo']);\n        $this->dispatcher->addListener('bar', [$factory, 'foo'], 3);\n        $this->assertSame(['bar' => [[$test, 'foo']]], $this->dispatcher->getListeners());\n    }\n\n    public function testMutatingWhilePropagationIsStopped()\n    {\n        $testLoaded = false;\n        $test = new TestEventListener();\n        $this->dispatcher->addListener('foo', $test->postFoo(...));\n        $this->dispatcher->addListener('foo', [static function () use ($test, &$testLoaded) {\n            $testLoaded = true;\n\n            return $test;\n        }, 'preFoo']);\n\n        $this->dispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertTrue($test->postFooInvoked);\n        $this->assertFalse($test->preFooInvoked);\n\n        $this->assertEquals(0, $this->dispatcher->getListenerPriority('foo', $test->postFoo(...)));\n\n        $test->preFoo(new Event());\n        $this->dispatcher->dispatch(new Event(), 'foo');\n\n        $this->assertTrue($testLoaded);\n    }\n\n    public function testNamedClosures()\n    {\n        $listener = new TestEventListener();\n\n        $callback1 = $listener(...);\n        $callback2 = $listener(...);\n        $callback3 = (new TestEventListener())(...);\n\n        $this->assertNotSame($callback1, $callback2);\n        $this->assertNotSame($callback1, $callback3);\n        $this->assertNotSame($callback2, $callback3);\n\n        $this->dispatcher->addListener('foo', $callback1, 3);\n        $this->dispatcher->addListener('foo', $callback2, 2);\n        $this->dispatcher->addListener('foo', $callback3, 1);\n\n        $this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback1));\n        $this->assertSame(3, $this->dispatcher->getListenerPriority('foo', $callback2));\n\n        $this->dispatcher->removeListener('foo', $callback1);\n\n        $this->assertSame(['foo' => [$callback3]], $this->dispatcher->getListeners());\n    }\n}\n\nclass CallableClass\n{\n    public function __invoke()\n    {\n    }\n}\n\nclass TestEventListener\n{\n    public string $name;\n    public bool $preFooInvoked = false;\n    public bool $postFooInvoked = false;\n\n    /* Listener methods */\n\n    public function preFoo($e)\n    {\n        $this->preFooInvoked = true;\n    }\n\n    public function postFoo($e)\n    {\n        $this->postFooInvoked = true;\n\n        if (!$this->preFooInvoked) {\n            $e->stopPropagation();\n        }\n    }\n\n    public function __invoke()\n    {\n    }\n}\n\nclass TestWithDispatcher\n{\n    public ?string $name = null;\n    public ?EventDispatcher $dispatcher = null;\n    public bool $invoked = false;\n\n    public function foo($e, $name, $dispatcher)\n    {\n        $this->name = $name;\n        $this->dispatcher = $dispatcher;\n    }\n\n    public function __invoke($e, $name, $dispatcher)\n    {\n        $this->name = $name;\n        $this->dispatcher = $dispatcher;\n        $this->invoked = true;\n    }\n}\n\nclass TestEventSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return ['pre.foo' => 'preFoo', 'post.foo' => 'postFoo'];\n    }\n}\n\nclass TestEventSubscriberWithPriorities implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return [\n            'pre.foo' => ['preFoo', 10],\n            'post.foo' => ['postFoo'],\n        ];\n    }\n}\n\nclass TestEventSubscriberWithMultipleListeners implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return ['pre.foo' => [\n            ['preFoo1'],\n            ['preFoo2', 10],\n        ]];\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/CustomEvent.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Fixtures;\n\nfinal class CustomEvent\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/DummyEvent.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Fixtures;\n\nfinal class DummyEvent\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/TaggedInvokableListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Fixtures;\n\nuse Symfony\\Component\\EventDispatcher\\Attribute\\AsEventListener;\n\n#[AsEventListener]\nfinal class TaggedInvokableListener\n{\n    public function __invoke(CustomEvent $event): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/TaggedMultiListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Fixtures;\n\nuse Symfony\\Component\\EventDispatcher\\Attribute\\AsEventListener;\n\n#[AsEventListener(event: CustomEvent::class, method: 'onCustomEvent')]\n#[AsEventListener(event: 'foo', priority: 42)]\n#[AsEventListener(event: 'bar', method: 'onBarEvent')]\nfinal class TaggedMultiListener\n{\n    public function onCustomEvent(CustomEvent $event): void\n    {\n    }\n\n    public function onFoo(): void\n    {\n    }\n\n    public function onBarEvent(): void\n    {\n    }\n\n    #[AsEventListener(event: 'baz')]\n    public function onBazEvent(): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/TaggedUnionTypeListener.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests\\Fixtures;\n\nuse Symfony\\Component\\EventDispatcher\\Attribute\\AsEventListener;\n\nfinal class TaggedUnionTypeListener\n{\n    #[AsEventListener]\n    public function onUnionEvent(CustomEvent|DummyEvent $event): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/GenericEventTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\EventDispatcher\\GenericEvent;\n\n/**\n * Test class for Event.\n */\nclass GenericEventTest extends TestCase\n{\n    private GenericEvent $event;\n    private \\stdClass $subject;\n\n    protected function setUp(): void\n    {\n        $this->subject = new \\stdClass();\n        $this->event = new GenericEvent($this->subject, ['name' => 'Event']);\n    }\n\n    public function testConstruct()\n    {\n        $this->assertEquals($this->event, new GenericEvent($this->subject, ['name' => 'Event']));\n    }\n\n    /**\n     * Tests Event->getArgs().\n     */\n    public function testGetArguments()\n    {\n        // test getting all\n        $this->assertSame(['name' => 'Event'], $this->event->getArguments());\n    }\n\n    public function testSetArguments()\n    {\n        $result = $this->event->setArguments(['foo' => 'bar']);\n        $this->assertSame(['foo' => 'bar'], $this->event->getArguments());\n        $this->assertSame($this->event, $result);\n    }\n\n    public function testSetArgument()\n    {\n        $result = $this->event->setArgument('foo2', 'bar2');\n        $this->assertSame(['name' => 'Event', 'foo2' => 'bar2'], $this->event->getArguments());\n        $this->assertEquals($this->event, $result);\n    }\n\n    public function testGetArgument()\n    {\n        // test getting key\n        $this->assertEquals('Event', $this->event->getArgument('name'));\n    }\n\n    public function testGetArgException()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->event->getArgument('nameNotExist');\n    }\n\n    public function testOffsetGet()\n    {\n        // test getting key\n        $this->assertEquals('Event', $this->event['name']);\n\n        // test getting invalid arg\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->assertFalse($this->event['nameNotExist']);\n    }\n\n    public function testOffsetSet()\n    {\n        $this->event['foo2'] = 'bar2';\n        $this->assertSame(['name' => 'Event', 'foo2' => 'bar2'], $this->event->getArguments());\n    }\n\n    public function testOffsetUnset()\n    {\n        unset($this->event['name']);\n        $this->assertSame([], $this->event->getArguments());\n    }\n\n    public function testOffsetIsset()\n    {\n        $this->assertArrayHasKey('name', $this->event);\n        $this->assertArrayNotHasKey('nameNotExist', $this->event);\n    }\n\n    public function testHasArgument()\n    {\n        $this->assertTrue($this->event->hasArgument('name'));\n        $this->assertFalse($this->event->hasArgument('nameNotExist'));\n    }\n\n    public function testGetSubject()\n    {\n        $this->assertSame($this->subject, $this->event->getSubject());\n    }\n\n    public function testHasIterator()\n    {\n        $data = [];\n        foreach ($this->event as $key => $value) {\n            $data[$key] = $value;\n        }\n        $this->assertEquals(['name' => 'Event'], $data);\n    }\n}\n"
  },
  {
    "path": "Tests/ImmutableEventDispatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\EventDispatcher\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcherInterface;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher;\nuse Symfony\\Contracts\\EventDispatcher\\Event;\n\n/**\n * @author Bernhard Schussek <bschussek@gmail.com>\n */\nclass ImmutableEventDispatcherTest extends TestCase\n{\n    public function testDispatchDelegates()\n    {\n        $innerDispatcher = $this->createMock(EventDispatcherInterface::class);\n        $dispatcher = new ImmutableEventDispatcher($innerDispatcher);\n\n        $event = new Event();\n        $resultEvent = new Event();\n\n        $innerDispatcher->expects($this->once())\n            ->method('dispatch')\n            ->with($event, 'event')\n            ->willReturn($resultEvent);\n\n        $this->assertSame($resultEvent, $dispatcher->dispatch($event, 'event'));\n    }\n\n    public function testGetListenersDelegates()\n    {\n        $innerDispatcher = $this->createMock(EventDispatcherInterface::class);\n        $dispatcher = new ImmutableEventDispatcher($innerDispatcher);\n\n        $innerDispatcher->expects($this->once())\n            ->method('getListeners')\n            ->with('event')\n            ->willReturn(['result']);\n\n        $this->assertSame(['result'], $dispatcher->getListeners('event'));\n    }\n\n    public function testHasListenersDelegates()\n    {\n        $innerDispatcher = $this->createMock(EventDispatcherInterface::class);\n        $dispatcher = new ImmutableEventDispatcher($innerDispatcher);\n\n        $innerDispatcher->expects($this->once())\n            ->method('hasListeners')\n            ->with('event')\n            ->willReturn(true);\n\n        $this->assertTrue($dispatcher->hasListeners('event'));\n    }\n\n    public function testAddListenerDisallowed()\n    {\n        $dispatcher = new ImmutableEventDispatcher(new EventDispatcher());\n\n        $this->expectException(\\BadMethodCallException::class);\n        $dispatcher->addListener('event', static fn () => 'foo');\n    }\n\n    public function testAddSubscriberDisallowed()\n    {\n        $dispatcher = new ImmutableEventDispatcher(new EventDispatcher());\n\n        $this->expectException(\\BadMethodCallException::class);\n        $subscriber = $this->createStub(EventSubscriberInterface::class);\n\n        $dispatcher->addSubscriber($subscriber);\n    }\n\n    public function testRemoveListenerDisallowed()\n    {\n        $dispatcher = new ImmutableEventDispatcher(new EventDispatcher());\n\n        $this->expectException(\\BadMethodCallException::class);\n        $dispatcher->removeListener('event', static fn () => 'foo');\n    }\n\n    public function testRemoveSubscriberDisallowed()\n    {\n        $dispatcher = new ImmutableEventDispatcher(new EventDispatcher());\n\n        $this->expectException(\\BadMethodCallException::class);\n        $subscriber = $this->createStub(EventSubscriberInterface::class);\n\n        $dispatcher->removeSubscriber($subscriber);\n    }\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"symfony/event-dispatcher\",\n    \"type\": \"library\",\n    \"description\": \"Provides tools that allow your application components to communicate with each other by dispatching events and listening to them\",\n    \"keywords\": [],\n    \"homepage\": \"https://symfony.com\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Symfony Community\",\n            \"homepage\": \"https://symfony.com/contributors\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=8.4\",\n        \"symfony/event-dispatcher-contracts\": \"^2.5|^3\"\n    },\n    \"require-dev\": {\n        \"psr/log\": \"^1|^2|^3\",\n        \"symfony/config\": \"^7.4|^8.0\",\n        \"symfony/dependency-injection\": \"^7.4|^8.0\",\n        \"symfony/error-handler\": \"^7.4|^8.0\",\n        \"symfony/expression-language\": \"^7.4|^8.0\",\n        \"symfony/framework-bundle\": \"^7.4|^8.0\",\n        \"symfony/http-foundation\": \"^7.4|^8.0\",\n        \"symfony/service-contracts\": \"^2.5|^3\",\n        \"symfony/stopwatch\": \"^7.4|^8.0\"\n    },\n    \"conflict\": {\n        \"symfony/security-http\": \"<7.4\",\n        \"symfony/service-contracts\": \"<2.5\"\n    },\n    \"provide\": {\n        \"psr/event-dispatcher-implementation\": \"1.0\",\n        \"symfony/event-dispatcher-implementation\": \"2.0|3.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Symfony\\\\Component\\\\EventDispatcher\\\\\": \"\" },\n        \"exclude-from-classmap\": [\n            \"/Tests/\"\n        ]\n    },\n    \"minimum-stability\": \"dev\"\n}\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"https://schema.phpunit.de/11.3/phpunit.xsd\"\n         backupGlobals=\"false\"\n         colors=\"true\"\n         bootstrap=\"vendor/autoload.php\"\n         failOnDeprecation=\"true\"\n         failOnRisky=\"true\"\n         failOnWarning=\"true\"\n>\n    <php>\n        <ini name=\"error_reporting\" value=\"-1\" />\n    </php>\n\n    <testsuites>\n        <testsuite name=\"Symfony EventDispatcher Component Test Suite\">\n            <directory>./Tests/</directory>\n        </testsuite>\n    </testsuites>\n\n    <source ignoreSuppressionOfDeprecations=\"true\">\n        <include>\n            <directory>./</directory>\n        </include>\n        <exclude>\n            <directory>./Resources</directory>\n            <directory>./Tests</directory>\n            <directory>./vendor</directory>\n        </exclude>\n    </source>\n\n    <extensions>\n        <bootstrap class=\"Symfony\\Bridge\\PhpUnit\\SymfonyExtension\" />\n    </extensions>\n</phpunit>\n"
  }
]