Repository: symfony/symfony
File: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php (PHP)

Code before:
            return [];
        }
    }

    /**
     * @return array<array{id: string, class: ?string, priority: int}>
     */
    protected function getDecorationStack(ContainerBuilder $container, string $id): array
    {
        $stack = [];

        while ($container->hasDefinition($id) || $container->hasAlias($id)) {
            // resolve Alias and continue
            if ($container->hasAlias($id)) {
                $id = (string) $container->getAlias($id);
                continue;
            }

            $definition = $container->getDefinition($id);
            $class = $definition->getClass();

            $priority = (int) (($definition->getDecoratedService() ?? [])[2] ?? 0);

            if (0 === $priority && $class) {
                try {
                    $attr = (new \ReflectionClass($class))->getAttributes(AsDecorator::class)[0] ?? null;
                    $priority = $attr?->newInstance()->priority ?? 0;
                } catch (\ReflectionException) {
                }
            }

            $stack[] = ['id' => $id, 'class' => $class, 'priority' => $priority];

            if (!$nextId = $definition->innerServiceId) {
                break;
            }

            $id = $nextId;
        }

        return $stack;
    }

    private function filterRoutesByHttpMethod(RouteCollection $routes, string $method): RouteCollection
    {
        if (!$method) {
            return $routes;
        }
        $filteredRoutes = clone $routes;

        foreach ($filteredRoutes as $routeName => $route) {

Review comment (suggestion):
I don't think that's the right implementation. Decorators can be defined not only using attributes. We should rely only on what definitions contain, tags instead of attributes when appropriate.


Code after:
        }
    }

    /**
     * @return array<array{id: string, class: ?string, priority: int}>
     */
    protected function getDecorationStack(ContainerBuilder $container, string $id): array
    {
        $stack = [];

        while ($container->hasDefinition($id) || $container->hasAlias($id)) {
            // resolve Alias and continue
            if ($container->hasAlias($id)) {
                $id = (string) $container->getAlias($id);
                continue;
            }

            $definition = $container->getDefinition($id);
            $class = $definition->getClass();
            $priority = $definition->decorationPriority ?? 0;

            $stack[] = ['id' => $id, 'class' => $class, 'priority' => $priority];

            if (!$nextId = $definition->innerServiceId) {
                break;
            }

            $id = $nextId;
        }

        return $stack;
    }

    private function filterRoutesByHttpMethod(RouteCollection $routes, string $method): RouteCollection
    {
        if (!$method) {
            return $routes;
        }
        $filteredRoutes = clone $routes;

        foreach ($filteredRoutes as $routeName => $route) {
            if ($route->getMethods() && !\in_array($method, $route->getMethods(), true)) {
                $filteredRoutes->remove($routeName);
            }
        }

        return $filteredRoutes;
    }
}